From fc65a6a99d9b9dc5a146b0e5d11dfa18c85eaa2e Mon Sep 17 00:00:00 2001 From: jjmr007 Date: Sat, 15 Apr 2023 22:21:49 -0400 Subject: [PATCH 1/2] completing artifacts from artifacts folder in deployments --- ...hers.populatableethersliquity.findhints.md | 22 + .../lib-ethers.populatableethersliquity.md | 1 + .../deployment/deployments/README.md | 12 + .../deployments/loadMainnetArtifacts.js | 75 + .../deployments/loadTestnetArtifacts.js | 95 + .../deployments/mainnetAddressListQA.json | 18 + .../rskSovrynMainnet/GeneralZero_Proxy.json | 109 + .../rskSovrynMainnet/activePool.json | 360 +++ .../rskSovrynMainnet/activePool_Proxy.json | 110 + .../rskSovrynMainnet/collSurplusPool.json | 276 +++ .../collSurplusPool_Proxy.json | 110 + .../rskSovrynMainnet/defaultPool.json | 306 +++ .../rskSovrynMainnet/defaultPool_Proxy.json | 110 + .../rskSovrynMainnet/feeDistributor.json | 358 +++ .../feeDistributor_Proxy.json | 110 + .../rskSovrynMainnet/hintHelpers.json | 406 ++++ .../rskSovrynMainnet/hintHelpers_Proxy.json | 110 + .../rskSovrynMainnet/multiTroveGetter.json | 157 ++ .../multiTroveGetter_Proxy.json | 110 + .../rskSovrynMainnet/priceFeed.json | 189 ++ .../rskSovrynMainnet/priceFeed_Proxy.json | 110 + .../rskSovrynMainnet/sortedTroves.json | 485 ++++ .../rskSovrynMainnet/sortedTroves_Proxy.json | 110 + .../rskSovrynTestnet/GeneralZero_Proxy.json | 109 + .../rskSovrynTestnet/LiquityBaseParams.json | 465 ++-- .../LiquityBaseParams_Proxy.json | 196 +- .../rskSovrynTestnet/activePool.json | 360 +++ .../rskSovrynTestnet/activePool_Proxy.json | 110 + .../rskSovrynTestnet/borrowerOperations.json | 1082 +++++++++ .../borrowerOperations_Proxy.json | 110 + .../rskSovrynTestnet/collSurplusPool.json | 276 +++ .../collSurplusPool_Proxy.json | 110 + .../rskSovrynTestnet/defaultPool.json | 306 +++ .../rskSovrynTestnet/defaultPool_Proxy.json | 110 + .../rskSovrynTestnet/feeDistributor.json | 358 +++ .../feeDistributor_Proxy.json | 110 + .../rskSovrynTestnet/hintHelpers.json | 406 ++++ .../rskSovrynTestnet/hintHelpers_Proxy.json | 110 + .../rskSovrynTestnet/multiTroveGetter.json | 157 ++ .../multiTroveGetter_Proxy.json | 110 + .../rskSovrynTestnet/sortedTroves.json | 485 ++++ .../rskSovrynTestnet/sortedTroves_Proxy.json | 110 + .../rskSovrynTestnet/stabilityPool.json | 1347 +++++++++++ .../rskSovrynTestnet/stabilityPool_Proxy.json | 110 + .../rskSovrynTestnet/troveManager.json | 1991 +++++++++++++++++ .../rskSovrynTestnet/troveManager_Proxy.json | 110 + .../rskSovrynTestnet/zusdToken.json | 619 +++++ .../rskSovrynTestnet/zusdToken_Proxy.json | 110 + .../deployments/testnetAddressListQA.json | 16 + packages/contracts/hardhat.config.ts | 16 +- packages/lib-ethers/etc/lib-ethers.api.md | 2 + 51 files changed, 12812 insertions(+), 338 deletions(-) create mode 100644 docs/sdk/lib-ethers.populatableethersliquity.findhints.md create mode 100644 packages/contracts/deployment/deployments/README.md create mode 100644 packages/contracts/deployment/deployments/loadMainnetArtifacts.js create mode 100644 packages/contracts/deployment/deployments/loadTestnetArtifacts.js create mode 100644 packages/contracts/deployment/deployments/mainnetAddressListQA.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/GeneralZero_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/activePool.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/activePool_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/collSurplusPool.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/collSurplusPool_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/defaultPool.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/defaultPool_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/feeDistributor.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/feeDistributor_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/hintHelpers.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/hintHelpers_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/multiTroveGetter.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/multiTroveGetter_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/priceFeed.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/priceFeed_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/sortedTroves.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/sortedTroves_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/GeneralZero_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/activePool.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/activePool_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/borrowerOperations.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/borrowerOperations_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/collSurplusPool.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/collSurplusPool_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/defaultPool.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/defaultPool_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/feeDistributor.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/feeDistributor_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/hintHelpers.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/hintHelpers_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/multiTroveGetter.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/multiTroveGetter_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/sortedTroves.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/sortedTroves_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/stabilityPool.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/stabilityPool_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/troveManager.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/troveManager_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/zusdToken.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/zusdToken_Proxy.json create mode 100644 packages/contracts/deployment/deployments/testnetAddressListQA.json diff --git a/docs/sdk/lib-ethers.populatableethersliquity.findhints.md b/docs/sdk/lib-ethers.populatableethersliquity.findhints.md new file mode 100644 index 00000000..a8e37545 --- /dev/null +++ b/docs/sdk/lib-ethers.populatableethersliquity.findhints.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [@sovryn-zero/lib-ethers](./lib-ethers.md) > [PopulatableEthersLiquity](./lib-ethers.populatableethersliquity.md) > [findHints](./lib-ethers.populatableethersliquity.findhints.md) + +## PopulatableEthersLiquity.findHints() method + +Signature: + +```typescript +findHints(trove: Trove): Promise<[string, string]>; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| trove | [Trove](./lib-base.trove.md) | | + +Returns: + +Promise<\[string, string\]> + diff --git a/docs/sdk/lib-ethers.populatableethersliquity.md b/docs/sdk/lib-ethers.populatableethersliquity.md index 4dcbe227..69f5a81d 100644 --- a/docs/sdk/lib-ethers.populatableethersliquity.md +++ b/docs/sdk/lib-ethers.populatableethersliquity.md @@ -31,6 +31,7 @@ export declare class PopulatableEthersLiquity implements PopulatableLiquity>; // (undocumented) + findHints(trove: Trove): Promise<[string, string]>; + // (undocumented) liquidate(address: string | string[], overrides?: EthersTransactionOverrides): Promise>; // (undocumented) liquidateUpTo(maximumNumberOfTrovesToLiquidate: number, overrides?: EthersTransactionOverrides): Promise>; From 30fbb1dd3c3bfb4dd9dce906bb1fa46583930199 Mon Sep 17 00:00:00 2001 From: jjmr007 Date: Fri, 28 Apr 2023 00:03:21 -0400 Subject: [PATCH 2/2] SOV-2101:Adding Artifacts for new Comm Issuance Storage --- .../deployment/deployments/README.md | 10 +- .../deployments/loadMainnetArtifacts.js | 62 +- .../deployments/loadTestnetArtifacts.js | 125 +++- .../{activePool.json => ActivePool.json} | 4 +- .../rskSovrynMainnet/ActivePool_Proxy.json | 110 ++++ .../CollSurplusPool.json} | 4 +- .../CollSurplusPool_Proxy.json | 110 ++++ .../rskSovrynMainnet/CommunityIssuance.json | 311 +++++++++ .../CommunityIssuance_Proxy.json | 110 ++++ .../{defaultPool.json => DefaultPool.json} | 4 +- .../rskSovrynMainnet/DefaultPool_Proxy.json | 110 ++++ .../FeeDistributor.json} | 4 +- .../FeeDistributor_Proxy.json | 110 ++++ .../HintHelpers.json} | 4 +- .../rskSovrynMainnet/HintHelpers_Proxy.json | 110 ++++ .../MultiTroveGetter.json} | 4 +- .../MultiTroveGetter_Proxy.json | 110 ++++ .../{priceFeed.json => PriceFeed.json} | 4 +- .../rskSovrynMainnet/PriceFeed_Proxy.json | 110 ++++ .../{sortedTroves.json => SortedTroves.json} | 4 +- .../rskSovrynMainnet/SortedTroves_Proxy.json | 110 ++++ .../rskSovrynMainnet/activePool_Proxy.json | 110 ---- .../collSurplusPool_Proxy.json | 110 ---- .../rskSovrynMainnet/defaultPool_Proxy.json | 110 ---- .../feeDistributor_Proxy.json | 110 ---- .../rskSovrynMainnet/hintHelpers_Proxy.json | 110 ---- .../multiTroveGetter_Proxy.json | 110 ---- .../rskSovrynMainnet/priceFeed_Proxy.json | 110 ---- .../rskSovrynMainnet/sortedTroves_Proxy.json | 110 ---- .../{activePool.json => ActivePool.json} | 4 +- .../rskSovrynTestnet/ActivePool_Proxy.json | 110 ++++ ...perations.json => BorrowerOperations.json} | 0 ...oxy.json => BorrowerOperations_Proxy.json} | 2 +- .../CollSurplusPool.json} | 4 +- .../CollSurplusPool_Proxy.json | 110 ++++ .../rskSovrynTestnet/CommunityIssuance.json | 415 ++++++++++++ .../CommunityIssuance_Implementation.json | 598 ++++++++++++++++++ .../CommunityIssuance_Proxy.json | 191 ++++++ .../{defaultPool.json => DefaultPool.json} | 4 +- .../rskSovrynTestnet/DefaultPool_Proxy.json | 110 ++++ .../FeeDistributor.json} | 4 +- .../FeeDistributor_Proxy.json | 110 ++++ .../HintHelpers.json} | 4 +- .../rskSovrynTestnet/HintHelpers_Proxy.json | 110 ++++ .../rskSovrynTestnet/LiquityBaseParams.json | 465 +++++++------- .../LiquityBaseParams_Proxy.json | 196 +++--- .../MultiTroveGetter.json} | 4 +- .../MultiTroveGetter_Proxy.json | 110 ++++ .../{sortedTroves.json => SortedTroves.json} | 4 +- .../rskSovrynTestnet/SortedTroves_Proxy.json | 110 ++++ ...{stabilityPool.json => StabilityPool.json} | 0 ...ol_Proxy.json => StabilityPool_Proxy.json} | 2 +- .../{troveManager.json => TroveManager.json} | 0 ...ger_Proxy.json => TroveManager_Proxy.json} | 2 +- .../{zusdToken.json => ZUSDToken.json} | 0 ...dToken_Proxy.json => ZUSDToken_Proxy.json} | 2 +- .../rskSovrynTestnet/activePool_Proxy.json | 110 ---- .../collSurplusPool_Proxy.json | 110 ---- .../rskSovrynTestnet/defaultPool_Proxy.json | 110 ---- .../feeDistributor_Proxy.json | 110 ---- .../rskSovrynTestnet/hintHelpers_Proxy.json | 110 ---- .../multiTroveGetter_Proxy.json | 110 ---- .../663a65e7f929c4555a67124fb1575a7f.json | 376 +++++++++++ .../754dff2eec82e13c98a907fdc90582aa.json | 376 +++++++++++ .../a74723cb677f46af6277664d6e1e3f48.json | 376 +++++++++++ .../be36e640ecbdc455165550d36df9feff.json | 376 +++++++++++ .../rskSovrynTestnet/sortedTroves_Proxy.json | 110 ---- .../deployments/testnetAddressListQA.json | 28 +- 68 files changed, 5291 insertions(+), 2092 deletions(-) rename packages/contracts/deployment/deployments/rskSovrynMainnet/{activePool.json => ActivePool.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/ActivePool_Proxy.json rename packages/contracts/deployment/deployments/{rskSovrynTestnet/collSurplusPool.json => rskSovrynMainnet/CollSurplusPool.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/CollSurplusPool_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/CommunityIssuance.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/CommunityIssuance_Proxy.json rename packages/contracts/deployment/deployments/rskSovrynMainnet/{defaultPool.json => DefaultPool.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/DefaultPool_Proxy.json rename packages/contracts/deployment/deployments/{rskSovrynTestnet/feeDistributor.json => rskSovrynMainnet/FeeDistributor.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/FeeDistributor_Proxy.json rename packages/contracts/deployment/deployments/{rskSovrynTestnet/hintHelpers.json => rskSovrynMainnet/HintHelpers.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/HintHelpers_Proxy.json rename packages/contracts/deployment/deployments/{rskSovrynTestnet/multiTroveGetter.json => rskSovrynMainnet/MultiTroveGetter.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/MultiTroveGetter_Proxy.json rename packages/contracts/deployment/deployments/rskSovrynMainnet/{priceFeed.json => PriceFeed.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/PriceFeed_Proxy.json rename packages/contracts/deployment/deployments/rskSovrynMainnet/{sortedTroves.json => SortedTroves.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/SortedTroves_Proxy.json delete mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/activePool_Proxy.json delete mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/collSurplusPool_Proxy.json delete mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/defaultPool_Proxy.json delete mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/feeDistributor_Proxy.json delete mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/hintHelpers_Proxy.json delete mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/multiTroveGetter_Proxy.json delete mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/priceFeed_Proxy.json delete mode 100644 packages/contracts/deployment/deployments/rskSovrynMainnet/sortedTroves_Proxy.json rename packages/contracts/deployment/deployments/rskSovrynTestnet/{activePool.json => ActivePool.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/ActivePool_Proxy.json rename packages/contracts/deployment/deployments/rskSovrynTestnet/{borrowerOperations.json => BorrowerOperations.json} (100%) rename packages/contracts/deployment/deployments/rskSovrynTestnet/{borrowerOperations_Proxy.json => BorrowerOperations_Proxy.json} (100%) rename packages/contracts/deployment/deployments/{rskSovrynMainnet/collSurplusPool.json => rskSovrynTestnet/CollSurplusPool.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/CollSurplusPool_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/CommunityIssuance.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/CommunityIssuance_Implementation.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/CommunityIssuance_Proxy.json rename packages/contracts/deployment/deployments/rskSovrynTestnet/{defaultPool.json => DefaultPool.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/DefaultPool_Proxy.json rename packages/contracts/deployment/deployments/{rskSovrynMainnet/feeDistributor.json => rskSovrynTestnet/FeeDistributor.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/FeeDistributor_Proxy.json rename packages/contracts/deployment/deployments/{rskSovrynMainnet/hintHelpers.json => rskSovrynTestnet/HintHelpers.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/HintHelpers_Proxy.json rename packages/contracts/deployment/deployments/{rskSovrynMainnet/multiTroveGetter.json => rskSovrynTestnet/MultiTroveGetter.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/MultiTroveGetter_Proxy.json rename packages/contracts/deployment/deployments/rskSovrynTestnet/{sortedTroves.json => SortedTroves.json} (99%) create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/SortedTroves_Proxy.json rename packages/contracts/deployment/deployments/rskSovrynTestnet/{stabilityPool.json => StabilityPool.json} (100%) rename packages/contracts/deployment/deployments/rskSovrynTestnet/{stabilityPool_Proxy.json => StabilityPool_Proxy.json} (100%) rename packages/contracts/deployment/deployments/rskSovrynTestnet/{troveManager.json => TroveManager.json} (100%) rename packages/contracts/deployment/deployments/rskSovrynTestnet/{troveManager_Proxy.json => TroveManager_Proxy.json} (100%) rename packages/contracts/deployment/deployments/rskSovrynTestnet/{zusdToken.json => ZUSDToken.json} (100%) rename packages/contracts/deployment/deployments/rskSovrynTestnet/{zusdToken_Proxy.json => ZUSDToken_Proxy.json} (100%) delete mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/activePool_Proxy.json delete mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/collSurplusPool_Proxy.json delete mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/defaultPool_Proxy.json delete mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/feeDistributor_Proxy.json delete mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/hintHelpers_Proxy.json delete mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/multiTroveGetter_Proxy.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/663a65e7f929c4555a67124fb1575a7f.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/754dff2eec82e13c98a907fdc90582aa.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/a74723cb677f46af6277664d6e1e3f48.json create mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/be36e640ecbdc455165550d36df9feff.json delete mode 100644 packages/contracts/deployment/deployments/rskSovrynTestnet/sortedTroves_Proxy.json diff --git a/packages/contracts/deployment/deployments/README.md b/packages/contracts/deployment/deployments/README.md index ba3a0b35..51806474 100644 --- a/packages/contracts/deployment/deployments/README.md +++ b/packages/contracts/deployment/deployments/README.md @@ -2,11 +2,11 @@ Scripts that helps to load callable contract objects: -#### loadTestnetArtifacts +### FIRST: Execute loadMainnetArtifacts -It takes from `artifacts` folder or from `rskSovrynMainnet` folder the abis of contracts and from `testnetAddressListQA.json`, the addresses. -To execute the loading after any fresh upgrade: `$ node loadTestnetArtifacts` +It keeps pre-existent artifacts in the `rskSovrynMainnet` folder. If there is any upgrade, the artifacts can be erased, then execute: `$ node loadMainnetArtifacts` -### loadMainnetArtifacts +#### THEN: Execute loadTestnetArtifacts -It keeps pre-existent artifacts in the `rskSovrynMainnet` folder. If there is any upgrade, the artifacts can be erased, then execute: `$ node loadMainnetArtifacts` \ No newline at end of file +It takes from `artifacts` folder or from `rskSovrynMainnet` folder the abis of contracts and from `testnetAddressListQA.json`, the addresses. +To execute the loading after any fresh upgrade: `$ node loadTestnetArtifacts` \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/loadMainnetArtifacts.js b/packages/contracts/deployment/deployments/loadMainnetArtifacts.js index 39e8604a..eb5dd618 100644 --- a/packages/contracts/deployment/deployments/loadMainnetArtifacts.js +++ b/packages/contracts/deployment/deployments/loadMainnetArtifacts.js @@ -12,40 +12,40 @@ for(let i = 0; i < Object.keys(alphas).length; i++){ for(let j = 0; j < files.length; j++){ - let file = files[j]; - let fileExt = path.extname(file); - if (fileExt == '.json') { + let file = files[j]; + let fileExt = path.extname(file); + if (fileExt == '.json') { - let fileName = path.basename(file, '.json'); - if(fileName.includes(alpha)){ + let fileName = path.basename(file, '.json'); + if(fileName.includes(alpha)){ - let subStrProxy = 'Proxy'; - if(fileName.includes(subStrProxy)){ + let subStrProxy = 'Proxy'; + let subStrImpl = 'Impl'; + let subStrSpecial = 'RedeemOps'; + if(fileName.includes(subStrProxy) || + (!fileName.includes(subStrImpl) && !fileName.includes(subStrSpecial))){ - found = true; - console.log(fileName); + found = true; + console.log(fileName); - } else { + } else { - let subStrImpl = 'Impl'; - if(!fileName.includes(subStrImpl)){ + console.log(' untouched ' + fileName); - found = true; - console.log(fileName); - - } - - } - console.log(fileName); - } + } } + } + } if(!found){ - let artifactPath = path.join('../../artifacts/contracts/', alpha + '.sol/', alpha + '.json'); + let artifactPath = + alpha == "CommunityIssuance" ? + path.join('../../artifacts/contracts/ZERO/', alpha + '.sol/', alpha + '.json') : + path.join('../../artifacts/contracts/', alpha + '.sol/', alpha + '.json'); if (fs.existsSync(artifactPath)) { @@ -56,9 +56,25 @@ for(let i = 0; i < Object.keys(alphas).length; i++){ let artifactLogicProxyPath = path.join('./rskSovrynMainnet/', alpha + '.json'); artifactProxy.address = artifactLogicProxy.address = Object.values(alphas)[i]; + + let entriesArtifactProxy = Object.entries(artifactProxy); + let entriesArtifactLogicProxy = Object.entries(artifactLogicProxy); + + entriesArtifactProxy.unshift( + entriesArtifactProxy.splice( + entriesArtifactProxy.findIndex( + ([key, value]) => key === 'address'), 1)[0]); + + entriesArtifactLogicProxy.unshift( + entriesArtifactLogicProxy.splice( + entriesArtifactLogicProxy.findIndex( + ([key, value]) => key === 'address'), 1)[0]); + + let reorderedArtifactProxy = Object.fromEntries(entriesArtifactProxy); + let reorderedArtifactLogicProxy = Object.fromEntries(entriesArtifactLogicProxy); - fs.writeFileSync(artifactLogicProxyPath, JSON.stringify(artifactLogicProxy, null, 2), {flag: 'w+'}); - fs.writeFileSync(artifactProxyPath, JSON.stringify(artifactProxy, null, 2), {flag: 'w+'}); + fs.writeFileSync(artifactProxyPath, JSON.stringify(reorderedArtifactProxy, null, 2), {flag: 'w+'}); + fs.writeFileSync(artifactLogicProxyPath, JSON.stringify(reorderedArtifactLogicProxy, null, 2), {flag: 'w+'}); console.log(alpha); console.log(alpha + '_Proxy.json'); diff --git a/packages/contracts/deployment/deployments/loadTestnetArtifacts.js b/packages/contracts/deployment/deployments/loadTestnetArtifacts.js index e4ef18d4..29d9fa78 100644 --- a/packages/contracts/deployment/deployments/loadTestnetArtifacts.js +++ b/packages/contracts/deployment/deployments/loadTestnetArtifacts.js @@ -1,40 +1,34 @@ const fs = require('fs'); const path = require('path'); -const files = fs.readdirSync('./rskSovrynMainnet'); +const filesInMainnet = fs.readdirSync('./rskSovrynMainnet'); +const filesInTestnet = fs.readdirSync('./rskSovrynTestnet'); const alphas = require('./testnetAddressListQA.json'); const proxy = require('./rskSovrynTestnet/GeneralZero_Proxy.json') for(let i = 0; i < Object.keys(alphas).length; i++){ let alpha = Object.keys(alphas)[i]; - let found = false; + var foundInMainnet = false; + let foundInTestnet = false; - for(let j = 0; j < files.length; j++){ + for(let j = 0; j < filesInTestnet.length; j++){ - let file = files[j]; - let fileExt = path.extname(file); + let testnetFile = filesInTestnet[j]; + let fileExt = path.extname(testnetFile); if (fileExt == '.json') { - let fileName = path.basename(file, '.json'); + let fileName = path.basename(testnetFile, '.json'); if(fileName.includes(alpha)){ let subStrProxy = 'Proxy'; if(fileName.includes(subStrProxy)){ - found = true; + foundInTestnet = true; console.log(fileName); - let artifactProxy = require( - ('./rskSovrynMainnet/' + fileName + '.json')); - artifactProxy.address = alphas[alpha]; - - fs.writeFileSync( - ('./rskSovrynTestnet/' + fileName + '.json'), - JSON.stringify(artifactProxy,null,2),{flag: 'w+'}); - } else { let subStrImpl = 'Impl'; @@ -42,21 +36,14 @@ for(let i = 0; i < Object.keys(alphas).length; i++){ if(!fileName.includes(subStrImpl)&& !fileName.includes(subStrRedeemOps)){ - found = true; + foundInTestnet = true; console.log(fileName); - - let artifactLogicProxy = require( - ('./rskSovrynMainnet/' + fileName + '.json')); - artifactLogicProxy.address = alphas[alpha]; - - fs.writeFileSync( - path.join('./rskSovrynTestnet/', fileName + '.json'), - JSON.stringify(artifactLogicProxy,null,2),{flag: 'w+'}); - } + } else { + console.log(' untouched ' + fileName); + } } - console.log(fileName); } @@ -64,32 +51,100 @@ for(let i = 0; i < Object.keys(alphas).length; i++){ } - if(!found){ + if(!foundInTestnet) { + + var artifactPath; + + for(let k = 0; k < filesInMainnet.length; k++){ + + let mainnetFile = filesInMainnet[k]; + let fileExt = path.extname(mainnetFile); + + if (fileExt == '.json') { + + let fileName = path.basename(mainnetFile, '.json'); + + if(fileName.includes(alpha)){ + + let subStrProxy = 'Proxy'; + let subStrImpl = 'Impl'; + let subStrRedeemOps = 'RedeemOps'; + if(fileName.includes(subStrProxy)|| + (!fileName.includes(subStrImpl)&& + !fileName.includes(subStrRedeemOps)) + ){ + + foundInMainnet = true; + artifactPath = './rskSovrynMainnet/' + fileName + '.json'; + let artifact = require(artifactPath); + let artifactTestnetPath = './rskSovrynTestnet/' + artifactPath.slice(19); + artifact.address = Object.values(alphas)[i]; + let entriesArtifact = Object.entries(artifact); + entriesArtifact.unshift( + entriesArtifact.splice( + entriesArtifact.findIndex( + ([key, value]) => key === 'address'), 1)[0]); + let reorderedArtifact = Object.fromEntries(entriesArtifact); + fs.writeFileSync(artifactTestnetPath, JSON.stringify(reorderedArtifact, null, 2), {flag: 'w+'}); + console.log(fileName); + + } else { + console.log(' untouched ' + fileName); + } + + } + + } + + } - let artifactPath = path.join('../../artifacts/contracts/', alpha + '.sol/', alpha + '.json'); + } + + if(!foundInMainnet && !foundInTestnet) { + + let artifactPath = alpha == "CommunityIssuance" ? + path.join('../../artifacts/contracts/ZERO/', alpha + '.sol/', alpha + '.json') : + path.join('../../artifacts/contracts/', alpha + '.sol/', alpha + '.json'); + if (fs.existsSync(artifactPath)) { let artifactProxy = proxy; let artifactLogicProxy = require(artifactPath); - + let artifactProxyPath = path.join('./rskSovrynTestnet/', alpha + '_Proxy.json'); let artifactLogicProxyPath = path.join('./rskSovrynTestnet/', alpha + '.json'); - + artifactProxy.address = artifactLogicProxy.address = Object.values(alphas)[i]; - - fs.writeFileSync(artifactLogicProxyPath, JSON.stringify(artifactLogicProxy, null, 2), {flag: 'w+'}); - fs.writeFileSync(artifactProxyPath, JSON.stringify(artifactProxy, null, 2), {flag: 'w+'}); + + let entriesArtifactProxy = Object.entries(artifactProxy); + let entriesArtifactLogicProxy = Object.entries(artifactLogicProxy); + + entriesArtifactProxy.unshift( + entriesArtifactProxy.splice( + entriesArtifactProxy.findIndex( + ([key, value]) => key === 'address'), 1)[0]); + + entriesArtifactLogicProxy.unshift( + entriesArtifactLogicProxy.splice( + entriesArtifactLogicProxy.findIndex( + ([key, value]) => key === 'address'), 1)[0]); + + let reorderedArtifactProxy = Object.fromEntries(entriesArtifactProxy); + let reorderedArtifactLogicProxy = Object.fromEntries(entriesArtifactLogicProxy); + + fs.writeFileSync(artifactProxyPath, JSON.stringify(reorderedArtifactProxy, null, 2), {flag: 'w+'}); + fs.writeFileSync(artifactLogicProxyPath, JSON.stringify(reorderedArtifactLogicProxy, null, 2), {flag: 'w+'}); console.log(alpha); console.log(alpha + '_Proxy.json'); - + } else { console.log(alpha + ' not available'); console.log(alpha + '_Proxy.json not available'); } - + } } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/activePool.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/ActivePool.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynMainnet/activePool.json rename to packages/contracts/deployment/deployments/rskSovrynMainnet/ActivePool.json index 12f55943..85558b06 100644 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/activePool.json +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/ActivePool.json @@ -1,4 +1,5 @@ { + "address": "0xf294ea272d6f8FedC08aCf8E93ff50fe99E1f7E8", "_format": "hh-sol-artifact-1", "contractName": "ActivePool", "sourceName": "contracts/ActivePool.sol", @@ -355,6 +356,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b8152600401808060200182810382526022815260200180610df66022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b610cd78061011f6000396000f3fe6080604052600436106100b65760003560e01c80635a4d28bb1161006f5780635a4d28bb1461022b57806364a197f314610240578063893d20e814610279578063a3f4df7e1461028e578063aac1846f14610318578063b7f8cf9b1461032d578063f2e91d71146103425761010f565b80630b622ab21461011457806313af40351461014557806314f6c3be1461017a5780632439789a146101a15780633963e980146101cb5780634a945f8d146101e05761010f565b3661010f576100c361036c565b6004546100d6903463ffffffff6103cc16565b600481905560408051918252517fca232b5abb988c540b959ff6c3bfae3e97fff964fd098c508f9613c0a6bf1a809181900360200190a1005b600080fd5b34801561012057600080fd5b5061012961042d565b604080516001600160a01b039092168252519081900360200190f35b34801561015157600080fd5b506101786004803603602081101561016857600080fd5b50356001600160a01b031661043c565b005b34801561018657600080fd5b5061018f6104af565b60408051918252519081900360200190f35b3480156101ad57600080fd5b50610178600480360360208110156101c457600080fd5b50356104b5565b3480156101d757600080fd5b5061018f61050a565b3480156101ec57600080fd5b506101786004803603608081101561020357600080fd5b506001600160a01b038135811691602081013582169160408201358116916060013516610510565b34801561023757600080fd5b506101296106cf565b34801561024c57600080fd5b506101786004803603604081101561026357600080fd5b506001600160a01b0381351690602001356106de565b34801561028557600080fd5b5061012961081f565b34801561029a57600080fd5b506102a3610849565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102dd5781810151838201526020016102c5565b50505050905090810190601f16801561030a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561032457600080fd5b5061012961086f565b34801561033957600080fd5b5061012961087e565b34801561034e57600080fd5b506101786004803603602081101561036557600080fd5b503561088d565b6000546001600160a01b031633148061038f57506003546001600160a01b031633145b6103ca5760405162461bcd60e51b8152600401808060200182810382526031815260200180610c716031913960400191505060405180910390fd5b565b600082820183811015610426576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6002546001600160a01b031681565b61044461081f565b6001600160a01b0316336001600160a01b0316146104a3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6104ac816108a8565b50565b60045490565b6104bd61095d565b6005546104d0908263ffffffff6109d016565b600581905560408051918252517fc179e77847def189a2838a920a4d2d78f966467c47494a7fb5fbd1477a2cf4f59181900360200190a150565b60055490565b61051861081f565b6001600160a01b0316336001600160a01b031614610577576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61058084610a12565b61058983610a12565b61059282610a12565b61059b81610a12565b600080546001600160a01b038087166001600160a01b031992831681179093556001805487831690841617905560028054868316908416179055600380549185169190921617905560408051918252517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1604080516001600160a01b038516815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038416815290517f82966d27eea39b038ee0fa30cd16532bb24f6e65d31cb58fb227aa5766cdcc7f9181900360200190a1604080516001600160a01b038316815290517f5ee0cae2f063ed938bb55046f6a932fb6ae792bf43624806bb90abe68a50be9b9181900360200190a150505050565b6001546001600160a01b031681565b6106e661095d565b6004546106f9908263ffffffff6109d016565b600481905560408051918252517fca232b5abb988c540b959ff6c3bfae3e97fff964fd098c508f9613c0a6bf1a809181900360200190a1604080516001600160a01b03841681526020810183905281517f6109e2559dfa766aaec7118351d48a523f0a4157f49c8d68749c8ac41318ad12929181900390910190a16040516000906001600160a01b0384169083908381818185875af1925050503d80600081146107bf576040519150601f19603f3d011682016040523d82523d6000602084013e6107c4565b606091505b505090508061081a576040805162461bcd60e51b815260206004820152601e60248201527f416374697665506f6f6c3a2073656e64696e6720455448206661696c65640000604482015290519081900360640190fd5b505050565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6040518060400160405280600a8152602001691058dd1a5d99541bdbdb60b21b81525081565b6003546001600160a01b031681565b6000546001600160a01b031681565b610895610ac5565b6005546104d0908263ffffffff6103cc16565b6001600160a01b0381166108ed5760405162461bcd60e51b8152600401808060200182810382526022815260200180610bfc6022913960400191505060405180910390fd5b806001600160a01b03166108ff61081f565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6000546001600160a01b031633148061098057506001546001600160a01b031633145b8061099557506002546001600160a01b031633145b6103ca5760405162461bcd60e51b8152600401808060200182810382526053815260200180610c1e6053913960600191505060405180910390fd5b600061042683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610b23565b6001600160a01b038116610a6d576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b80610ac1576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b6000546001600160a01b0316331480610ae857506001546001600160a01b031633145b6103ca5760405162461bcd60e51b8152600401808060200182810382526041815260200180610bbb6041913960600191505060405180910390fd5b60008184841115610bb25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b77578181015183820152602001610b5f565b50505050905090810190601f168015610ba45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe416374697665506f6f6c3a2043616c6c6572206973206e65697468657220426f72726f7765724f7065726174696f6e73206e6f722054726f76654d616e616765724f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373416374697665506f6f6c3a2043616c6c6572206973206e65697468657220426f72726f7765724f7065726174696f6e73206e6f722054726f76654d616e61676572206e6f722053746162696c697479506f6f6c416374697665506f6f6c3a2043616c6c6572206973206e65697468657220424f206e6f722044656661756c7420506f6f6ca26469706673582212209b05c372200c8127ca513fb34ec2474a15cb2a4151e9268b0749f3eb662cb88b64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", "deployedBytecode": "0x6080604052600436106100b65760003560e01c80635a4d28bb1161006f5780635a4d28bb1461022b57806364a197f314610240578063893d20e814610279578063a3f4df7e1461028e578063aac1846f14610318578063b7f8cf9b1461032d578063f2e91d71146103425761010f565b80630b622ab21461011457806313af40351461014557806314f6c3be1461017a5780632439789a146101a15780633963e980146101cb5780634a945f8d146101e05761010f565b3661010f576100c361036c565b6004546100d6903463ffffffff6103cc16565b600481905560408051918252517fca232b5abb988c540b959ff6c3bfae3e97fff964fd098c508f9613c0a6bf1a809181900360200190a1005b600080fd5b34801561012057600080fd5b5061012961042d565b604080516001600160a01b039092168252519081900360200190f35b34801561015157600080fd5b506101786004803603602081101561016857600080fd5b50356001600160a01b031661043c565b005b34801561018657600080fd5b5061018f6104af565b60408051918252519081900360200190f35b3480156101ad57600080fd5b50610178600480360360208110156101c457600080fd5b50356104b5565b3480156101d757600080fd5b5061018f61050a565b3480156101ec57600080fd5b506101786004803603608081101561020357600080fd5b506001600160a01b038135811691602081013582169160408201358116916060013516610510565b34801561023757600080fd5b506101296106cf565b34801561024c57600080fd5b506101786004803603604081101561026357600080fd5b506001600160a01b0381351690602001356106de565b34801561028557600080fd5b5061012961081f565b34801561029a57600080fd5b506102a3610849565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102dd5781810151838201526020016102c5565b50505050905090810190601f16801561030a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561032457600080fd5b5061012961086f565b34801561033957600080fd5b5061012961087e565b34801561034e57600080fd5b506101786004803603602081101561036557600080fd5b503561088d565b6000546001600160a01b031633148061038f57506003546001600160a01b031633145b6103ca5760405162461bcd60e51b8152600401808060200182810382526031815260200180610c716031913960400191505060405180910390fd5b565b600082820183811015610426576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6002546001600160a01b031681565b61044461081f565b6001600160a01b0316336001600160a01b0316146104a3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6104ac816108a8565b50565b60045490565b6104bd61095d565b6005546104d0908263ffffffff6109d016565b600581905560408051918252517fc179e77847def189a2838a920a4d2d78f966467c47494a7fb5fbd1477a2cf4f59181900360200190a150565b60055490565b61051861081f565b6001600160a01b0316336001600160a01b031614610577576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61058084610a12565b61058983610a12565b61059282610a12565b61059b81610a12565b600080546001600160a01b038087166001600160a01b031992831681179093556001805487831690841617905560028054868316908416179055600380549185169190921617905560408051918252517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1604080516001600160a01b038516815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038416815290517f82966d27eea39b038ee0fa30cd16532bb24f6e65d31cb58fb227aa5766cdcc7f9181900360200190a1604080516001600160a01b038316815290517f5ee0cae2f063ed938bb55046f6a932fb6ae792bf43624806bb90abe68a50be9b9181900360200190a150505050565b6001546001600160a01b031681565b6106e661095d565b6004546106f9908263ffffffff6109d016565b600481905560408051918252517fca232b5abb988c540b959ff6c3bfae3e97fff964fd098c508f9613c0a6bf1a809181900360200190a1604080516001600160a01b03841681526020810183905281517f6109e2559dfa766aaec7118351d48a523f0a4157f49c8d68749c8ac41318ad12929181900390910190a16040516000906001600160a01b0384169083908381818185875af1925050503d80600081146107bf576040519150601f19603f3d011682016040523d82523d6000602084013e6107c4565b606091505b505090508061081a576040805162461bcd60e51b815260206004820152601e60248201527f416374697665506f6f6c3a2073656e64696e6720455448206661696c65640000604482015290519081900360640190fd5b505050565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6040518060400160405280600a8152602001691058dd1a5d99541bdbdb60b21b81525081565b6003546001600160a01b031681565b6000546001600160a01b031681565b610895610ac5565b6005546104d0908263ffffffff6103cc16565b6001600160a01b0381166108ed5760405162461bcd60e51b8152600401808060200182810382526022815260200180610bfc6022913960400191505060405180910390fd5b806001600160a01b03166108ff61081f565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6000546001600160a01b031633148061098057506001546001600160a01b031633145b8061099557506002546001600160a01b031633145b6103ca5760405162461bcd60e51b8152600401808060200182810382526053815260200180610c1e6053913960600191505060405180910390fd5b600061042683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610b23565b6001600160a01b038116610a6d576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b80610ac1576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b6000546001600160a01b0316331480610ae857506001546001600160a01b031633145b6103ca5760405162461bcd60e51b8152600401808060200182810382526041815260200180610bbb6041913960600191505060405180910390fd5b60008184841115610bb25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b77578181015183820152602001610b5f565b50505050905090810190601f168015610ba45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe416374697665506f6f6c3a2043616c6c6572206973206e65697468657220426f72726f7765724f7065726174696f6e73206e6f722054726f76654d616e616765724f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373416374697665506f6f6c3a2043616c6c6572206973206e65697468657220426f72726f7765724f7065726174696f6e73206e6f722054726f76654d616e61676572206e6f722053746162696c697479506f6f6c416374697665506f6f6c3a2043616c6c6572206973206e65697468657220424f206e6f722044656661756c7420506f6f6ca26469706673582212209b05c372200c8127ca513fb34ec2474a15cb2a4151e9268b0749f3eb662cb88b64736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0xf294ea272d6f8FedC08aCf8E93ff50fe99E1f7E8" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/ActivePool_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/ActivePool_Proxy.json new file mode 100644 index 00000000..5f250b46 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/ActivePool_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0xf294ea272d6f8FedC08aCf8E93ff50fe99E1f7E8", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/collSurplusPool.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/CollSurplusPool.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/collSurplusPool.json rename to packages/contracts/deployment/deployments/rskSovrynMainnet/CollSurplusPool.json index 5bbed856..94a6c658 100644 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/collSurplusPool.json +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/CollSurplusPool.json @@ -1,4 +1,5 @@ { + "address": "0x310ec7Fe6e4943DA773De8948255E37CC45e34bb", "_format": "hh-sol-artifact-1", "contractName": "CollSurplusPool", "sourceName": "contracts/CollSurplusPool.sol", @@ -271,6 +272,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b8152600401808060200182810382526022815260200180610d786022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b610c598061011f6000396000f3fe6080604052600436106100a05760003560e01c8063893d20e811610064578063893d20e8146101d55780639b56d6c9146101ea578063a3f4df7e1461021d578063b08bc722146102a7578063b32beb5b146102bc578063b7f8cf9b146102ef576100c5565b806313af4035146100ca57806314f6c3be146100ff578063363bf964146101265780633f10abab1461016b5780635a4d28bb146101a4576100c5565b366100c5576100ad610304565b6003546100c0903463ffffffff61034f16565b600355005b600080fd5b3480156100d657600080fd5b506100fd600480360360208110156100ed57600080fd5b50356001600160a01b03166103b0565b005b34801561010b57600080fd5b50610114610423565b60408051918252519081900360200190f35b34801561013257600080fd5b506100fd6004803603606081101561014957600080fd5b506001600160a01b038135811691602081013582169160409091013516610429565b34801561017757600080fd5b506100fd6004803603604081101561018e57600080fd5b506001600160a01b038135169060200135610595565b3480156101b057600080fd5b506101b9610621565b604080516001600160a01b039092168252519081900360200190f35b3480156101e157600080fd5b506101b9610630565b3480156101f657600080fd5b506101146004803603602081101561020d57600080fd5b50356001600160a01b031661065a565b34801561022957600080fd5b50610232610675565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561026c578181015183820152602001610254565b50505050905090810190601f1680156102995780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102b357600080fd5b506101b96106a0565b3480156102c857600080fd5b506100fd600480360360208110156102df57600080fd5b50356001600160a01b03166106af565b3480156102fb57600080fd5b506101b9610849565b6002546001600160a01b0316331461034d5760405162461bcd60e51b815260040180806020018281038252602a815260200180610b58602a913960400191505060405180910390fd5b565b6000828201838110156103a9576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6103b8610630565b6001600160a01b0316336001600160a01b031614610417576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61042081610858565b50565b60035490565b610431610630565b6001600160a01b0316336001600160a01b031614610490576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6104998361090d565b6104a28261090d565b6104ab8161090d565b600080546001600160a01b038086166001600160a01b0319928316811790935560018054868316908416179055600280549185169190921617905560408051918252517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1604080516001600160a01b038416815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038316815290517f78f058b189175430c48dc02699e3a0031ea4ff781536dc2fab847de4babdd8829181900360200190a1505050565b61059d6109c0565b6001600160a01b0382166000908152600460205260408120546105c6908363ffffffff61034f16565b6001600160a01b0384166000818152600460209081526040918290208490558151848152915193945091927ff0393a34d05e6567686ad4e097f9d9d2781565957394f1f0d984e5d8e6378f20929181900390910190a2505050565b6001546001600160a01b031681565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6001600160a01b031660009081526004602052604090205490565b6040518060400160405280600f81526020016e10dbdb1b14dd5c9c1b1d5cd41bdbdb608a1b81525081565b6002546001600160a01b031681565b6106b7610a09565b6001600160a01b0381166000908152600460205260409020548061070c5760405162461bcd60e51b8152600401808060200182810382526031815260200180610b276031913960400191505060405180910390fd5b6001600160a01b03821660008181526004602090815260408083208390558051928352517ff0393a34d05e6567686ad4e097f9d9d2781565957394f1f0d984e5d8e6378f209281900390910190a260035461076d908263ffffffff610a5216565b600355604080516001600160a01b03841681526020810183905281517f6109e2559dfa766aaec7118351d48a523f0a4157f49c8d68749c8ac41318ad12929181900390910190a16040516000906001600160a01b0384169083908381818185875af1925050503d80600081146107ff576040519150601f19603f3d011682016040523d82523d6000602084013e610804565b606091505b50509050806108445760405162461bcd60e51b8152600401808060200182810382526023815260200180610ba46023913960400191505060405180910390fd5b505050565b6000546001600160a01b031681565b6001600160a01b03811661089d5760405162461bcd60e51b8152600401808060200182810382526022815260200180610b826022913960400191505060405180910390fd5b806001600160a01b03166108af610630565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b038116610968576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806109bc576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b6001546001600160a01b0316331461034d5760405162461bcd60e51b815260040180806020018281038252602b815260200180610bf9602b913960400191505060405180910390fd5b6000546001600160a01b0316331461034d5760405162461bcd60e51b8152600401808060200182810382526032815260200180610bc76032913960400191505060405180910390fd5b60006103a983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060008184841115610b1e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ae3578181015183820152602001610acb565b50505050905090810190601f168015610b105780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe436f6c6c537572706c7573506f6f6c3a204e6f20636f6c6c61746572616c20617661696c61626c6520746f20636c61696d436f6c6c537572706c7573506f6f6c3a2043616c6c6572206973206e6f742041637469766520506f6f6c4f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373436f6c6c537572706c7573506f6f6c3a2073656e64696e6720455448206661696c6564436f6c6c537572706c7573506f6f6c3a2043616c6c6572206973206e6f7420426f72726f776572204f7065726174696f6e73436f6c6c537572706c7573506f6f6c3a2043616c6c6572206973206e6f742054726f76654d616e61676572a2646970667358221220ec19e79dbe7180a98cb7d6212d7b49be2e6c8b1fa1ef966e63158e1190ee1e1e64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", "deployedBytecode": "0x6080604052600436106100a05760003560e01c8063893d20e811610064578063893d20e8146101d55780639b56d6c9146101ea578063a3f4df7e1461021d578063b08bc722146102a7578063b32beb5b146102bc578063b7f8cf9b146102ef576100c5565b806313af4035146100ca57806314f6c3be146100ff578063363bf964146101265780633f10abab1461016b5780635a4d28bb146101a4576100c5565b366100c5576100ad610304565b6003546100c0903463ffffffff61034f16565b600355005b600080fd5b3480156100d657600080fd5b506100fd600480360360208110156100ed57600080fd5b50356001600160a01b03166103b0565b005b34801561010b57600080fd5b50610114610423565b60408051918252519081900360200190f35b34801561013257600080fd5b506100fd6004803603606081101561014957600080fd5b506001600160a01b038135811691602081013582169160409091013516610429565b34801561017757600080fd5b506100fd6004803603604081101561018e57600080fd5b506001600160a01b038135169060200135610595565b3480156101b057600080fd5b506101b9610621565b604080516001600160a01b039092168252519081900360200190f35b3480156101e157600080fd5b506101b9610630565b3480156101f657600080fd5b506101146004803603602081101561020d57600080fd5b50356001600160a01b031661065a565b34801561022957600080fd5b50610232610675565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561026c578181015183820152602001610254565b50505050905090810190601f1680156102995780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102b357600080fd5b506101b96106a0565b3480156102c857600080fd5b506100fd600480360360208110156102df57600080fd5b50356001600160a01b03166106af565b3480156102fb57600080fd5b506101b9610849565b6002546001600160a01b0316331461034d5760405162461bcd60e51b815260040180806020018281038252602a815260200180610b58602a913960400191505060405180910390fd5b565b6000828201838110156103a9576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6103b8610630565b6001600160a01b0316336001600160a01b031614610417576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61042081610858565b50565b60035490565b610431610630565b6001600160a01b0316336001600160a01b031614610490576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6104998361090d565b6104a28261090d565b6104ab8161090d565b600080546001600160a01b038086166001600160a01b0319928316811790935560018054868316908416179055600280549185169190921617905560408051918252517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1604080516001600160a01b038416815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038316815290517f78f058b189175430c48dc02699e3a0031ea4ff781536dc2fab847de4babdd8829181900360200190a1505050565b61059d6109c0565b6001600160a01b0382166000908152600460205260408120546105c6908363ffffffff61034f16565b6001600160a01b0384166000818152600460209081526040918290208490558151848152915193945091927ff0393a34d05e6567686ad4e097f9d9d2781565957394f1f0d984e5d8e6378f20929181900390910190a2505050565b6001546001600160a01b031681565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6001600160a01b031660009081526004602052604090205490565b6040518060400160405280600f81526020016e10dbdb1b14dd5c9c1b1d5cd41bdbdb608a1b81525081565b6002546001600160a01b031681565b6106b7610a09565b6001600160a01b0381166000908152600460205260409020548061070c5760405162461bcd60e51b8152600401808060200182810382526031815260200180610b276031913960400191505060405180910390fd5b6001600160a01b03821660008181526004602090815260408083208390558051928352517ff0393a34d05e6567686ad4e097f9d9d2781565957394f1f0d984e5d8e6378f209281900390910190a260035461076d908263ffffffff610a5216565b600355604080516001600160a01b03841681526020810183905281517f6109e2559dfa766aaec7118351d48a523f0a4157f49c8d68749c8ac41318ad12929181900390910190a16040516000906001600160a01b0384169083908381818185875af1925050503d80600081146107ff576040519150601f19603f3d011682016040523d82523d6000602084013e610804565b606091505b50509050806108445760405162461bcd60e51b8152600401808060200182810382526023815260200180610ba46023913960400191505060405180910390fd5b505050565b6000546001600160a01b031681565b6001600160a01b03811661089d5760405162461bcd60e51b8152600401808060200182810382526022815260200180610b826022913960400191505060405180910390fd5b806001600160a01b03166108af610630565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b038116610968576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806109bc576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b6001546001600160a01b0316331461034d5760405162461bcd60e51b815260040180806020018281038252602b815260200180610bf9602b913960400191505060405180910390fd5b6000546001600160a01b0316331461034d5760405162461bcd60e51b8152600401808060200182810382526032815260200180610bc76032913960400191505060405180910390fd5b60006103a983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060008184841115610b1e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ae3578181015183820152602001610acb565b50505050905090810190601f168015610b105780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe436f6c6c537572706c7573506f6f6c3a204e6f20636f6c6c61746572616c20617661696c61626c6520746f20636c61696d436f6c6c537572706c7573506f6f6c3a2043616c6c6572206973206e6f742041637469766520506f6f6c4f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373436f6c6c537572706c7573506f6f6c3a2073656e64696e6720455448206661696c6564436f6c6c537572706c7573506f6f6c3a2043616c6c6572206973206e6f7420426f72726f776572204f7065726174696f6e73436f6c6c537572706c7573506f6f6c3a2043616c6c6572206973206e6f742054726f76654d616e61676572a2646970667358221220ec19e79dbe7180a98cb7d6212d7b49be2e6c8b1fa1ef966e63158e1190ee1e1e64736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x6b74D66210f78dF0Ffb3A0D6A87471A1345C1284" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/CollSurplusPool_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/CollSurplusPool_Proxy.json new file mode 100644 index 00000000..6b8ff98a --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/CollSurplusPool_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0x310ec7Fe6e4943DA773De8948255E37CC45e34bb", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/CommunityIssuance.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/CommunityIssuance.json new file mode 100644 index 00000000..d3474072 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/CommunityIssuance.json @@ -0,0 +1,311 @@ +{ + "address": "0x9398131Dee201c7B530c5E3bAeeEB2e5B10F231c", + "_format": "hh-sol-artifact-1", + "contractName": "CommunityIssuance", + "sourceName": "contracts/ZERO/CommunityIssuance.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_communityPotAddress", + "type": "address" + } + ], + "name": "CommunityPotAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_zeroTokenAddress", + "type": "address" + } + ], + "name": "FundingWalletAddressSet", + "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": "uint256", + "name": "_fundingWalletAddress", + "type": "uint256" + } + ], + "name": "TotalZEROIssuedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_zeroTokenAddress", + "type": "address" + } + ], + "name": "ZEROTokenAddressSet", + "type": "event" + }, + { + "inputs": [], + "name": "DECIMAL_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ISSUANCE_FACTOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SECONDS_IN_ONE_MINUTE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ZEROSupplyCap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "communityPotAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deploymentTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fundingWalletAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_zeroTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_communityPotAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_fundingWalletAddress", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "issueZERO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_ZEROamount", + "type": "uint256" + } + ], + "name": "receiveZero", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_ZEROamount", + "type": "uint256" + } + ], + "name": "sendZERO", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalZEROIssued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "zeroToken", + "outputs": [ + { + "internalType": "contract IZEROToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x60806040526000805534801561001457600080fd5b50610027336001600160e01b0361002c16565b610114565b6001600160a01b0381166100715760405162461bcd60e51b8152600401808060200182810382526022815260200180610f086022913960400191505060405180910390fd5b6001600160a01b03811661008c6001600160e01b036100ea16565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b610de5806101236000396000f3fe608060405234801561001057600080fd5b50600436106100e05760003560e01c80639d4101b7116100875780639d4101b714610197578063a20baee61461019f578063a3f4df7e146101a7578063c0c53b8b14610224578063e59be5861461025c578063ecda10f514610264578063f1bd258b1461026c578063f294bd9214610298576100e0565b80630fc83da3146100e557806313af4035146100ff5780631a5a934a1461012757806321492b2a1461014b57806337362c181461015357806361ec893d1461017f578063893d20e8146101875780639ce21f3c1461018f575b600080fd5b6100ed6102a0565b60408051918252519081900360200190f35b6101256004803603602081101561011557600080fd5b50356001600160a01b03166102ac565b005b61012f61031f565b604080516001600160a01b039092168252519081900360200190f35b6100ed61032e565b6101256004803603604081101561016957600080fd5b506001600160a01b038135169060200135610334565b6100ed610410565b61012f610415565b61012f61043f565b6100ed61044e565b6100ed610454565b6101af610460565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101e95781810151838201526020016101d1565b50505050905090810190601f1680156102165780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101256004803603606081101561023a57600080fd5b506001600160a01b03813581169160208101358216916040909101351661048d565b6100ed6105b4565b6100ed61064d565b6101256004803603604081101561028257600080fd5b506001600160a01b038135169060200135610653565b61012f6107c9565b670de0b5809a6f939881565b6102b4610415565b6001600160a01b0316336001600160a01b031614610313576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61031c816107d8565b50565b6002546001600160a01b031681565b60005481565b61033c61088d565b6001546040805163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529151600093929092169163a9059cbb9160448082019260209290919082900301818787803b15801561039557600080fd5b505af11580156103a9573d6000803e3d6000fd5b505050506040513d60208110156103bf57600080fd5b505190508061040b576040805162461bcd60e51b81526020600482015260136024820152724661696c656420746f2073656e64205a45524f60681b604482015290519081900360640190fd5b505050565b603c81565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6003546001600160a01b031681565b60045481565b670de0b6b3a764000081565b60405180604001604052806011815260200170436f6d6d756e69747949737375616e636560781b81525081565b610495610415565b6001600160a01b0316336001600160a01b0316146104f4576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6104fd836108d8565b610506826108d8565b600180546001600160a01b038086166001600160a01b0319928316811790935560028054868316908416179055600380549185169190921617905560408051918252517f7eeded1a6761a0ca57ff60155bdd3e94fbfe5d9e8dc5013b3aa195b8d9e851ea9181900360200190a1604080516001600160a01b038416815290517f47ebfdc80bf05a81c1216176fd90779f8f67326c8d82eb50b3bce67473f188ce9181900360200190a1505050565b60006105be61088d565b60006105f2670de0b6b3a76400006105e66105d761098b565b6000549063ffffffff6109f516565b9063ffffffff610a5716565b9050600061060b60045483610a9990919063ffffffff16565b60048390556040805184815290519192507f0e4f366add234067215e649a6bccebac27241d6488de286967c468de64f62614919081900360200190a191505090565b60055481565b6003546001600160a01b0383811691161461069f5760405162461bcd60e51b8152600401808060200182810382526028815260200180610d446028913960400191505060405180910390fd5b600054156106f4576040805162461bcd60e51b815260206004820152601c60248201527f436f6d6d756e69747920706f7420616c72656164792066756e64656400000000604482015290519081900360640190fd5b600154604080516323b872dd60e01b81526001600160a01b03858116600483015230602483015260448201859052915191909216916323b872dd9160648083019260209291908290030181600087803b15801561075057600080fd5b505af1158015610764573d6000803e3d6000fd5b505050506040513d602081101561077a57600080fd5b50516107bf576040805162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b6000555042600555565b6001546001600160a01b031681565b6001600160a01b03811661081d5760405162461bcd60e51b8152600401808060200182810382526022815260200180610d226022913960400191505060405180910390fd5b806001600160a01b031661082f610415565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6002546001600160a01b031633146108d65760405162461bcd60e51b8152600401808060200182810382526023815260200180610d8d6023913960400191505060405180910390fd5b565b6001600160a01b038116610933576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b80610987576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b6000806109a8603c6105e660055442610a9990919063ffffffff16565b905060006109be670de0b5809a6f939883610adb565b905060006109da670de0b6b3a76400008363ffffffff610a9916565b9050670de0b6b3a76400008111156109ee57fe5b9250505090565b600082610a0457506000610a51565b82820282848281610a1157fe5b0414610a4e5760405162461bcd60e51b8152600401808060200182810382526021815260200180610d6c6021913960400191505060405180910390fd5b90505b92915050565b6000610a4e83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610b90565b6000610a4e83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610c32565b6000631f540500821115610af157631f54050091505b81610b055750670de0b6b3a7640000610a51565b670de0b6b3a764000083835b6001811115610b7c5760028106610b4657610b2c8283610c8c565b9150610b3f81600263ffffffff610a5716565b9050610b77565b610b508284610c8c565b9250610b5c8283610c8c565b9150610b7460026105e683600163ffffffff610a9916565b90505b610b11565b610b868284610c8c565b9695505050505050565b60008183610c1c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610be1578181015183820152602001610bc9565b50505050905090810190601f168015610c0e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581610c2857fe5b0495945050505050565b60008184841115610c845760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610be1578181015183820152602001610bc9565b505050900390565b600080610c9f848463ffffffff6109f516565b9050610cbf670de0b6b3a76400006105e6836706f05b59d3b20000610cc7565b949350505050565b600082820183811015610a4e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fdfe4f776e61626c653a3a7365744f776e65723a20696e76616c696420616464726573734f6e6c79207468652066756e64696e672077616c6c65742063616e206465706f736974205a45524f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6d6d756e69747949737375616e63653a2063616c6c6572206973206e6f74205350a26469706673582212206b553fb1df1bfd823d8fd29b2fde34c87b6e41e5de8d6fad1bd46628da8bff8264736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100e05760003560e01c80639d4101b7116100875780639d4101b714610197578063a20baee61461019f578063a3f4df7e146101a7578063c0c53b8b14610224578063e59be5861461025c578063ecda10f514610264578063f1bd258b1461026c578063f294bd9214610298576100e0565b80630fc83da3146100e557806313af4035146100ff5780631a5a934a1461012757806321492b2a1461014b57806337362c181461015357806361ec893d1461017f578063893d20e8146101875780639ce21f3c1461018f575b600080fd5b6100ed6102a0565b60408051918252519081900360200190f35b6101256004803603602081101561011557600080fd5b50356001600160a01b03166102ac565b005b61012f61031f565b604080516001600160a01b039092168252519081900360200190f35b6100ed61032e565b6101256004803603604081101561016957600080fd5b506001600160a01b038135169060200135610334565b6100ed610410565b61012f610415565b61012f61043f565b6100ed61044e565b6100ed610454565b6101af610460565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101e95781810151838201526020016101d1565b50505050905090810190601f1680156102165780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101256004803603606081101561023a57600080fd5b506001600160a01b03813581169160208101358216916040909101351661048d565b6100ed6105b4565b6100ed61064d565b6101256004803603604081101561028257600080fd5b506001600160a01b038135169060200135610653565b61012f6107c9565b670de0b5809a6f939881565b6102b4610415565b6001600160a01b0316336001600160a01b031614610313576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61031c816107d8565b50565b6002546001600160a01b031681565b60005481565b61033c61088d565b6001546040805163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529151600093929092169163a9059cbb9160448082019260209290919082900301818787803b15801561039557600080fd5b505af11580156103a9573d6000803e3d6000fd5b505050506040513d60208110156103bf57600080fd5b505190508061040b576040805162461bcd60e51b81526020600482015260136024820152724661696c656420746f2073656e64205a45524f60681b604482015290519081900360640190fd5b505050565b603c81565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6003546001600160a01b031681565b60045481565b670de0b6b3a764000081565b60405180604001604052806011815260200170436f6d6d756e69747949737375616e636560781b81525081565b610495610415565b6001600160a01b0316336001600160a01b0316146104f4576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6104fd836108d8565b610506826108d8565b600180546001600160a01b038086166001600160a01b0319928316811790935560028054868316908416179055600380549185169190921617905560408051918252517f7eeded1a6761a0ca57ff60155bdd3e94fbfe5d9e8dc5013b3aa195b8d9e851ea9181900360200190a1604080516001600160a01b038416815290517f47ebfdc80bf05a81c1216176fd90779f8f67326c8d82eb50b3bce67473f188ce9181900360200190a1505050565b60006105be61088d565b60006105f2670de0b6b3a76400006105e66105d761098b565b6000549063ffffffff6109f516565b9063ffffffff610a5716565b9050600061060b60045483610a9990919063ffffffff16565b60048390556040805184815290519192507f0e4f366add234067215e649a6bccebac27241d6488de286967c468de64f62614919081900360200190a191505090565b60055481565b6003546001600160a01b0383811691161461069f5760405162461bcd60e51b8152600401808060200182810382526028815260200180610d446028913960400191505060405180910390fd5b600054156106f4576040805162461bcd60e51b815260206004820152601c60248201527f436f6d6d756e69747920706f7420616c72656164792066756e64656400000000604482015290519081900360640190fd5b600154604080516323b872dd60e01b81526001600160a01b03858116600483015230602483015260448201859052915191909216916323b872dd9160648083019260209291908290030181600087803b15801561075057600080fd5b505af1158015610764573d6000803e3d6000fd5b505050506040513d602081101561077a57600080fd5b50516107bf576040805162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b6000555042600555565b6001546001600160a01b031681565b6001600160a01b03811661081d5760405162461bcd60e51b8152600401808060200182810382526022815260200180610d226022913960400191505060405180910390fd5b806001600160a01b031661082f610415565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6002546001600160a01b031633146108d65760405162461bcd60e51b8152600401808060200182810382526023815260200180610d8d6023913960400191505060405180910390fd5b565b6001600160a01b038116610933576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b80610987576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b6000806109a8603c6105e660055442610a9990919063ffffffff16565b905060006109be670de0b5809a6f939883610adb565b905060006109da670de0b6b3a76400008363ffffffff610a9916565b9050670de0b6b3a76400008111156109ee57fe5b9250505090565b600082610a0457506000610a51565b82820282848281610a1157fe5b0414610a4e5760405162461bcd60e51b8152600401808060200182810382526021815260200180610d6c6021913960400191505060405180910390fd5b90505b92915050565b6000610a4e83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610b90565b6000610a4e83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610c32565b6000631f540500821115610af157631f54050091505b81610b055750670de0b6b3a7640000610a51565b670de0b6b3a764000083835b6001811115610b7c5760028106610b4657610b2c8283610c8c565b9150610b3f81600263ffffffff610a5716565b9050610b77565b610b508284610c8c565b9250610b5c8283610c8c565b9150610b7460026105e683600163ffffffff610a9916565b90505b610b11565b610b868284610c8c565b9695505050505050565b60008183610c1c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610be1578181015183820152602001610bc9565b50505050905090810190601f168015610c0e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581610c2857fe5b0495945050505050565b60008184841115610c845760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610be1578181015183820152602001610bc9565b505050900390565b600080610c9f848463ffffffff6109f516565b9050610cbf670de0b6b3a76400006105e6836706f05b59d3b20000610cc7565b949350505050565b600082820183811015610a4e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fdfe4f776e61626c653a3a7365744f776e65723a20696e76616c696420616464726573734f6e6c79207468652066756e64696e672077616c6c65742063616e206465706f736974205a45524f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6d6d756e69747949737375616e63653a2063616c6c6572206973206e6f74205350a26469706673582212206b553fb1df1bfd823d8fd29b2fde34c87b6e41e5de8d6fad1bd46628da8bff8264736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/CommunityIssuance_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/CommunityIssuance_Proxy.json new file mode 100644 index 00000000..478f8bb6 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/CommunityIssuance_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0x9398131Dee201c7B530c5E3bAeeEB2e5B10F231c", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/defaultPool.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/DefaultPool.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynMainnet/defaultPool.json rename to packages/contracts/deployment/deployments/rskSovrynMainnet/DefaultPool.json index a37e7485..30526092 100644 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/defaultPool.json +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/DefaultPool.json @@ -1,4 +1,5 @@ { + "address": "0xcdbA14ca707B99afb8CA93E178aD614Db422a030", "_format": "hh-sol-artifact-1", "contractName": "DefaultPool", "sourceName": "contracts/DefaultPool.sol", @@ -301,6 +302,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b8152600401808060200182810382526022815260200180610bd56022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b610ab68061011f6000396000f3fe6080604052600436106100a05760003560e01c8063893d20e811610064578063893d20e8146101ca57806390107afe146101df578063a3f4df7e1461021a578063b08bc722146102a4578063be41205f146102b9578063f2e91d71146102e3576100f9565b806313af4035146100fe57806314f6c3be146101335780632439789a1461015a5780633963e980146101845780635a4d28bb14610199576100f9565b366100f9576100ad61030d565b6002546100c0903463ffffffff61035816565b600281905560408051918252517f9a14ae677a60400af9176bed2e2d5ce8dfa6405e6c1702debb27668f567214289181900360200190a1005b600080fd5b34801561010a57600080fd5b506101316004803603602081101561012157600080fd5b50356001600160a01b03166103b9565b005b34801561013f57600080fd5b5061014861042c565b60408051918252519081900360200190f35b34801561016657600080fd5b506101316004803603602081101561017d57600080fd5b5035610432565b34801561019057600080fd5b50610148610487565b3480156101a557600080fd5b506101ae61048d565b604080516001600160a01b039092168252519081900360200190f35b3480156101d657600080fd5b506101ae61049c565b3480156101eb57600080fd5b506101316004803603604081101561020257600080fd5b506001600160a01b03813581169160200135166104c6565b34801561022657600080fd5b5061022f6105df565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610269578181015183820152602001610251565b50505050905090810190601f1680156102965780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102b057600080fd5b506101ae610606565b3480156102c557600080fd5b50610131600480360360208110156102dc57600080fd5b5035610615565b3480156102ef57600080fd5b506101316004803603602081101561030657600080fd5b5035610765565b6001546001600160a01b031633146103565760405162461bcd60e51b8152600401808060200182810382526029815260200180610a0b6029913960400191505060405180910390fd5b565b6000828201838110156103b2576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6103c161049c565b6001600160a01b0316336001600160a01b031614610420576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61042981610780565b50565b60025490565b61043a610835565b60035461044d908263ffffffff61087e16565b600381905560408051918252517f636083bfd8929ae461979d51af53349434cd5ee35f983909b704bded4142b9519181900360200190a150565b60035490565b6000546001600160a01b031681565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104ce61049c565b6001600160a01b0316336001600160a01b03161461052d576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b610536826108c0565b61053f816108c0565b600080546001600160a01b038085166001600160a01b03199283168117909355600180549185169190921617905560408051918252517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038316815290517f78f058b189175430c48dc02699e3a0031ea4ff781536dc2fab847de4babdd8829181900360200190a15050565b6040518060400160405280600b81526020016a111959985d5b1d141bdbdb60aa1b81525081565b6001546001600160a01b031681565b61061d610835565b6001546002546001600160a01b039091169061063f908363ffffffff61087e16565b600281905560408051918252517f9a14ae677a60400af9176bed2e2d5ce8dfa6405e6c1702debb27668f567214289181900360200190a1604080516001600160a01b03831681526020810184905281517f6109e2559dfa766aaec7118351d48a523f0a4157f49c8d68749c8ac41318ad12929181900390910190a16040516000906001600160a01b0383169084908381818185875af1925050503d8060008114610705576040519150601f19603f3d011682016040523d82523d6000602084013e61070a565b606091505b5050905080610760576040805162461bcd60e51b815260206004820152601f60248201527f44656661756c74506f6f6c3a2073656e64696e6720455448206661696c656400604482015290519081900360640190fd5b505050565b61076d610835565b60035461044d908263ffffffff61035816565b6001600160a01b0381166107c55760405162461bcd60e51b8152600401808060200182810382526022815260200180610a346022913960400191505060405180910390fd5b806001600160a01b03166107d761049c565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6000546001600160a01b031633146103565760405162461bcd60e51b815260040180806020018281038252602b815260200180610a56602b913960400191505060405180910390fd5b60006103b283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610973565b6001600160a01b03811661091b576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b8061096f576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b60008184841115610a025760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156109c75781810151838201526020016109af565b50505050905090810190601f1680156109f45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe44656661756c74506f6f6c3a2043616c6c6572206973206e6f742074686520416374697665506f6f6c4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737344656661756c74506f6f6c3a2043616c6c6572206973206e6f74207468652054726f76654d616e61676572a2646970667358221220d99aea28c644c442996807d1a9df6b9c6fcb9a4741349be927c8e86d5886d30464736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", "deployedBytecode": "0x6080604052600436106100a05760003560e01c8063893d20e811610064578063893d20e8146101ca57806390107afe146101df578063a3f4df7e1461021a578063b08bc722146102a4578063be41205f146102b9578063f2e91d71146102e3576100f9565b806313af4035146100fe57806314f6c3be146101335780632439789a1461015a5780633963e980146101845780635a4d28bb14610199576100f9565b366100f9576100ad61030d565b6002546100c0903463ffffffff61035816565b600281905560408051918252517f9a14ae677a60400af9176bed2e2d5ce8dfa6405e6c1702debb27668f567214289181900360200190a1005b600080fd5b34801561010a57600080fd5b506101316004803603602081101561012157600080fd5b50356001600160a01b03166103b9565b005b34801561013f57600080fd5b5061014861042c565b60408051918252519081900360200190f35b34801561016657600080fd5b506101316004803603602081101561017d57600080fd5b5035610432565b34801561019057600080fd5b50610148610487565b3480156101a557600080fd5b506101ae61048d565b604080516001600160a01b039092168252519081900360200190f35b3480156101d657600080fd5b506101ae61049c565b3480156101eb57600080fd5b506101316004803603604081101561020257600080fd5b506001600160a01b03813581169160200135166104c6565b34801561022657600080fd5b5061022f6105df565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610269578181015183820152602001610251565b50505050905090810190601f1680156102965780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102b057600080fd5b506101ae610606565b3480156102c557600080fd5b50610131600480360360208110156102dc57600080fd5b5035610615565b3480156102ef57600080fd5b506101316004803603602081101561030657600080fd5b5035610765565b6001546001600160a01b031633146103565760405162461bcd60e51b8152600401808060200182810382526029815260200180610a0b6029913960400191505060405180910390fd5b565b6000828201838110156103b2576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6103c161049c565b6001600160a01b0316336001600160a01b031614610420576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61042981610780565b50565b60025490565b61043a610835565b60035461044d908263ffffffff61087e16565b600381905560408051918252517f636083bfd8929ae461979d51af53349434cd5ee35f983909b704bded4142b9519181900360200190a150565b60035490565b6000546001600160a01b031681565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104ce61049c565b6001600160a01b0316336001600160a01b03161461052d576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b610536826108c0565b61053f816108c0565b600080546001600160a01b038085166001600160a01b03199283168117909355600180549185169190921617905560408051918252517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038316815290517f78f058b189175430c48dc02699e3a0031ea4ff781536dc2fab847de4babdd8829181900360200190a15050565b6040518060400160405280600b81526020016a111959985d5b1d141bdbdb60aa1b81525081565b6001546001600160a01b031681565b61061d610835565b6001546002546001600160a01b039091169061063f908363ffffffff61087e16565b600281905560408051918252517f9a14ae677a60400af9176bed2e2d5ce8dfa6405e6c1702debb27668f567214289181900360200190a1604080516001600160a01b03831681526020810184905281517f6109e2559dfa766aaec7118351d48a523f0a4157f49c8d68749c8ac41318ad12929181900390910190a16040516000906001600160a01b0383169084908381818185875af1925050503d8060008114610705576040519150601f19603f3d011682016040523d82523d6000602084013e61070a565b606091505b5050905080610760576040805162461bcd60e51b815260206004820152601f60248201527f44656661756c74506f6f6c3a2073656e64696e6720455448206661696c656400604482015290519081900360640190fd5b505050565b61076d610835565b60035461044d908263ffffffff61035816565b6001600160a01b0381166107c55760405162461bcd60e51b8152600401808060200182810382526022815260200180610a346022913960400191505060405180910390fd5b806001600160a01b03166107d761049c565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6000546001600160a01b031633146103565760405162461bcd60e51b815260040180806020018281038252602b815260200180610a56602b913960400191505060405180910390fd5b60006103b283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610973565b6001600160a01b03811661091b576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b8061096f576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b60008184841115610a025760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156109c75781810151838201526020016109af565b50505050905090810190601f1680156109f45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe44656661756c74506f6f6c3a2043616c6c6572206973206e6f742074686520416374697665506f6f6c4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737344656661756c74506f6f6c3a2043616c6c6572206973206e6f74207468652054726f76654d616e61676572a2646970667358221220d99aea28c644c442996807d1a9df6b9c6fcb9a4741349be927c8e86d5886d30464736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0xcdbA14ca707B99afb8CA93E178aD614Db422a030" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/DefaultPool_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/DefaultPool_Proxy.json new file mode 100644 index 00000000..6c08cb85 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/DefaultPool_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0xcdbA14ca707B99afb8CA93E178aD614Db422a030", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/feeDistributor.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/FeeDistributor.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/feeDistributor.json rename to packages/contracts/deployment/deployments/rskSovrynMainnet/FeeDistributor.json index 28e30969..eaa9c61a 100644 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/feeDistributor.json +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/FeeDistributor.json @@ -1,4 +1,5 @@ { + "address": "0x1261d5872d56e2Ab61B3C68451D015b752105027", "_format": "hh-sol-artifact-1", "contractName": "FeeDistributor", "sourceName": "contracts/FeeDistributor.sol", @@ -353,6 +354,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b815260040180806020018281038252602281526020018061129c6022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b61117d8061011f6000396000f3fe6080604052600436106100c15760003560e01c8063b08bc7221161006f578063b08bc72214610229578063bb57ad201461023e578063d9db1a6814610253578063eaa8ba7f14610268578063ec5472fd146102cd578063ec9f7d46146102e2578063f231f7cd146102f7576100d0565b806313af4035146100d55780633d83908a146101085780636b7dbb2d1461013957806377553ad41461014e578063893d20e8146101635780638e93c64914610178578063a3f4df7e1461019f576100d0565b366100d0576100ce610321565b005b600080fd5b3480156100e157600080fd5b506100ce600480360360208110156100f857600080fd5b50356001600160a01b031661036c565b34801561011457600080fd5b5061011d6103df565b604080516001600160a01b039092168252519081900360200190f35b34801561014557600080fd5b5061011d6103ee565b34801561015a57600080fd5b5061011d6103fd565b34801561016f57600080fd5b5061011d61040c565b34801561018457600080fd5b5061018d610436565b60408051918252519081900360200190f35b3480156101ab57600080fd5b506101b461043c565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101ee5781810151838201526020016101d6565b50505050905090810190601f16801561021b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023557600080fd5b5061011d610466565b34801561024a57600080fd5b506100ce610475565b34801561025f57600080fd5b5061011d610585565b34801561027457600080fd5b506100ce600480360360e081101561028b57600080fd5b506001600160a01b038135811691602081013582169160408201358116916060810135821691608082013581169160a081013582169160c09091013516610594565b3480156102d957600080fd5b5061011d610857565b3480156102ee57600080fd5b5061011d610866565b34801561030357600080fd5b506100ce6004803603602081101561031a57600080fd5b5035610875565b6006546001600160a01b0316331461036a5760405162461bcd60e51b81526004018080602001828103825260288152602001806111206028913960400191505060405180910390fd5b565b61037461040c565b6001600160a01b0316336001600160a01b0316146103d3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6103dc816108e1565b50565b6003546001600160a01b031681565b6000546001600160a01b031681565b6002546001600160a01b031681565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b60075481565b6040518060400160405280600e81526020016d2332b2a234b9ba3934b13aba37b960911b81525081565b6006546001600160a01b031681565b6002546001600160a01b031633148061049857506003546001600160a01b031633145b6104e9576040805162461bcd60e51b815260206004820152601e60248201527f4665654469737472696275746f723a20696e76616c69642063616c6c65720000604482015290519081900360640190fd5b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561053457600080fd5b505afa158015610548573d6000803e3d6000fd5b505050506040513d602081101561055e57600080fd5b505190504781156105725761057282610996565b80156105815761058181610c58565b5050565b6004546001600160a01b031681565b61059c61040c565b6001600160a01b0316336001600160a01b0316146105fb576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61060487610e29565b61060d86610e29565b61061685610e29565b61061f84610e29565b61062883610e29565b61063182610e29565b61063a81610e29565b600080546001600160a01b03199081166001600160a01b038a81169182179093556001805483168a851617905560028054831689851617905560038054831688851617905560048054831687851617905560058054831686851617905560068054909216928416929092179055670de0b6b3a764000060075560408051918252517f963023df1091dc8c0e46db982274139953d69a4d688a740bee4aa40fa318497e916020908290030190a1604080516001600160a01b038816815290517fc7b150c129c1c24ff23a07f2d3c9579928b1a51697a8a1f79dd07888fc904b849181900360200190a1604080516001600160a01b038716815290517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1604080516001600160a01b038616815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038516815290517f35bae0aeb0bdf7e62f85dbfcc7876b98015f550d75ae3deb0505c0565db12f4b9181900360200190a1604080516001600160a01b038416815290517fcdf33850c44a1a874b5fefb51dae615ac6afebd581ef90d571f81b06541d8e9d9181900360200190a1604080516001600160a01b038316815290517f8f6a6e7d20a3233e0a79883272259ffbd7a243734e397bc2b4642c79d7fa8a6d9181900360200190a150505050505050565b6001546001600160a01b031681565b6005546001600160a01b031681565b61087d61040c565b6001600160a01b0316336001600160a01b0316146108dc576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b600755565b6001600160a01b0381166109265760405162461bcd60e51b81526004018080602001828103825260228152602001806110bb6022913960400191505060405180910390fd5b806001600160a01b031661093861040c565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b60006109c5670de0b6b3a76400006109b960075485610ed890919063ffffffff16565b9063ffffffff610f3a16565b600554600080546040805163095ea7b360e01b81526001600160a01b03928316600482015260248101869052905194955092169263095ea7b3926044808201936020939283900390910190829087803b158015610a2157600080fd5b505af1158015610a35573d6000803e3d6000fd5b505050506040513d6020811015610a4b57600080fd5b5050600080546005546040805163abe979e160e01b81526001600160a01b0392831660048201526bffffffffffffffffffffffff861660248201529051919092169263abe979e1926044808201939182900301818387803b158015610aaf57600080fd5b505af1158015610ac3573d6000803e3d6000fd5b505050506000610adc8284610f7c90919063ffffffff16565b90508015610c20576005546001546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b158015610b3d57600080fd5b505af1158015610b51573d6000803e3d6000fd5b505050506040513d6020811015610b6757600080fd5b5051610bba576040805162461bcd60e51b815260206004820152601d60248201527f436f75646e27742065786563757465205a555344207472616e73666572000000604482015290519081900360640190fd5b6001546040805163187daae360e21b81526004810184905290516001600160a01b03909216916361f6ab8c9160248082019260009290919082900301818387803b158015610c0757600080fd5b505af1158015610c1b573d6000803e3d6000fd5b505050505b6040805184815290517f3168880c2a9a8e657d1de00769e3baefa8c1153f1847a85b43070ee5fed512959181900360200190a1505050565b6000610c7b670de0b6b3a76400006109b960075485610ed890919063ffffffff16565b60008054604080516322a6fd9560e01b815290519394506001600160a01b03909116926322a6fd959285926004808201939182900301818588803b158015610cc257600080fd5b505af1158015610cd6573d6000803e3d6000fd5b50505050506000610cf08284610f7c90919063ffffffff16565b90508015610df1576001546040516000916001600160a01b03169083908381818185875af1925050503d8060008114610d45576040519150601f19603f3d011682016040523d82523d6000602084013e610d4a565b606091505b5050905080610d8a5760405162461bcd60e51b81526004018080602001828103825260228152602001806110dd6022913960400191505060405180910390fd5b60015460408051630f1f150d60e11b81526004810185905290516001600160a01b0390921691631e3e2a1a9160248082019260009290919082900301818387803b158015610dd757600080fd5b505af1158015610deb573d6000803e3d6000fd5b50505050505b6040805184815290517f3289490aa1b0ec56454cbd5d18bd6b8d79609982b2abe74eee579eb6f67581919181900360200190a1505050565b6001600160a01b038116610e84576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b80610581576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b600082610ee757506000610f34565b82820282848281610ef457fe5b0414610f315760405162461bcd60e51b81526004018080602001828103825260218152602001806110ff6021913960400191505060405180910390fd5b90505b92915050565b6000610f3183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610fbe565b6000610f3183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611060565b6000818361104a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561100f578181015183820152602001610ff7565b50505050905090810190601f16801561103c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161105657fe5b0495945050505050565b600081848411156110b25760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561100f578181015183820152602001610ff7565b50505090039056fe4f776e61626c653a3a7365744f776e65723a20696e76616c696420616464726573734665654469737472696275746f723a2073656e64696e6720455448206661696c6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774665654469737472696275746f723a2063616c6c6572206973206e6f7420416374697665506f6f6ca264697066735822122068cbf3a893e2b9713149ddceb6b3570b9d11482f5f07b3b3066ad70f4eec87e264736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", "deployedBytecode": "0x6080604052600436106100c15760003560e01c8063b08bc7221161006f578063b08bc72214610229578063bb57ad201461023e578063d9db1a6814610253578063eaa8ba7f14610268578063ec5472fd146102cd578063ec9f7d46146102e2578063f231f7cd146102f7576100d0565b806313af4035146100d55780633d83908a146101085780636b7dbb2d1461013957806377553ad41461014e578063893d20e8146101635780638e93c64914610178578063a3f4df7e1461019f576100d0565b366100d0576100ce610321565b005b600080fd5b3480156100e157600080fd5b506100ce600480360360208110156100f857600080fd5b50356001600160a01b031661036c565b34801561011457600080fd5b5061011d6103df565b604080516001600160a01b039092168252519081900360200190f35b34801561014557600080fd5b5061011d6103ee565b34801561015a57600080fd5b5061011d6103fd565b34801561016f57600080fd5b5061011d61040c565b34801561018457600080fd5b5061018d610436565b60408051918252519081900360200190f35b3480156101ab57600080fd5b506101b461043c565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101ee5781810151838201526020016101d6565b50505050905090810190601f16801561021b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023557600080fd5b5061011d610466565b34801561024a57600080fd5b506100ce610475565b34801561025f57600080fd5b5061011d610585565b34801561027457600080fd5b506100ce600480360360e081101561028b57600080fd5b506001600160a01b038135811691602081013582169160408201358116916060810135821691608082013581169160a081013582169160c09091013516610594565b3480156102d957600080fd5b5061011d610857565b3480156102ee57600080fd5b5061011d610866565b34801561030357600080fd5b506100ce6004803603602081101561031a57600080fd5b5035610875565b6006546001600160a01b0316331461036a5760405162461bcd60e51b81526004018080602001828103825260288152602001806111206028913960400191505060405180910390fd5b565b61037461040c565b6001600160a01b0316336001600160a01b0316146103d3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6103dc816108e1565b50565b6003546001600160a01b031681565b6000546001600160a01b031681565b6002546001600160a01b031681565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b60075481565b6040518060400160405280600e81526020016d2332b2a234b9ba3934b13aba37b960911b81525081565b6006546001600160a01b031681565b6002546001600160a01b031633148061049857506003546001600160a01b031633145b6104e9576040805162461bcd60e51b815260206004820152601e60248201527f4665654469737472696275746f723a20696e76616c69642063616c6c65720000604482015290519081900360640190fd5b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561053457600080fd5b505afa158015610548573d6000803e3d6000fd5b505050506040513d602081101561055e57600080fd5b505190504781156105725761057282610996565b80156105815761058181610c58565b5050565b6004546001600160a01b031681565b61059c61040c565b6001600160a01b0316336001600160a01b0316146105fb576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61060487610e29565b61060d86610e29565b61061685610e29565b61061f84610e29565b61062883610e29565b61063182610e29565b61063a81610e29565b600080546001600160a01b03199081166001600160a01b038a81169182179093556001805483168a851617905560028054831689851617905560038054831688851617905560048054831687851617905560058054831686851617905560068054909216928416929092179055670de0b6b3a764000060075560408051918252517f963023df1091dc8c0e46db982274139953d69a4d688a740bee4aa40fa318497e916020908290030190a1604080516001600160a01b038816815290517fc7b150c129c1c24ff23a07f2d3c9579928b1a51697a8a1f79dd07888fc904b849181900360200190a1604080516001600160a01b038716815290517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1604080516001600160a01b038616815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038516815290517f35bae0aeb0bdf7e62f85dbfcc7876b98015f550d75ae3deb0505c0565db12f4b9181900360200190a1604080516001600160a01b038416815290517fcdf33850c44a1a874b5fefb51dae615ac6afebd581ef90d571f81b06541d8e9d9181900360200190a1604080516001600160a01b038316815290517f8f6a6e7d20a3233e0a79883272259ffbd7a243734e397bc2b4642c79d7fa8a6d9181900360200190a150505050505050565b6001546001600160a01b031681565b6005546001600160a01b031681565b61087d61040c565b6001600160a01b0316336001600160a01b0316146108dc576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b600755565b6001600160a01b0381166109265760405162461bcd60e51b81526004018080602001828103825260228152602001806110bb6022913960400191505060405180910390fd5b806001600160a01b031661093861040c565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b60006109c5670de0b6b3a76400006109b960075485610ed890919063ffffffff16565b9063ffffffff610f3a16565b600554600080546040805163095ea7b360e01b81526001600160a01b03928316600482015260248101869052905194955092169263095ea7b3926044808201936020939283900390910190829087803b158015610a2157600080fd5b505af1158015610a35573d6000803e3d6000fd5b505050506040513d6020811015610a4b57600080fd5b5050600080546005546040805163abe979e160e01b81526001600160a01b0392831660048201526bffffffffffffffffffffffff861660248201529051919092169263abe979e1926044808201939182900301818387803b158015610aaf57600080fd5b505af1158015610ac3573d6000803e3d6000fd5b505050506000610adc8284610f7c90919063ffffffff16565b90508015610c20576005546001546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b158015610b3d57600080fd5b505af1158015610b51573d6000803e3d6000fd5b505050506040513d6020811015610b6757600080fd5b5051610bba576040805162461bcd60e51b815260206004820152601d60248201527f436f75646e27742065786563757465205a555344207472616e73666572000000604482015290519081900360640190fd5b6001546040805163187daae360e21b81526004810184905290516001600160a01b03909216916361f6ab8c9160248082019260009290919082900301818387803b158015610c0757600080fd5b505af1158015610c1b573d6000803e3d6000fd5b505050505b6040805184815290517f3168880c2a9a8e657d1de00769e3baefa8c1153f1847a85b43070ee5fed512959181900360200190a1505050565b6000610c7b670de0b6b3a76400006109b960075485610ed890919063ffffffff16565b60008054604080516322a6fd9560e01b815290519394506001600160a01b03909116926322a6fd959285926004808201939182900301818588803b158015610cc257600080fd5b505af1158015610cd6573d6000803e3d6000fd5b50505050506000610cf08284610f7c90919063ffffffff16565b90508015610df1576001546040516000916001600160a01b03169083908381818185875af1925050503d8060008114610d45576040519150601f19603f3d011682016040523d82523d6000602084013e610d4a565b606091505b5050905080610d8a5760405162461bcd60e51b81526004018080602001828103825260228152602001806110dd6022913960400191505060405180910390fd5b60015460408051630f1f150d60e11b81526004810185905290516001600160a01b0390921691631e3e2a1a9160248082019260009290919082900301818387803b158015610dd757600080fd5b505af1158015610deb573d6000803e3d6000fd5b50505050505b6040805184815290517f3289490aa1b0ec56454cbd5d18bd6b8d79609982b2abe74eee579eb6f67581919181900360200190a1505050565b6001600160a01b038116610e84576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b80610581576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b600082610ee757506000610f34565b82820282848281610ef457fe5b0414610f315760405162461bcd60e51b81526004018080602001828103825260218152602001806110ff6021913960400191505060405180910390fd5b90505b92915050565b6000610f3183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610fbe565b6000610f3183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611060565b6000818361104a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561100f578181015183820152602001610ff7565b50505050905090810190601f16801561103c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161105657fe5b0495945050505050565b600081848411156110b25760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561100f578181015183820152602001610ff7565b50505090039056fe4f776e61626c653a3a7365744f776e65723a20696e76616c696420616464726573734665654469737472696275746f723a2073656e64696e6720455448206661696c6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774665654469737472696275746f723a2063616c6c6572206973206e6f7420416374697665506f6f6ca264697066735822122068cbf3a893e2b9713149ddceb6b3570b9d11482f5f07b3b3066ad70f4eec87e264736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x6e825a3569D46510c0f707eb625e456679dff721" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/FeeDistributor_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/FeeDistributor_Proxy.json new file mode 100644 index 00000000..2fbfc6a6 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/FeeDistributor_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0x1261d5872d56e2Ab61B3C68451D015b752105027", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/hintHelpers.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/HintHelpers.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/hintHelpers.json rename to packages/contracts/deployment/deployments/rskSovrynMainnet/HintHelpers.json index 75cac69d..ac7e89ca 100644 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/hintHelpers.json +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/HintHelpers.json @@ -1,4 +1,5 @@ { + "address": "0x1D7DaC5a63A35540bE9e031212ecf39584AE5595", "_format": "hh-sol-artifact-1", "contractName": "HintHelpers", "sourceName": "contracts/HintHelpers.sol", @@ -401,6 +402,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806116d46022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6115b58061011f6000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c8063795d26c3116100ad5780639f070670116100715780639f070670146102b2578063a20baee614610251578063a3f4df7e146102ba578063ae91875414610337578063c394a7fa1461033f5761012c565b8063795d26c3146102695780637b41bdbe146102715780637f7dde4a1461029a578063887105d3146102a2578063893d20e8146102aa5761012c565b80633d83908a116100f45780633d83908a14610220578063525acdbb1461022857806372fe25aa14610251578063741bef1a14610259578063759b3034146102615761012c565b806313144dba1461013157806313af4035146101825780631bf43555146101aa578063363bf964146101c45780633cc74225146101fc575b600080fd5b61015a6004803603606081101561014757600080fd5b5080359060208101359060400135610362565b604080516001600160a01b039094168452602084019290925282820152519081900360600190f35b6101a86004803603602081101561019857600080fd5b50356001600160a01b0316610951565b005b6101b26109c4565b60408051918252519081900360200190f35b6101a8600480360360608110156101da57600080fd5b506001600160a01b0381358116916020810135821691604090910135166109d1565b610204610b05565b604080516001600160a01b039092168252519081900360200190f35b610204610b14565b6101b26004803603606081101561023e57600080fd5b5080359060208101359060400135610b23565b6101b2610b3a565b610204610b46565b6101b2610b55565b6101b2610b62565b61015a6004803603606081101561028757600080fd5b5080359060208101359060400135610c61565b610204610f72565b6101b2610f81565b61020461103d565b610204611067565b6102c2611076565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102fc5781810151838201526020016102e4565b50505050905090810190601f1680156103295780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61020461109d565b6101b26004803603604081101561035557600080fd5b50803590602001356110ac565b6004805460408051634d62283160e01b81529051600093849384936001600160a01b0390911692899285928592634d62283192828101926020929190829003018186803b1580156103b257600080fd5b505afa1580156103c6573d6000803e3d6000fd5b505050506040513d60208110156103dc57600080fd5b505190505b6001600160a01b038116158015906104f05750600360009054906101000a90046001600160a01b03166001600160a01b031663794e57246040518163ffffffff1660e01b815260040160206040518083038186803b15801561044257600080fd5b505afa158015610456573d6000803e3d6000fd5b505050506040513d602081101561046c57600080fd5b505160055460408051630d293c7160e41b81526001600160a01b038581166004830152602482018d90529151919092169163d293c710916044808301926020929190829003018186803b1580156104c257600080fd5b505afa1580156104d6573d6000803e3d6000fd5b505050506040513d60208110156104ec57600080fd5b5051105b1561057e57826001600160a01b031663b72703ac826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561054b57600080fd5b505afa15801561055f573d6000803e3d6000fd5b505050506040513d602081101561057557600080fd5b505190506103e1565b9450848661058c5760001996505b6001600160a01b038116158015906105a45750600082115b80156105b4575060001987019615155b1561093357600554604080516317c62b1760e01b81526001600160a01b03848116600483015291516000936106c59316916317c62b17916024808301926020929190829003018186803b15801561060a57600080fd5b505afa15801561061e573d6000803e3d6000fd5b505050506040513d602081101561063457600080fd5b50516005546040805163d66a255360e01b81526001600160a01b03878116600483015291516106b993929092169163d66a255391602480820192602092909190829003018186803b15801561068857600080fd5b505afa15801561069c573d6000803e3d6000fd5b505050506040513d60208110156106b257600080fd5b50516110c1565b9063ffffffff6110dc16565b905082811115610896576809c2007651b2500000811115610890576000610704846106ff846809c2007651b250000063ffffffff61113616565b611178565b60055460408051635d8c960960e01b81526001600160a01b038781166004830152915193945060009361080d939290921691635d8c960991602480820192602092909190829003018186803b15801561075c57600080fd5b505afa158015610770573d6000803e3d6000fd5b505050506040513d602081101561078657600080fd5b5051600554604080516309019aaf60e31b81526001600160a01b0389811660048301529151919092169163480cd578916024808301926020929190829003018186803b1580156107d557600080fd5b505afa1580156107e9573d6000803e3d6000fd5b505050506040513d60208110156107ff57600080fd5b50519063ffffffff6110dc16565b9050600061084961083c8d61083086670de0b6b3a764000063ffffffff61118e16565b9063ffffffff6111e716565b839063ffffffff61113616565b9050600061085d858563ffffffff61113616565b9050600061086a82611229565b90506108768382611244565b9a50610888888663ffffffff61113616565b975050505050505b50610933565b6108a6838263ffffffff61113616565b9250836001600160a01b031663b72703ac836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156108fe57600080fd5b505afa158015610912573d6000803e3d6000fd5b505050506040513d602081101561092857600080fd5b5051915061058c9050565b610943898363ffffffff61113616565b935050505093509350939050565b61095961103d565b6001600160a01b0316336001600160a01b0316146109b8576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6109c181611279565b50565b6809c2007651b250000081565b6109d961103d565b6001600160a01b0316336001600160a01b031614610a38576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b610a418361132e565b610a4a8261132e565b610a538161132e565b600380546001600160a01b038086166001600160a01b031992831617909255600480548584169083168117909155600580549385169390921692909217905560408051918252517f65f4cf077bc01e4742eb5ad98326f6e95b63548ea24b17f8d5e823111fe788009181900360200190a1604080516001600160a01b038316815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1505050565b6001546001600160a01b031681565b6005546001600160a01b031681565b6000610b308484846113e1565b90505b9392505050565b670de0b6b3a764000081565b6002546001600160a01b031681565b6801158e460913d0000081565b60008054604080516272c7d360e71b8152905183926001600160a01b031691633963e980916004808301926020929190829003018186803b158015610ba657600080fd5b505afa158015610bba573d6000803e3d6000fd5b505050506040513d6020811015610bd057600080fd5b5051600154604080516272c7d360e71b815290519293506000926001600160a01b0390921691633963e98091600480820192602092909190829003018186803b158015610c1c57600080fd5b505afa158015610c30573d6000803e3d6000fd5b505050506040513d6020811015610c4657600080fd5b50519050610c5a828263ffffffff6110dc16565b9250505090565b600080600080600560009054906101000a90046001600160a01b03166001600160a01b03166349eefeee6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cb557600080fd5b505afa158015610cc9573d6000803e3d6000fd5b505050506040513d6020811015610cdf57600080fd5b5051905080610cf8575060009250829150839050610f69565b6004805460408051634d62283160e01b815290516001600160a01b0390921692634d622831928282019260209290829003018186803b158015610d3a57600080fd5b505afa158015610d4e573d6000803e3d6000fd5b505050506040513d6020811015610d6457600080fd5b50516005546040805163b0d8e18160e01b81526001600160a01b0380851660048301529151939750610dee938b93929092169163b0d8e18191602480820192602092909190829003018186803b158015610dbd57600080fd5b505afa158015610dd1573d6000803e3d6000fd5b505050506040513d6020811015610de757600080fd5b5051611411565b925084915060015b86811015610f6657604080516020808201959095528151808203860181529082019091528051930192909220916000828481610e2e57fe5b0690506000600560009054906101000a90046001600160a01b03166001600160a01b031663d9a72444836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610e8c57600080fd5b505afa158015610ea0573d6000803e3d6000fd5b505050506040513d6020811015610eb657600080fd5b50516005546040805163b0d8e18160e01b81526001600160a01b0380851660048301529151939450600093919092169163b0d8e181916024808301926020929190829003018186803b158015610f0b57600080fd5b505afa158015610f1f573d6000803e3d6000fd5b505050506040513d6020811015610f3557600080fd5b505190506000610f45828d611411565b905087811015610f56578097508298505b505060019092019150610df69050565b50505b93509350939050565b6000546001600160a01b031681565b6000805460408051630a7b61df60e11b8152905183926001600160a01b0316916314f6c3be916004808301926020929190829003018186803b158015610fc657600080fd5b505afa158015610fda573d6000803e3d6000fd5b505050506040513d6020811015610ff057600080fd5b505160015460408051630a7b61df60e11b815290519293506000926001600160a01b03909216916314f6c3be91600480820192602092909190829003018186803b158015610c1c57600080fd5b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6003546001600160a01b031681565b6040518060400160405280600b81526020016a48696e7448656c7065727360a81b81525081565b6004546001600160a01b031681565b60006110b88383611244565b90505b92915050565b60006110bb826801158e460913d0000063ffffffff61113616565b6000828201838110156110b8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006110b883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611440565b600081831061118757816110b8565b5090919050565b60008261119d575060006110bb565b828202828482816111aa57fe5b04146110b85760405162461bcd60e51b815260040180806020018281038252602181526020018061155f6021913960400191505060405180910390fd5b60006110b883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506114d7565b60006110bb826801158e460913d0000063ffffffff6110dc16565b6000811561127057611269826108308568056bc75e2d6310000063ffffffff61118e16565b90506110bb565b506000196110bb565b6001600160a01b0381166112be5760405162461bcd60e51b815260040180806020018281038252602281526020018061153d6022913960400191505060405180910390fd5b806001600160a01b03166112d061103d565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b038116611389576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806113dd576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b600082156114085760006113ff84610830878663ffffffff61118e16565b9150610b339050565b50600019610b33565b6000818310156114305761142b828463ffffffff61113616565b6110b8565b6110b8838363ffffffff61113616565b600081848411156114cf5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561149457818101518382015260200161147c565b50505050905090810190601f1680156114c15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836115265760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561149457818101518382015260200161147c565b50600083858161153257fe5b049594505050505056fe4f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220b45699dc70b63074cc3f4814bee259edea28c29802a6fd53970398c4e3e6509564736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061012c5760003560e01c8063795d26c3116100ad5780639f070670116100715780639f070670146102b2578063a20baee614610251578063a3f4df7e146102ba578063ae91875414610337578063c394a7fa1461033f5761012c565b8063795d26c3146102695780637b41bdbe146102715780637f7dde4a1461029a578063887105d3146102a2578063893d20e8146102aa5761012c565b80633d83908a116100f45780633d83908a14610220578063525acdbb1461022857806372fe25aa14610251578063741bef1a14610259578063759b3034146102615761012c565b806313144dba1461013157806313af4035146101825780631bf43555146101aa578063363bf964146101c45780633cc74225146101fc575b600080fd5b61015a6004803603606081101561014757600080fd5b5080359060208101359060400135610362565b604080516001600160a01b039094168452602084019290925282820152519081900360600190f35b6101a86004803603602081101561019857600080fd5b50356001600160a01b0316610951565b005b6101b26109c4565b60408051918252519081900360200190f35b6101a8600480360360608110156101da57600080fd5b506001600160a01b0381358116916020810135821691604090910135166109d1565b610204610b05565b604080516001600160a01b039092168252519081900360200190f35b610204610b14565b6101b26004803603606081101561023e57600080fd5b5080359060208101359060400135610b23565b6101b2610b3a565b610204610b46565b6101b2610b55565b6101b2610b62565b61015a6004803603606081101561028757600080fd5b5080359060208101359060400135610c61565b610204610f72565b6101b2610f81565b61020461103d565b610204611067565b6102c2611076565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102fc5781810151838201526020016102e4565b50505050905090810190601f1680156103295780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61020461109d565b6101b26004803603604081101561035557600080fd5b50803590602001356110ac565b6004805460408051634d62283160e01b81529051600093849384936001600160a01b0390911692899285928592634d62283192828101926020929190829003018186803b1580156103b257600080fd5b505afa1580156103c6573d6000803e3d6000fd5b505050506040513d60208110156103dc57600080fd5b505190505b6001600160a01b038116158015906104f05750600360009054906101000a90046001600160a01b03166001600160a01b031663794e57246040518163ffffffff1660e01b815260040160206040518083038186803b15801561044257600080fd5b505afa158015610456573d6000803e3d6000fd5b505050506040513d602081101561046c57600080fd5b505160055460408051630d293c7160e41b81526001600160a01b038581166004830152602482018d90529151919092169163d293c710916044808301926020929190829003018186803b1580156104c257600080fd5b505afa1580156104d6573d6000803e3d6000fd5b505050506040513d60208110156104ec57600080fd5b5051105b1561057e57826001600160a01b031663b72703ac826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561054b57600080fd5b505afa15801561055f573d6000803e3d6000fd5b505050506040513d602081101561057557600080fd5b505190506103e1565b9450848661058c5760001996505b6001600160a01b038116158015906105a45750600082115b80156105b4575060001987019615155b1561093357600554604080516317c62b1760e01b81526001600160a01b03848116600483015291516000936106c59316916317c62b17916024808301926020929190829003018186803b15801561060a57600080fd5b505afa15801561061e573d6000803e3d6000fd5b505050506040513d602081101561063457600080fd5b50516005546040805163d66a255360e01b81526001600160a01b03878116600483015291516106b993929092169163d66a255391602480820192602092909190829003018186803b15801561068857600080fd5b505afa15801561069c573d6000803e3d6000fd5b505050506040513d60208110156106b257600080fd5b50516110c1565b9063ffffffff6110dc16565b905082811115610896576809c2007651b2500000811115610890576000610704846106ff846809c2007651b250000063ffffffff61113616565b611178565b60055460408051635d8c960960e01b81526001600160a01b038781166004830152915193945060009361080d939290921691635d8c960991602480820192602092909190829003018186803b15801561075c57600080fd5b505afa158015610770573d6000803e3d6000fd5b505050506040513d602081101561078657600080fd5b5051600554604080516309019aaf60e31b81526001600160a01b0389811660048301529151919092169163480cd578916024808301926020929190829003018186803b1580156107d557600080fd5b505afa1580156107e9573d6000803e3d6000fd5b505050506040513d60208110156107ff57600080fd5b50519063ffffffff6110dc16565b9050600061084961083c8d61083086670de0b6b3a764000063ffffffff61118e16565b9063ffffffff6111e716565b839063ffffffff61113616565b9050600061085d858563ffffffff61113616565b9050600061086a82611229565b90506108768382611244565b9a50610888888663ffffffff61113616565b975050505050505b50610933565b6108a6838263ffffffff61113616565b9250836001600160a01b031663b72703ac836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156108fe57600080fd5b505afa158015610912573d6000803e3d6000fd5b505050506040513d602081101561092857600080fd5b5051915061058c9050565b610943898363ffffffff61113616565b935050505093509350939050565b61095961103d565b6001600160a01b0316336001600160a01b0316146109b8576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6109c181611279565b50565b6809c2007651b250000081565b6109d961103d565b6001600160a01b0316336001600160a01b031614610a38576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b610a418361132e565b610a4a8261132e565b610a538161132e565b600380546001600160a01b038086166001600160a01b031992831617909255600480548584169083168117909155600580549385169390921692909217905560408051918252517f65f4cf077bc01e4742eb5ad98326f6e95b63548ea24b17f8d5e823111fe788009181900360200190a1604080516001600160a01b038316815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1505050565b6001546001600160a01b031681565b6005546001600160a01b031681565b6000610b308484846113e1565b90505b9392505050565b670de0b6b3a764000081565b6002546001600160a01b031681565b6801158e460913d0000081565b60008054604080516272c7d360e71b8152905183926001600160a01b031691633963e980916004808301926020929190829003018186803b158015610ba657600080fd5b505afa158015610bba573d6000803e3d6000fd5b505050506040513d6020811015610bd057600080fd5b5051600154604080516272c7d360e71b815290519293506000926001600160a01b0390921691633963e98091600480820192602092909190829003018186803b158015610c1c57600080fd5b505afa158015610c30573d6000803e3d6000fd5b505050506040513d6020811015610c4657600080fd5b50519050610c5a828263ffffffff6110dc16565b9250505090565b600080600080600560009054906101000a90046001600160a01b03166001600160a01b03166349eefeee6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cb557600080fd5b505afa158015610cc9573d6000803e3d6000fd5b505050506040513d6020811015610cdf57600080fd5b5051905080610cf8575060009250829150839050610f69565b6004805460408051634d62283160e01b815290516001600160a01b0390921692634d622831928282019260209290829003018186803b158015610d3a57600080fd5b505afa158015610d4e573d6000803e3d6000fd5b505050506040513d6020811015610d6457600080fd5b50516005546040805163b0d8e18160e01b81526001600160a01b0380851660048301529151939750610dee938b93929092169163b0d8e18191602480820192602092909190829003018186803b158015610dbd57600080fd5b505afa158015610dd1573d6000803e3d6000fd5b505050506040513d6020811015610de757600080fd5b5051611411565b925084915060015b86811015610f6657604080516020808201959095528151808203860181529082019091528051930192909220916000828481610e2e57fe5b0690506000600560009054906101000a90046001600160a01b03166001600160a01b031663d9a72444836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610e8c57600080fd5b505afa158015610ea0573d6000803e3d6000fd5b505050506040513d6020811015610eb657600080fd5b50516005546040805163b0d8e18160e01b81526001600160a01b0380851660048301529151939450600093919092169163b0d8e181916024808301926020929190829003018186803b158015610f0b57600080fd5b505afa158015610f1f573d6000803e3d6000fd5b505050506040513d6020811015610f3557600080fd5b505190506000610f45828d611411565b905087811015610f56578097508298505b505060019092019150610df69050565b50505b93509350939050565b6000546001600160a01b031681565b6000805460408051630a7b61df60e11b8152905183926001600160a01b0316916314f6c3be916004808301926020929190829003018186803b158015610fc657600080fd5b505afa158015610fda573d6000803e3d6000fd5b505050506040513d6020811015610ff057600080fd5b505160015460408051630a7b61df60e11b815290519293506000926001600160a01b03909216916314f6c3be91600480820192602092909190829003018186803b158015610c1c57600080fd5b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6003546001600160a01b031681565b6040518060400160405280600b81526020016a48696e7448656c7065727360a81b81525081565b6004546001600160a01b031681565b60006110b88383611244565b90505b92915050565b60006110bb826801158e460913d0000063ffffffff61113616565b6000828201838110156110b8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006110b883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611440565b600081831061118757816110b8565b5090919050565b60008261119d575060006110bb565b828202828482816111aa57fe5b04146110b85760405162461bcd60e51b815260040180806020018281038252602181526020018061155f6021913960400191505060405180910390fd5b60006110b883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506114d7565b60006110bb826801158e460913d0000063ffffffff6110dc16565b6000811561127057611269826108308568056bc75e2d6310000063ffffffff61118e16565b90506110bb565b506000196110bb565b6001600160a01b0381166112be5760405162461bcd60e51b815260040180806020018281038252602281526020018061153d6022913960400191505060405180910390fd5b806001600160a01b03166112d061103d565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b038116611389576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806113dd576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b600082156114085760006113ff84610830878663ffffffff61118e16565b9150610b339050565b50600019610b33565b6000818310156114305761142b828463ffffffff61113616565b6110b8565b6110b8838363ffffffff61113616565b600081848411156114cf5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561149457818101518382015260200161147c565b50505050905090810190601f1680156114c15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836115265760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561149457818101518382015260200161147c565b50600083858161153257fe5b049594505050505056fe4f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220b45699dc70b63074cc3f4814bee259edea28c29802a6fd53970398c4e3e6509564736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0xc7Bf159d6259ce5a4Fbdd0e3d060875F76605Dba" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/HintHelpers_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/HintHelpers_Proxy.json new file mode 100644 index 00000000..d9cd43ef --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/HintHelpers_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0x1D7DaC5a63A35540bE9e031212ecf39584AE5595", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/multiTroveGetter.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/MultiTroveGetter.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/multiTroveGetter.json rename to packages/contracts/deployment/deployments/rskSovrynMainnet/MultiTroveGetter.json index 8226c186..125a93f9 100644 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/multiTroveGetter.json +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/MultiTroveGetter.json @@ -1,4 +1,5 @@ { + "address": "0xF265a169191348c02829B62650B025BdeAf00AE4", "_format": "hh-sol-artifact-1", "contractName": "MultiTroveGetter", "sourceName": "contracts/MultiTroveGetter.sol", @@ -152,6 +153,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610143565b6001600160a01b0381166100575760405162461bcd60e51b815260040161004e90610101565b60405180910390fd5b6001600160a01b0381166100726001600160e01b036100c516565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360006040516100b5906100e4565b6040519081900390209190915550565b6000806040516100d4906100e4565b6040519081900390205492915050565b7035b2bc9737bbb730b136329737bbb732b960791b815260110190565b60208082526022908201527f4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265604082015261737360f01b606082015260800190565b610dc7806101526000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c806313af4035146100675780633d83908a1461007c578063893d20e81461009a57806390107afe146100a2578063ae918754146100b5578063b90bce45146100bd575b600080fd5b61007a610075366004610b20565b6100dd565b005b61008461012a565b6040516100919190610c74565b60405180910390f35b610084610139565b61007a6100b0366004610b5f565b610158565b6100846101be565b6100d06100cb366004610b97565b6101cd565b6040516100919190610c88565b6100e5610139565b6001600160a01b0316336001600160a01b03161461011e5760405162461bcd60e51b815260040161011590610d4b565b60405180910390fd5b610127816102f0565b50565b6000546001600160a01b031681565b60008060405161014890610c57565b6040519081900390205492915050565b610160610139565b6001600160a01b0316336001600160a01b0316146101905760405162461bcd60e51b815260040161011590610d4b565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6001546001600160a01b031681565b6060600080600085126101e5575083905060016101f3565b846001016000039150600090505b6001546040805163de8fa43160e01b815290516000926001600160a01b03169163de8fa431916004808301926020929190829003018186803b15801561023857600080fd5b505afa15801561024c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102709190610bb8565b90508083106102b25760408051600080825260208201909252906102aa565b610297610ae1565b81526020019060019003908161028f5790505b5093506102e7565b828103808611156102c1578095505b82156102d8576102d1848761037b565b94506102e5565b6102e28487610732565b94505b505b50505092915050565b6001600160a01b0381166103165760405162461bcd60e51b815260040161011590610d09565b806001600160a01b0316610328610139565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600060405161036b90610c57565b6040519081900390209190915550565b60606000600160009054906101000a90046001600160a01b03166001600160a01b0316631e2231436040518163ffffffff1660e01b815260040160206040518083038186803b1580156103cd57600080fd5b505afa1580156103e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104059190610b43565b905060005b8481101561049c5760015460405163765e015960e01b81526001600160a01b039091169063765e015990610442908590600401610c74565b60206040518083038186803b15801561045a57600080fd5b505afa15801561046e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104929190610b43565b915060010161040a565b508267ffffffffffffffff811180156104b457600080fd5b506040519080825280602002602001820160405280156104ee57816020015b6104db610ae1565b8152602001906001900390816104d35790505b50915060005b8381101561072a578183828151811061050957fe5b60209081029190910101516001600160a01b039182169052600054604051630ddec86760e31b8152911690636ef6433890610548908590600401610c74565b60a06040518083038186803b15801561056057600080fd5b505afa158015610574573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105989190610bf3565b9050508584815181106105a757fe5b60200260200101516020018685815181106105be57fe5b60200260200101516040018786815181106105d557fe5b60209081029190910101516060019290925291905252600054604051630b39e3cd60e11b81526001600160a01b0390911690631673c79a9061061b908590600401610c74565b604080518083038186803b15801561063257600080fd5b505afa158015610646573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066a9190610bd0565b84838151811061067657fe5b602002602001015160800185848151811061068d57fe5b602090810291909101015160a001919091525260015460405163765e015960e01b81526001600160a01b039091169063765e0159906106d0908590600401610c74565b60206040518083038186803b1580156106e857600080fd5b505afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190610b43565b91506001016104f4565b505092915050565b60606000600160009054906101000a90046001600160a01b03166001600160a01b0316634d6228316040518163ffffffff1660e01b815260040160206040518083038186803b15801561078457600080fd5b505afa158015610798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107bc9190610b43565b905060005b8481101561085357600154604051632dc9c0eb60e21b81526001600160a01b039091169063b72703ac906107f9908590600401610c74565b60206040518083038186803b15801561081157600080fd5b505afa158015610825573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108499190610b43565b91506001016107c1565b508267ffffffffffffffff8111801561086b57600080fd5b506040519080825280602002602001820160405280156108a557816020015b610892610ae1565b81526020019060019003908161088a5790505b50915060005b8381101561072a57818382815181106108c057fe5b60209081029190910101516001600160a01b039182169052600054604051630ddec86760e31b8152911690636ef64338906108ff908590600401610c74565b60a06040518083038186803b15801561091757600080fd5b505afa15801561092b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094f9190610bf3565b90505085848151811061095e57fe5b602002602001015160200186858151811061097557fe5b602002602001015160400187868151811061098c57fe5b60209081029190910101516060019290925291905252600054604051630b39e3cd60e11b81526001600160a01b0390911690631673c79a906109d2908590600401610c74565b604080518083038186803b1580156109e957600080fd5b505afa1580156109fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a219190610bd0565b848381518110610a2d57fe5b6020026020010151608001858481518110610a4457fe5b602090810291909101015160a0019190915252600154604051632dc9c0eb60e21b81526001600160a01b039091169063b72703ac90610a87908590600401610c74565b60206040518083038186803b158015610a9f57600080fd5b505afa158015610ab3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad79190610b43565b91506001016108ab565b6040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b600060208284031215610b31578081fd5b8135610b3c81610d7c565b9392505050565b600060208284031215610b54578081fd5b8151610b3c81610d7c565b60008060408385031215610b71578081fd5b8235610b7c81610d7c565b91506020830135610b8c81610d7c565b809150509250929050565b60008060408385031215610ba9578182fd5b50508035926020909101359150565b600060208284031215610bc9578081fd5b5051919050565b60008060408385031215610be2578182fd5b505080516020909101519092909150565b600080600080600060a08688031215610c0a578081fd5b855194506020860151935060408601519250606086015160058110610c2d578182fd5b60808701519092506001600160801b0381168114610c49578182fd5b809150509295509295909350565b7035b2bc9737bbb730b136329737bbb732b960791b815260110190565b6001600160a01b0391909116815260200190565b602080825282518282018190526000919060409081850190868401855b82811015610cfc57815180516001600160a01b0316855286810151878601528581015186860152606080820151908601526080808201519086015260a0908101519085015260c09093019290850190600101610ca5565b5091979650505050505050565b60208082526022908201527f4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265604082015261737360f01b606082015260800190565b60208082526017908201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604082015260600190565b6001600160a01b038116811461012757600080fdfea2646970667358221220659f4dc0a25b28f8b8a559e447b60b3ff6f5f3d8084d3627ee2f90efdfe1a25864736f6c634300060b0033", "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100625760003560e01c806313af4035146100675780633d83908a1461007c578063893d20e81461009a57806390107afe146100a2578063ae918754146100b5578063b90bce45146100bd575b600080fd5b61007a610075366004610b20565b6100dd565b005b61008461012a565b6040516100919190610c74565b60405180910390f35b610084610139565b61007a6100b0366004610b5f565b610158565b6100846101be565b6100d06100cb366004610b97565b6101cd565b6040516100919190610c88565b6100e5610139565b6001600160a01b0316336001600160a01b03161461011e5760405162461bcd60e51b815260040161011590610d4b565b60405180910390fd5b610127816102f0565b50565b6000546001600160a01b031681565b60008060405161014890610c57565b6040519081900390205492915050565b610160610139565b6001600160a01b0316336001600160a01b0316146101905760405162461bcd60e51b815260040161011590610d4b565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6001546001600160a01b031681565b6060600080600085126101e5575083905060016101f3565b846001016000039150600090505b6001546040805163de8fa43160e01b815290516000926001600160a01b03169163de8fa431916004808301926020929190829003018186803b15801561023857600080fd5b505afa15801561024c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102709190610bb8565b90508083106102b25760408051600080825260208201909252906102aa565b610297610ae1565b81526020019060019003908161028f5790505b5093506102e7565b828103808611156102c1578095505b82156102d8576102d1848761037b565b94506102e5565b6102e28487610732565b94505b505b50505092915050565b6001600160a01b0381166103165760405162461bcd60e51b815260040161011590610d09565b806001600160a01b0316610328610139565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600060405161036b90610c57565b6040519081900390209190915550565b60606000600160009054906101000a90046001600160a01b03166001600160a01b0316631e2231436040518163ffffffff1660e01b815260040160206040518083038186803b1580156103cd57600080fd5b505afa1580156103e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104059190610b43565b905060005b8481101561049c5760015460405163765e015960e01b81526001600160a01b039091169063765e015990610442908590600401610c74565b60206040518083038186803b15801561045a57600080fd5b505afa15801561046e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104929190610b43565b915060010161040a565b508267ffffffffffffffff811180156104b457600080fd5b506040519080825280602002602001820160405280156104ee57816020015b6104db610ae1565b8152602001906001900390816104d35790505b50915060005b8381101561072a578183828151811061050957fe5b60209081029190910101516001600160a01b039182169052600054604051630ddec86760e31b8152911690636ef6433890610548908590600401610c74565b60a06040518083038186803b15801561056057600080fd5b505afa158015610574573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105989190610bf3565b9050508584815181106105a757fe5b60200260200101516020018685815181106105be57fe5b60200260200101516040018786815181106105d557fe5b60209081029190910101516060019290925291905252600054604051630b39e3cd60e11b81526001600160a01b0390911690631673c79a9061061b908590600401610c74565b604080518083038186803b15801561063257600080fd5b505afa158015610646573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066a9190610bd0565b84838151811061067657fe5b602002602001015160800185848151811061068d57fe5b602090810291909101015160a001919091525260015460405163765e015960e01b81526001600160a01b039091169063765e0159906106d0908590600401610c74565b60206040518083038186803b1580156106e857600080fd5b505afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190610b43565b91506001016104f4565b505092915050565b60606000600160009054906101000a90046001600160a01b03166001600160a01b0316634d6228316040518163ffffffff1660e01b815260040160206040518083038186803b15801561078457600080fd5b505afa158015610798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107bc9190610b43565b905060005b8481101561085357600154604051632dc9c0eb60e21b81526001600160a01b039091169063b72703ac906107f9908590600401610c74565b60206040518083038186803b15801561081157600080fd5b505afa158015610825573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108499190610b43565b91506001016107c1565b508267ffffffffffffffff8111801561086b57600080fd5b506040519080825280602002602001820160405280156108a557816020015b610892610ae1565b81526020019060019003908161088a5790505b50915060005b8381101561072a57818382815181106108c057fe5b60209081029190910101516001600160a01b039182169052600054604051630ddec86760e31b8152911690636ef64338906108ff908590600401610c74565b60a06040518083038186803b15801561091757600080fd5b505afa15801561092b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094f9190610bf3565b90505085848151811061095e57fe5b602002602001015160200186858151811061097557fe5b602002602001015160400187868151811061098c57fe5b60209081029190910101516060019290925291905252600054604051630b39e3cd60e11b81526001600160a01b0390911690631673c79a906109d2908590600401610c74565b604080518083038186803b1580156109e957600080fd5b505afa1580156109fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a219190610bd0565b848381518110610a2d57fe5b6020026020010151608001858481518110610a4457fe5b602090810291909101015160a0019190915252600154604051632dc9c0eb60e21b81526001600160a01b039091169063b72703ac90610a87908590600401610c74565b60206040518083038186803b158015610a9f57600080fd5b505afa158015610ab3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad79190610b43565b91506001016108ab565b6040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b600060208284031215610b31578081fd5b8135610b3c81610d7c565b9392505050565b600060208284031215610b54578081fd5b8151610b3c81610d7c565b60008060408385031215610b71578081fd5b8235610b7c81610d7c565b91506020830135610b8c81610d7c565b809150509250929050565b60008060408385031215610ba9578182fd5b50508035926020909101359150565b600060208284031215610bc9578081fd5b5051919050565b60008060408385031215610be2578182fd5b505080516020909101519092909150565b600080600080600060a08688031215610c0a578081fd5b855194506020860151935060408601519250606086015160058110610c2d578182fd5b60808701519092506001600160801b0381168114610c49578182fd5b809150509295509295909350565b7035b2bc9737bbb730b136329737bbb732b960791b815260110190565b6001600160a01b0391909116815260200190565b602080825282518282018190526000919060409081850190868401855b82811015610cfc57815180516001600160a01b0316855286810151878601528581015186860152606080820151908601526080808201519086015260a0908101519085015260c09093019290850190600101610ca5565b5091979650505050505050565b60208082526022908201527f4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265604082015261737360f01b606082015260800190565b60208082526017908201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604082015260600190565b6001600160a01b038116811461012757600080fdfea2646970667358221220659f4dc0a25b28f8b8a559e447b60b3ff6f5f3d8084d3627ee2f90efdfe1a25864736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x3adF6FAe3C494F0CF151abA537E60fCCbAC0e0a0" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/MultiTroveGetter_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/MultiTroveGetter_Proxy.json new file mode 100644 index 00000000..fe827f81 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/MultiTroveGetter_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0xF265a169191348c02829B62650B025BdeAf00AE4", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/priceFeed.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/PriceFeed.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynMainnet/priceFeed.json rename to packages/contracts/deployment/deployments/rskSovrynMainnet/PriceFeed.json index 50806acc..2b237d14 100644 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/priceFeed.json +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/PriceFeed.json @@ -1,4 +1,5 @@ { + "address": "0x6D1d9574d67e04cf35Fa1d916F763eDDae03b75d", "_format": "hh-sol-artifact-1", "contractName": "PriceFeed", "sourceName": "contracts/PriceFeed.sol", @@ -184,6 +185,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806109936022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6108748061011f6000396000f3fe608060405234801561001057600080fd5b506004361061006d5760003560e01c80630490be83146100725780630589c4e51461008c5780630fdb11cf146100bb57806313af4035146100c3578063893d20e8146100eb57806390107afe1461010f578063a3f4df7e1461013d575b600080fd5b61007a6101ba565b60408051918252519081900360200190f35b61007a600480360360408110156100a257600080fd5b50803560ff1690602001356001600160a01b03166101c0565b61007a6103b9565b6100e9600480360360208110156100d957600080fd5b50356001600160a01b03166104d9565b005b6100f361054c565b604080516001600160a01b039092168252519081900360200190f35b6100e96004803603604081101561012557600080fd5b506001600160a01b0381358116916020013516610576565b610145610606565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561017f578181015183820152602001610167565b50505050905090810190601f1680156101ac5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60025481565b60006101ca61054c565b6001600160a01b0316336001600160a01b031614610229576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b60028360ff161061026b5760405162461bcd60e51b81526004018080602001828103825260298152602001806107cf6029913960400191505060405180910390fd5b6102748261062b565b8160008460ff166002811061028557fe5b0180546001600160a01b0319166001600160a01b03929092169190911790556000808060ff8616600281106102b657fe5b0154604080516350d25bcd60e01b815281516001600160a01b03909316926350d25bcd92600480840193919291829003018186803b1580156102f757600080fd5b505afa15801561030b573d6000803e3d6000fd5b505050506040513d604081101561032157600080fd5b50805160209091015190925090508061036b5760405162461bcd60e51b815260040180806020018281038252602581526020018061081a6025913960400191505060405180910390fd5b6040805160ff871681526001600160a01b038616602082015281517f97f7578becfa7a6013824d8ab1174e8c0522d468cd75e7a7e7fc4bde27338442929181900390910190a1509392505050565b6000805b60028160ff1610156104d05760008060008360ff16600281106103dc57fe5b0154604080516350d25bcd60e01b815281516001600160a01b03909316926350d25bcd92600480840193919291829003018186803b15801561041d57600080fd5b505afa158015610431573d6000803e3d6000fd5b505050506040513d604081101561044757600080fd5b5080516020909101519092509050801561046e57610464826106de565b5091506104d69050565b7f19f3630adb38b0aca2b2ad2b9db00888aef6e2b79bbf683a6c4992500998ea708360008560ff16600281106104a057fe5b01546040805160ff90931683526001600160a01b0390911660208301528051918290030190a150506001016103bd565b50506002545b90565b6104e161054c565b6001600160a01b0316336001600160a01b031614610540576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61054981610719565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b61057e61054c565b6001600160a01b0316336001600160a01b0316146105dd576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b60006105ea6000846101c0565b90506105f76001836101c0565b50610601816106de565b505050565b60405180604001604052806009815260200168141c9a58d95199595960ba1b81525081565b6001600160a01b038116610686576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806106da576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b60028190556040805182815290517f4d29de21de555af78a62fc82dd4bc05e9ae5b0660a37f04729527e0f22780cd39181900360200190a150565b6001600160a01b03811661075e5760405162461bcd60e51b81526004018080602001828103825260228152602001806107f86022913960400191505060405180910390fd5b806001600160a01b031661077061054c565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205556fe4f7574206f6620626f756e6473207768656e2073657474696e672074686520707269636520666565644f776e61626c653a3a7365744f776e65723a20696e76616c696420616464726573735072696365466565643a2050726963652066656564206d75737420626520776f726b696e67a2646970667358221220d75a0e789852c7f8e3e44c3497dbdf447a2e3743166b9f9b0216e249934429d564736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061006d5760003560e01c80630490be83146100725780630589c4e51461008c5780630fdb11cf146100bb57806313af4035146100c3578063893d20e8146100eb57806390107afe1461010f578063a3f4df7e1461013d575b600080fd5b61007a6101ba565b60408051918252519081900360200190f35b61007a600480360360408110156100a257600080fd5b50803560ff1690602001356001600160a01b03166101c0565b61007a6103b9565b6100e9600480360360208110156100d957600080fd5b50356001600160a01b03166104d9565b005b6100f361054c565b604080516001600160a01b039092168252519081900360200190f35b6100e96004803603604081101561012557600080fd5b506001600160a01b0381358116916020013516610576565b610145610606565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561017f578181015183820152602001610167565b50505050905090810190601f1680156101ac5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60025481565b60006101ca61054c565b6001600160a01b0316336001600160a01b031614610229576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b60028360ff161061026b5760405162461bcd60e51b81526004018080602001828103825260298152602001806107cf6029913960400191505060405180910390fd5b6102748261062b565b8160008460ff166002811061028557fe5b0180546001600160a01b0319166001600160a01b03929092169190911790556000808060ff8616600281106102b657fe5b0154604080516350d25bcd60e01b815281516001600160a01b03909316926350d25bcd92600480840193919291829003018186803b1580156102f757600080fd5b505afa15801561030b573d6000803e3d6000fd5b505050506040513d604081101561032157600080fd5b50805160209091015190925090508061036b5760405162461bcd60e51b815260040180806020018281038252602581526020018061081a6025913960400191505060405180910390fd5b6040805160ff871681526001600160a01b038616602082015281517f97f7578becfa7a6013824d8ab1174e8c0522d468cd75e7a7e7fc4bde27338442929181900390910190a1509392505050565b6000805b60028160ff1610156104d05760008060008360ff16600281106103dc57fe5b0154604080516350d25bcd60e01b815281516001600160a01b03909316926350d25bcd92600480840193919291829003018186803b15801561041d57600080fd5b505afa158015610431573d6000803e3d6000fd5b505050506040513d604081101561044757600080fd5b5080516020909101519092509050801561046e57610464826106de565b5091506104d69050565b7f19f3630adb38b0aca2b2ad2b9db00888aef6e2b79bbf683a6c4992500998ea708360008560ff16600281106104a057fe5b01546040805160ff90931683526001600160a01b0390911660208301528051918290030190a150506001016103bd565b50506002545b90565b6104e161054c565b6001600160a01b0316336001600160a01b031614610540576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61054981610719565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b61057e61054c565b6001600160a01b0316336001600160a01b0316146105dd576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b60006105ea6000846101c0565b90506105f76001836101c0565b50610601816106de565b505050565b60405180604001604052806009815260200168141c9a58d95199595960ba1b81525081565b6001600160a01b038116610686576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806106da576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b60028190556040805182815290517f4d29de21de555af78a62fc82dd4bc05e9ae5b0660a37f04729527e0f22780cd39181900360200190a150565b6001600160a01b03811661075e5760405162461bcd60e51b81526004018080602001828103825260228152602001806107f86022913960400191505060405180910390fd5b806001600160a01b031661077061054c565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205556fe4f7574206f6620626f756e6473207768656e2073657474696e672074686520707269636520666565644f776e61626c653a3a7365744f776e65723a20696e76616c696420616464726573735072696365466565643a2050726963652066656564206d75737420626520776f726b696e67a2646970667358221220d75a0e789852c7f8e3e44c3497dbdf447a2e3743166b9f9b0216e249934429d564736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x6D1d9574d67e04cf35Fa1d916F763eDDae03b75d" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/PriceFeed_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/PriceFeed_Proxy.json new file mode 100644 index 00000000..fcaa3744 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/PriceFeed_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0x6D1d9574d67e04cf35Fa1d916F763eDDae03b75d", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/sortedTroves.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/SortedTroves.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynMainnet/sortedTroves.json rename to packages/contracts/deployment/deployments/rskSovrynMainnet/SortedTroves.json index 8f18454e..d8d5ba53 100644 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/sortedTroves.json +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/SortedTroves.json @@ -1,4 +1,5 @@ { + "address": "0xdeEB95480B94f9395514Fe35CAF692A1C788DfE9", "_format": "hh-sol-artifact-1", "contractName": "SortedTroves", "sourceName": "contracts/SortedTroves.sol", @@ -480,6 +481,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b8152600401808060200182810382526022815260200180611b186022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6119f98061011f6000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806363e1d57c116100b8578063a3f4df7e1161007c578063a3f4df7e14610388578063b72703ac14610405578063b7f8cf9b1461042b578063babd3d9a14610433578063de8fa4311461043b578063f376d7981461044357610137565b806363e1d57c146102fe578063681fe70c1461031857806373d4a13a14610320578063765e01591461035a578063893d20e81461038057610137565b80633fce12d5116100ff5780633fce12d5146101f2578063416980dc1461023a57806346f7cf87146102945780634d622831146102d05780635dbe47e8146102d857610137565b806313af40351461013c5780631e2231431461016457806329092d0e146101885780632be21260146101ae5780633d83908a146101ea575b600080fd5b6101626004803603602081101561015257600080fd5b50356001600160a01b0316610477565b005b61016c6104ea565b604080516001600160a01b039092168252519081900360200190f35b6101626004803603602081101561019e57600080fd5b50356001600160a01b03166104f9565b610162600480360360808110156101c457600080fd5b506001600160a01b0381358116916020810135916040820135811691606001351661050a565b61016c6105bf565b6102266004803603606081101561020857600080fd5b508035906001600160a01b03602082013581169160400135166105ce565b604080519115158252519081900360200190f35b61026e6004803603606081101561025057600080fd5b508035906001600160a01b03602082013581169160400135166105f1565b604080516001600160a01b03938416815291909216602082015281519081900390910190f35b610162600480360360808110156102aa57600080fd5b506001600160a01b0381358116916020810135916040820135811691606001351661061b565b61016c610630565b610226600480360360208110156102ee57600080fd5b50356001600160a01b031661063f565b61030661065d565b60408051918252519081900360200190f35b610226610663565b61032861066a565b604080516001600160a01b03958616815293909416602084015282840191909152606082015290519081900360800190f35b61016c6004803603602081101561037057600080fd5b50356001600160a01b0316610689565b61016c6106ac565b6103906106d6565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103ca5781810151838201526020016103b2565b50505050905090810190601f1680156103f75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61016c6004803603602081101561041b57600080fd5b50356001600160a01b03166106fe565b61016c61071f565b61022661072e565b610306610738565b6101626004803603606081101561045957600080fd5b508035906001600160a01b036020820135811691604001351661073e565b61047f6106ac565b6001600160a01b0316336001600160a01b0316146104de576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6104e78161089c565b50565b6002546001600160a01b031690565b610501610951565b6104e78161099c565b6001546001600160a01b031661051f81610bd0565b6105288561063f565b6105635760405162461bcd60e51b815260040180806020018281038252602a8152602001806118da602a913960400191505060405180910390fd5b600084116105a25760405162461bcd60e51b81526004018080602001828103825260238152602001806119a16023913960400191505060405180910390fd5b6105ab8561099c565b6105b88186868686610c2c565b5050505050565b6001546001600160a01b031681565b6001546000906105e9906001600160a01b0316858585610fb0565b949350505050565b600154600090819061060e906001600160a01b0316868686611257565b915091505b935093915050565b6001546001600160a01b03166105ab81610bd0565b6003546001600160a01b031690565b6001600160a01b031660009081526006602052604090205460ff1690565b60045490565b6005541590565b6002546003546004546005546001600160a01b03938416939092169184565b6001600160a01b0390811660009081526006602052604090205461010090041690565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6040518060400160405280600c81526020016b536f7274656454726f76657360a01b81525081565b6001600160a01b039081166000908152600660205260409020600101541690565b6000546001600160a01b031681565b6004546005541490565b60055490565b6107466106ac565b6001600160a01b0316336001600160a01b0316146107a5576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b600083116107e45760405162461bcd60e51b81526004018080602001828103825260228152602001806119046022913960400191505060405180910390fd5b6107ed82611444565b6107f681611444565b6004839055600180546001600160a01b038085166001600160a01b03199283168117909355600080549185169190921617905560408051918252517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038316815290517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1505050565b6001600160a01b0381166108e15760405162461bcd60e51b81526004018080602001828103825260228152602001806119526022913960400191505060405180910390fd5b806001600160a01b03166108f36106ac565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001546001600160a01b0316331461099a5760405162461bcd60e51b815260040180806020018281038252602c815260200180611926602c913960400191505060405180910390fd5b565b6109a58161063f565b6109e05760405162461bcd60e51b815260040180806020018281038252602a8152602001806118da602a913960400191505060405180910390fd5b60055460011015610b26576002546001600160a01b0382811691161415610a4f576001600160a01b03818116600090815260066020526040808220546002805461010090920485166001600160a01b031992831617908190559093168252902060010180549091169055610b21565b6003546001600160a01b0382811691161415610ab6576001600160a01b0380821660009081526006602052604080822060010154600380546001600160a01b03191691851691909117908190559092168152208054610100600160a81b0319169055610b21565b6001600160a01b038082166000908152600660205260408082208054600180830180548716865284862080546101009485900489168502610100600160a81b03199091161790555492549190910485168452919092200180546001600160a01b031916919092161790555b610b43565b600280546001600160a01b03199081169091556003805490911690555b6001600160a01b038116600090815260066020526040902080546001600160a81b0319168155600190810180546001600160a01b0319169055600554610b8e9163ffffffff6114f716565b600555604080516001600160a01b038316815290517fcfc24166db4bb677e857cacabd1541fb2b30645021b27c5130419589b84db52b9181900360200190a150565b6000546001600160a01b0316331480610bf15750336001600160a01b038216145b6104e75760405162461bcd60e51b815260040180806020018281038252602d815260200180611974602d913960400191505060405180910390fd5b610c3461072e565b15610c86576040805162461bcd60e51b815260206004820152601a60248201527f536f7274656454726f7665733a204c6973742069732066756c6c000000000000604482015290519081900360640190fd5b610c8f8461063f565b15610ccb5760405162461bcd60e51b815260040180806020018281038252602c8152602001806118ae602c913960400191505060405180910390fd5b6001600160a01b038416610d26576040805162461bcd60e51b815260206004820152601f60248201527f536f7274656454726f7665733a2049642063616e6e6f74206265207a65726f00604482015290519081900360640190fd5b60008311610d655760405162461bcd60e51b81526004018080602001828103825260238152602001806119a16023913960400191505060405180910390fd5b8181610d7387868484610fb0565b610d8957610d8387868484611257565b90925090505b6001600160a01b038087166000908152600660205260409020805460ff191660011790558216158015610dc357506001600160a01b038116155b15610df857600280546001600160a01b0388166001600160a01b03199182168117909255600380549091169091179055610f4c565b6001600160a01b038216610e6c57600280546001600160a01b03888116600081815260066020526040808220805495851661010002610100600160a81b0319909616959095179094558454909216825291902060010180546001600160a01b03199081168317909155825416179055610f4c565b6001600160a01b038116610edc57600380546001600160a01b0388811660008181526006602052604080822060010180549585166001600160a01b031996871617905585549093168152919091208054610100600160a81b03191661010083021790558254909116179055610f4c565b6001600160a01b038087166000818152600660205260408082208054858716610100818102610100600160a81b031993841617845560019384018054988b166001600160a01b0319998a168117909155865284862080549188029190931617909155835291200180549092161790555b600554610f6090600163ffffffff61154016565b600555604080516001600160a01b03881681526020810187905281517fe02b43adbee0c123de070a04554a71877a0007e2fc161466299cae3c094fe82f929181900390910190a150505050505050565b60006001600160a01b038316158015610fd057506001600160a01b038216155b15610fe457610fdd610663565b90506105e9565b6001600160a01b038316611096576002546001600160a01b038381169116148015610fdd5750846001600160a01b031663b0d8e181836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561106057600080fd5b505afa158015611074573d6000803e3d6000fd5b505050506040513d602081101561108a57600080fd5b505184101590506105e9565b6001600160a01b038216611148576003546001600160a01b038481169116148015610fdd5750846001600160a01b031663b0d8e181846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561111257600080fd5b505afa158015611126573d6000803e3d6000fd5b505050506040513d602081101561113c57600080fd5b505184111590506105e9565b6001600160a01b03838116600090815260066020526040902054610100900481169083161480156111fa575083856001600160a01b031663b0d8e181856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156111cb57600080fd5b505afa1580156111df573d6000803e3d6000fd5b505050506040513d60208110156111f557600080fd5b505110155b8015610fdd5750846001600160a01b031663b0d8e181836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561106057600080fd5b60008083836001600160a01b0382161561130a576112748261063f565b15806113005750876001600160a01b031663b0d8e181836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156112d157600080fd5b505afa1580156112e5573d6000803e3d6000fd5b505050506040513d60208110156112fb57600080fd5b505187115b1561130a57600091505b6001600160a01b038116156113b7576113228161063f565b15806113ae5750876001600160a01b031663b0d8e181826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561137f57600080fd5b505afa158015611393573d6000803e3d6000fd5b505050506040513d60208110156113a957600080fd5b505187105b156113b7575060005b6001600160a01b0382161580156113d557506001600160a01b038116155b156113fe576002546113f390899089906001600160a01b031661159a565b93509350505061143b565b6001600160a01b038216611417576113f38888836116db565b6001600160a01b038116611430576113f388888461159a565b6113f388888461159a565b94509492505050565b6001600160a01b03811661149f576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806114f3576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b600061153983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611816565b9392505050565b600082820183811015611539576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60025460009081906001600160a01b03848116911614801561163d5750846001600160a01b031663b0d8e181846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561160d57600080fd5b505afa158015611621573d6000803e3d6000fd5b505050506040513d602081101561163757600080fd5b50518410155b1561164d57506000905081610613565b6001600160a01b038084166000908152600660205260409020548491610100909104165b6001600160a01b03821615801590611692575061169087878484610fb0565b155b156116cf57506001600160a01b03908116600090815260066020526040808220546101009081900484168084529190922054909291900416611671565b90969095509350505050565b60035460009081906001600160a01b03848116911614801561177e5750846001600160a01b031663b0d8e181846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561174e57600080fd5b505afa158015611762573d6000803e3d6000fd5b505050506040513d602081101561177857600080fd5b50518411155b1561178e57508190506000610613565b6001600160a01b038084166000908152600660205260409020600101548491165b6001600160a01b038216158015906117d057506117ce87878385610fb0565b155b1561180b57506001600160a01b03908116600090815260066020526040808220600190810154841680845291909220909101549091166117af565b969095509350505050565b600081848411156118a55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561186a578181015183820152602001611852565b50505050905090810190601f1680156118975780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe536f7274656454726f7665733a204c69737420616c726561647920636f6e7461696e7320746865206e6f6465536f7274656454726f7665733a204c69737420646f6573206e6f7420636f6e7461696e20746865206964536f7274656454726f7665733a2053697a652063616ee2809974206265207a65726f536f7274656454726f7665733a2043616c6c6572206973206e6f74207468652054726f76654d616e616765724f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373536f7274656454726f7665733a2043616c6c6572206973206e65697468657220424f206e6f722054726f76654d536f7274656454726f7665733a204e494352206d75737420626520706f736974697665a264697066735822122032b466fa1ae0f54c795858e19523f6f623b02846824d1e4a37750d801b21599064736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101375760003560e01c806363e1d57c116100b8578063a3f4df7e1161007c578063a3f4df7e14610388578063b72703ac14610405578063b7f8cf9b1461042b578063babd3d9a14610433578063de8fa4311461043b578063f376d7981461044357610137565b806363e1d57c146102fe578063681fe70c1461031857806373d4a13a14610320578063765e01591461035a578063893d20e81461038057610137565b80633fce12d5116100ff5780633fce12d5146101f2578063416980dc1461023a57806346f7cf87146102945780634d622831146102d05780635dbe47e8146102d857610137565b806313af40351461013c5780631e2231431461016457806329092d0e146101885780632be21260146101ae5780633d83908a146101ea575b600080fd5b6101626004803603602081101561015257600080fd5b50356001600160a01b0316610477565b005b61016c6104ea565b604080516001600160a01b039092168252519081900360200190f35b6101626004803603602081101561019e57600080fd5b50356001600160a01b03166104f9565b610162600480360360808110156101c457600080fd5b506001600160a01b0381358116916020810135916040820135811691606001351661050a565b61016c6105bf565b6102266004803603606081101561020857600080fd5b508035906001600160a01b03602082013581169160400135166105ce565b604080519115158252519081900360200190f35b61026e6004803603606081101561025057600080fd5b508035906001600160a01b03602082013581169160400135166105f1565b604080516001600160a01b03938416815291909216602082015281519081900390910190f35b610162600480360360808110156102aa57600080fd5b506001600160a01b0381358116916020810135916040820135811691606001351661061b565b61016c610630565b610226600480360360208110156102ee57600080fd5b50356001600160a01b031661063f565b61030661065d565b60408051918252519081900360200190f35b610226610663565b61032861066a565b604080516001600160a01b03958616815293909416602084015282840191909152606082015290519081900360800190f35b61016c6004803603602081101561037057600080fd5b50356001600160a01b0316610689565b61016c6106ac565b6103906106d6565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103ca5781810151838201526020016103b2565b50505050905090810190601f1680156103f75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61016c6004803603602081101561041b57600080fd5b50356001600160a01b03166106fe565b61016c61071f565b61022661072e565b610306610738565b6101626004803603606081101561045957600080fd5b508035906001600160a01b036020820135811691604001351661073e565b61047f6106ac565b6001600160a01b0316336001600160a01b0316146104de576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6104e78161089c565b50565b6002546001600160a01b031690565b610501610951565b6104e78161099c565b6001546001600160a01b031661051f81610bd0565b6105288561063f565b6105635760405162461bcd60e51b815260040180806020018281038252602a8152602001806118da602a913960400191505060405180910390fd5b600084116105a25760405162461bcd60e51b81526004018080602001828103825260238152602001806119a16023913960400191505060405180910390fd5b6105ab8561099c565b6105b88186868686610c2c565b5050505050565b6001546001600160a01b031681565b6001546000906105e9906001600160a01b0316858585610fb0565b949350505050565b600154600090819061060e906001600160a01b0316868686611257565b915091505b935093915050565b6001546001600160a01b03166105ab81610bd0565b6003546001600160a01b031690565b6001600160a01b031660009081526006602052604090205460ff1690565b60045490565b6005541590565b6002546003546004546005546001600160a01b03938416939092169184565b6001600160a01b0390811660009081526006602052604090205461010090041690565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6040518060400160405280600c81526020016b536f7274656454726f76657360a01b81525081565b6001600160a01b039081166000908152600660205260409020600101541690565b6000546001600160a01b031681565b6004546005541490565b60055490565b6107466106ac565b6001600160a01b0316336001600160a01b0316146107a5576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b600083116107e45760405162461bcd60e51b81526004018080602001828103825260228152602001806119046022913960400191505060405180910390fd5b6107ed82611444565b6107f681611444565b6004839055600180546001600160a01b038085166001600160a01b03199283168117909355600080549185169190921617905560408051918252517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038316815290517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1505050565b6001600160a01b0381166108e15760405162461bcd60e51b81526004018080602001828103825260228152602001806119526022913960400191505060405180910390fd5b806001600160a01b03166108f36106ac565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001546001600160a01b0316331461099a5760405162461bcd60e51b815260040180806020018281038252602c815260200180611926602c913960400191505060405180910390fd5b565b6109a58161063f565b6109e05760405162461bcd60e51b815260040180806020018281038252602a8152602001806118da602a913960400191505060405180910390fd5b60055460011015610b26576002546001600160a01b0382811691161415610a4f576001600160a01b03818116600090815260066020526040808220546002805461010090920485166001600160a01b031992831617908190559093168252902060010180549091169055610b21565b6003546001600160a01b0382811691161415610ab6576001600160a01b0380821660009081526006602052604080822060010154600380546001600160a01b03191691851691909117908190559092168152208054610100600160a81b0319169055610b21565b6001600160a01b038082166000908152600660205260408082208054600180830180548716865284862080546101009485900489168502610100600160a81b03199091161790555492549190910485168452919092200180546001600160a01b031916919092161790555b610b43565b600280546001600160a01b03199081169091556003805490911690555b6001600160a01b038116600090815260066020526040902080546001600160a81b0319168155600190810180546001600160a01b0319169055600554610b8e9163ffffffff6114f716565b600555604080516001600160a01b038316815290517fcfc24166db4bb677e857cacabd1541fb2b30645021b27c5130419589b84db52b9181900360200190a150565b6000546001600160a01b0316331480610bf15750336001600160a01b038216145b6104e75760405162461bcd60e51b815260040180806020018281038252602d815260200180611974602d913960400191505060405180910390fd5b610c3461072e565b15610c86576040805162461bcd60e51b815260206004820152601a60248201527f536f7274656454726f7665733a204c6973742069732066756c6c000000000000604482015290519081900360640190fd5b610c8f8461063f565b15610ccb5760405162461bcd60e51b815260040180806020018281038252602c8152602001806118ae602c913960400191505060405180910390fd5b6001600160a01b038416610d26576040805162461bcd60e51b815260206004820152601f60248201527f536f7274656454726f7665733a2049642063616e6e6f74206265207a65726f00604482015290519081900360640190fd5b60008311610d655760405162461bcd60e51b81526004018080602001828103825260238152602001806119a16023913960400191505060405180910390fd5b8181610d7387868484610fb0565b610d8957610d8387868484611257565b90925090505b6001600160a01b038087166000908152600660205260409020805460ff191660011790558216158015610dc357506001600160a01b038116155b15610df857600280546001600160a01b0388166001600160a01b03199182168117909255600380549091169091179055610f4c565b6001600160a01b038216610e6c57600280546001600160a01b03888116600081815260066020526040808220805495851661010002610100600160a81b0319909616959095179094558454909216825291902060010180546001600160a01b03199081168317909155825416179055610f4c565b6001600160a01b038116610edc57600380546001600160a01b0388811660008181526006602052604080822060010180549585166001600160a01b031996871617905585549093168152919091208054610100600160a81b03191661010083021790558254909116179055610f4c565b6001600160a01b038087166000818152600660205260408082208054858716610100818102610100600160a81b031993841617845560019384018054988b166001600160a01b0319998a168117909155865284862080549188029190931617909155835291200180549092161790555b600554610f6090600163ffffffff61154016565b600555604080516001600160a01b03881681526020810187905281517fe02b43adbee0c123de070a04554a71877a0007e2fc161466299cae3c094fe82f929181900390910190a150505050505050565b60006001600160a01b038316158015610fd057506001600160a01b038216155b15610fe457610fdd610663565b90506105e9565b6001600160a01b038316611096576002546001600160a01b038381169116148015610fdd5750846001600160a01b031663b0d8e181836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561106057600080fd5b505afa158015611074573d6000803e3d6000fd5b505050506040513d602081101561108a57600080fd5b505184101590506105e9565b6001600160a01b038216611148576003546001600160a01b038481169116148015610fdd5750846001600160a01b031663b0d8e181846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561111257600080fd5b505afa158015611126573d6000803e3d6000fd5b505050506040513d602081101561113c57600080fd5b505184111590506105e9565b6001600160a01b03838116600090815260066020526040902054610100900481169083161480156111fa575083856001600160a01b031663b0d8e181856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156111cb57600080fd5b505afa1580156111df573d6000803e3d6000fd5b505050506040513d60208110156111f557600080fd5b505110155b8015610fdd5750846001600160a01b031663b0d8e181836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561106057600080fd5b60008083836001600160a01b0382161561130a576112748261063f565b15806113005750876001600160a01b031663b0d8e181836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156112d157600080fd5b505afa1580156112e5573d6000803e3d6000fd5b505050506040513d60208110156112fb57600080fd5b505187115b1561130a57600091505b6001600160a01b038116156113b7576113228161063f565b15806113ae5750876001600160a01b031663b0d8e181826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561137f57600080fd5b505afa158015611393573d6000803e3d6000fd5b505050506040513d60208110156113a957600080fd5b505187105b156113b7575060005b6001600160a01b0382161580156113d557506001600160a01b038116155b156113fe576002546113f390899089906001600160a01b031661159a565b93509350505061143b565b6001600160a01b038216611417576113f38888836116db565b6001600160a01b038116611430576113f388888461159a565b6113f388888461159a565b94509492505050565b6001600160a01b03811661149f576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806114f3576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b600061153983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611816565b9392505050565b600082820183811015611539576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60025460009081906001600160a01b03848116911614801561163d5750846001600160a01b031663b0d8e181846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561160d57600080fd5b505afa158015611621573d6000803e3d6000fd5b505050506040513d602081101561163757600080fd5b50518410155b1561164d57506000905081610613565b6001600160a01b038084166000908152600660205260409020548491610100909104165b6001600160a01b03821615801590611692575061169087878484610fb0565b155b156116cf57506001600160a01b03908116600090815260066020526040808220546101009081900484168084529190922054909291900416611671565b90969095509350505050565b60035460009081906001600160a01b03848116911614801561177e5750846001600160a01b031663b0d8e181846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561174e57600080fd5b505afa158015611762573d6000803e3d6000fd5b505050506040513d602081101561177857600080fd5b50518411155b1561178e57508190506000610613565b6001600160a01b038084166000908152600660205260409020600101548491165b6001600160a01b038216158015906117d057506117ce87878385610fb0565b155b1561180b57506001600160a01b03908116600090815260066020526040808220600190810154841680845291909220909101549091166117af565b969095509350505050565b600081848411156118a55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561186a578181015183820152602001611852565b50505050905090810190601f1680156118975780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe536f7274656454726f7665733a204c69737420616c726561647920636f6e7461696e7320746865206e6f6465536f7274656454726f7665733a204c69737420646f6573206e6f7420636f6e7461696e20746865206964536f7274656454726f7665733a2053697a652063616ee2809974206265207a65726f536f7274656454726f7665733a2043616c6c6572206973206e6f74207468652054726f76654d616e616765724f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373536f7274656454726f7665733a2043616c6c6572206973206e65697468657220424f206e6f722054726f76654d536f7274656454726f7665733a204e494352206d75737420626520706f736974697665a264697066735822122032b466fa1ae0f54c795858e19523f6f623b02846824d1e4a37750d801b21599064736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0xdeEB95480B94f9395514Fe35CAF692A1C788DfE9" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/SortedTroves_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/SortedTroves_Proxy.json new file mode 100644 index 00000000..2d72d195 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynMainnet/SortedTroves_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0xdeEB95480B94f9395514Fe35CAF692A1C788DfE9", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/activePool_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/activePool_Proxy.json deleted file mode 100644 index 6205ce53..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/activePool_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0xf294ea272d6f8FedC08aCf8E93ff50fe99E1f7E8" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/collSurplusPool_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/collSurplusPool_Proxy.json deleted file mode 100644 index 40f43485..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/collSurplusPool_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x310ec7Fe6e4943DA773De8948255E37CC45e34bb" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/defaultPool_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/defaultPool_Proxy.json deleted file mode 100644 index b2cf01bc..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/defaultPool_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0xcdbA14ca707B99afb8CA93E178aD614Db422a030" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/feeDistributor_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/feeDistributor_Proxy.json deleted file mode 100644 index bd11588f..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/feeDistributor_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x1261d5872d56e2Ab61B3C68451D015b752105027" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/hintHelpers_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/hintHelpers_Proxy.json deleted file mode 100644 index 0e526641..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/hintHelpers_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x1D7DaC5a63A35540bE9e031212ecf39584AE5595" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/multiTroveGetter_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/multiTroveGetter_Proxy.json deleted file mode 100644 index 7ae0fc56..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/multiTroveGetter_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0xF265a169191348c02829B62650B025BdeAf00AE4" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/priceFeed_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/priceFeed_Proxy.json deleted file mode 100644 index 4dd83655..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/priceFeed_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x6D1d9574d67e04cf35Fa1d916F763eDDae03b75d" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/sortedTroves_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynMainnet/sortedTroves_Proxy.json deleted file mode 100644 index 7c3820d1..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/sortedTroves_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0xdeEB95480B94f9395514Fe35CAF692A1C788DfE9" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/activePool.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/ActivePool.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/activePool.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/ActivePool.json index 5d57dc53..ffe27b51 100644 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/activePool.json +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/ActivePool.json @@ -1,4 +1,5 @@ { + "address": "0xAD16eBA4EF0ff4C1aB5ffd89c485D5CfC51b5E61", "_format": "hh-sol-artifact-1", "contractName": "ActivePool", "sourceName": "contracts/ActivePool.sol", @@ -355,6 +356,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b8152600401808060200182810382526022815260200180610df66022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b610cd78061011f6000396000f3fe6080604052600436106100b65760003560e01c80635a4d28bb1161006f5780635a4d28bb1461022b57806364a197f314610240578063893d20e814610279578063a3f4df7e1461028e578063aac1846f14610318578063b7f8cf9b1461032d578063f2e91d71146103425761010f565b80630b622ab21461011457806313af40351461014557806314f6c3be1461017a5780632439789a146101a15780633963e980146101cb5780634a945f8d146101e05761010f565b3661010f576100c361036c565b6004546100d6903463ffffffff6103cc16565b600481905560408051918252517fca232b5abb988c540b959ff6c3bfae3e97fff964fd098c508f9613c0a6bf1a809181900360200190a1005b600080fd5b34801561012057600080fd5b5061012961042d565b604080516001600160a01b039092168252519081900360200190f35b34801561015157600080fd5b506101786004803603602081101561016857600080fd5b50356001600160a01b031661043c565b005b34801561018657600080fd5b5061018f6104af565b60408051918252519081900360200190f35b3480156101ad57600080fd5b50610178600480360360208110156101c457600080fd5b50356104b5565b3480156101d757600080fd5b5061018f61050a565b3480156101ec57600080fd5b506101786004803603608081101561020357600080fd5b506001600160a01b038135811691602081013582169160408201358116916060013516610510565b34801561023757600080fd5b506101296106cf565b34801561024c57600080fd5b506101786004803603604081101561026357600080fd5b506001600160a01b0381351690602001356106de565b34801561028557600080fd5b5061012961081f565b34801561029a57600080fd5b506102a3610849565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102dd5781810151838201526020016102c5565b50505050905090810190601f16801561030a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561032457600080fd5b5061012961086f565b34801561033957600080fd5b5061012961087e565b34801561034e57600080fd5b506101786004803603602081101561036557600080fd5b503561088d565b6000546001600160a01b031633148061038f57506003546001600160a01b031633145b6103ca5760405162461bcd60e51b8152600401808060200182810382526031815260200180610c716031913960400191505060405180910390fd5b565b600082820183811015610426576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6002546001600160a01b031681565b61044461081f565b6001600160a01b0316336001600160a01b0316146104a3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6104ac816108a8565b50565b60045490565b6104bd61095d565b6005546104d0908263ffffffff6109d016565b600581905560408051918252517fc179e77847def189a2838a920a4d2d78f966467c47494a7fb5fbd1477a2cf4f59181900360200190a150565b60055490565b61051861081f565b6001600160a01b0316336001600160a01b031614610577576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61058084610a12565b61058983610a12565b61059282610a12565b61059b81610a12565b600080546001600160a01b038087166001600160a01b031992831681179093556001805487831690841617905560028054868316908416179055600380549185169190921617905560408051918252517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1604080516001600160a01b038516815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038416815290517f82966d27eea39b038ee0fa30cd16532bb24f6e65d31cb58fb227aa5766cdcc7f9181900360200190a1604080516001600160a01b038316815290517f5ee0cae2f063ed938bb55046f6a932fb6ae792bf43624806bb90abe68a50be9b9181900360200190a150505050565b6001546001600160a01b031681565b6106e661095d565b6004546106f9908263ffffffff6109d016565b600481905560408051918252517fca232b5abb988c540b959ff6c3bfae3e97fff964fd098c508f9613c0a6bf1a809181900360200190a1604080516001600160a01b03841681526020810183905281517f6109e2559dfa766aaec7118351d48a523f0a4157f49c8d68749c8ac41318ad12929181900390910190a16040516000906001600160a01b0384169083908381818185875af1925050503d80600081146107bf576040519150601f19603f3d011682016040523d82523d6000602084013e6107c4565b606091505b505090508061081a576040805162461bcd60e51b815260206004820152601e60248201527f416374697665506f6f6c3a2073656e64696e6720455448206661696c65640000604482015290519081900360640190fd5b505050565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6040518060400160405280600a8152602001691058dd1a5d99541bdbdb60b21b81525081565b6003546001600160a01b031681565b6000546001600160a01b031681565b610895610ac5565b6005546104d0908263ffffffff6103cc16565b6001600160a01b0381166108ed5760405162461bcd60e51b8152600401808060200182810382526022815260200180610bfc6022913960400191505060405180910390fd5b806001600160a01b03166108ff61081f565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6000546001600160a01b031633148061098057506001546001600160a01b031633145b8061099557506002546001600160a01b031633145b6103ca5760405162461bcd60e51b8152600401808060200182810382526053815260200180610c1e6053913960600191505060405180910390fd5b600061042683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610b23565b6001600160a01b038116610a6d576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b80610ac1576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b6000546001600160a01b0316331480610ae857506001546001600160a01b031633145b6103ca5760405162461bcd60e51b8152600401808060200182810382526041815260200180610bbb6041913960600191505060405180910390fd5b60008184841115610bb25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b77578181015183820152602001610b5f565b50505050905090810190601f168015610ba45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe416374697665506f6f6c3a2043616c6c6572206973206e65697468657220426f72726f7765724f7065726174696f6e73206e6f722054726f76654d616e616765724f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373416374697665506f6f6c3a2043616c6c6572206973206e65697468657220426f72726f7765724f7065726174696f6e73206e6f722054726f76654d616e61676572206e6f722053746162696c697479506f6f6c416374697665506f6f6c3a2043616c6c6572206973206e65697468657220424f206e6f722044656661756c7420506f6f6ca26469706673582212209b05c372200c8127ca513fb34ec2474a15cb2a4151e9268b0749f3eb662cb88b64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", "deployedBytecode": "0x6080604052600436106100b65760003560e01c80635a4d28bb1161006f5780635a4d28bb1461022b57806364a197f314610240578063893d20e814610279578063a3f4df7e1461028e578063aac1846f14610318578063b7f8cf9b1461032d578063f2e91d71146103425761010f565b80630b622ab21461011457806313af40351461014557806314f6c3be1461017a5780632439789a146101a15780633963e980146101cb5780634a945f8d146101e05761010f565b3661010f576100c361036c565b6004546100d6903463ffffffff6103cc16565b600481905560408051918252517fca232b5abb988c540b959ff6c3bfae3e97fff964fd098c508f9613c0a6bf1a809181900360200190a1005b600080fd5b34801561012057600080fd5b5061012961042d565b604080516001600160a01b039092168252519081900360200190f35b34801561015157600080fd5b506101786004803603602081101561016857600080fd5b50356001600160a01b031661043c565b005b34801561018657600080fd5b5061018f6104af565b60408051918252519081900360200190f35b3480156101ad57600080fd5b50610178600480360360208110156101c457600080fd5b50356104b5565b3480156101d757600080fd5b5061018f61050a565b3480156101ec57600080fd5b506101786004803603608081101561020357600080fd5b506001600160a01b038135811691602081013582169160408201358116916060013516610510565b34801561023757600080fd5b506101296106cf565b34801561024c57600080fd5b506101786004803603604081101561026357600080fd5b506001600160a01b0381351690602001356106de565b34801561028557600080fd5b5061012961081f565b34801561029a57600080fd5b506102a3610849565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102dd5781810151838201526020016102c5565b50505050905090810190601f16801561030a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561032457600080fd5b5061012961086f565b34801561033957600080fd5b5061012961087e565b34801561034e57600080fd5b506101786004803603602081101561036557600080fd5b503561088d565b6000546001600160a01b031633148061038f57506003546001600160a01b031633145b6103ca5760405162461bcd60e51b8152600401808060200182810382526031815260200180610c716031913960400191505060405180910390fd5b565b600082820183811015610426576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6002546001600160a01b031681565b61044461081f565b6001600160a01b0316336001600160a01b0316146104a3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6104ac816108a8565b50565b60045490565b6104bd61095d565b6005546104d0908263ffffffff6109d016565b600581905560408051918252517fc179e77847def189a2838a920a4d2d78f966467c47494a7fb5fbd1477a2cf4f59181900360200190a150565b60055490565b61051861081f565b6001600160a01b0316336001600160a01b031614610577576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61058084610a12565b61058983610a12565b61059282610a12565b61059b81610a12565b600080546001600160a01b038087166001600160a01b031992831681179093556001805487831690841617905560028054868316908416179055600380549185169190921617905560408051918252517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1604080516001600160a01b038516815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038416815290517f82966d27eea39b038ee0fa30cd16532bb24f6e65d31cb58fb227aa5766cdcc7f9181900360200190a1604080516001600160a01b038316815290517f5ee0cae2f063ed938bb55046f6a932fb6ae792bf43624806bb90abe68a50be9b9181900360200190a150505050565b6001546001600160a01b031681565b6106e661095d565b6004546106f9908263ffffffff6109d016565b600481905560408051918252517fca232b5abb988c540b959ff6c3bfae3e97fff964fd098c508f9613c0a6bf1a809181900360200190a1604080516001600160a01b03841681526020810183905281517f6109e2559dfa766aaec7118351d48a523f0a4157f49c8d68749c8ac41318ad12929181900390910190a16040516000906001600160a01b0384169083908381818185875af1925050503d80600081146107bf576040519150601f19603f3d011682016040523d82523d6000602084013e6107c4565b606091505b505090508061081a576040805162461bcd60e51b815260206004820152601e60248201527f416374697665506f6f6c3a2073656e64696e6720455448206661696c65640000604482015290519081900360640190fd5b505050565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6040518060400160405280600a8152602001691058dd1a5d99541bdbdb60b21b81525081565b6003546001600160a01b031681565b6000546001600160a01b031681565b610895610ac5565b6005546104d0908263ffffffff6103cc16565b6001600160a01b0381166108ed5760405162461bcd60e51b8152600401808060200182810382526022815260200180610bfc6022913960400191505060405180910390fd5b806001600160a01b03166108ff61081f565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6000546001600160a01b031633148061098057506001546001600160a01b031633145b8061099557506002546001600160a01b031633145b6103ca5760405162461bcd60e51b8152600401808060200182810382526053815260200180610c1e6053913960600191505060405180910390fd5b600061042683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610b23565b6001600160a01b038116610a6d576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b80610ac1576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b6000546001600160a01b0316331480610ae857506001546001600160a01b031633145b6103ca5760405162461bcd60e51b8152600401808060200182810382526041815260200180610bbb6041913960600191505060405180910390fd5b60008184841115610bb25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b77578181015183820152602001610b5f565b50505050905090810190601f168015610ba45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe416374697665506f6f6c3a2043616c6c6572206973206e65697468657220426f72726f7765724f7065726174696f6e73206e6f722054726f76654d616e616765724f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373416374697665506f6f6c3a2043616c6c6572206973206e65697468657220426f72726f7765724f7065726174696f6e73206e6f722054726f76654d616e61676572206e6f722053746162696c697479506f6f6c416374697665506f6f6c3a2043616c6c6572206973206e65697468657220424f206e6f722044656661756c7420506f6f6ca26469706673582212209b05c372200c8127ca513fb34ec2474a15cb2a4151e9268b0749f3eb662cb88b64736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0xAD16eBA4EF0ff4C1aB5ffd89c485D5CfC51b5E61" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/ActivePool_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/ActivePool_Proxy.json new file mode 100644 index 00000000..71deaeca --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/ActivePool_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0xAD16eBA4EF0ff4C1aB5ffd89c485D5CfC51b5E61", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/borrowerOperations.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/BorrowerOperations.json similarity index 100% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/borrowerOperations.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/BorrowerOperations.json diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/borrowerOperations_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/BorrowerOperations_Proxy.json similarity index 100% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/borrowerOperations_Proxy.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/BorrowerOperations_Proxy.json index 3d84e5f1..3d3d03e9 100644 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/borrowerOperations_Proxy.json +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/BorrowerOperations_Proxy.json @@ -1,8 +1,8 @@ { + "address": "0xba8d7B80bcb3A01A5e713c356fD18EeD299B70D0", "_format": "hh-sol-artifact-1", "contractName": "UpgradableProxy", "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "address": "0xba8d7B80bcb3A01A5e713c356fD18EeD299B70D0", "abi": [ { "anonymous": false, diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/collSurplusPool.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/CollSurplusPool.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynMainnet/collSurplusPool.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/CollSurplusPool.json index f1c6810a..0e488f25 100644 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/collSurplusPool.json +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/CollSurplusPool.json @@ -1,4 +1,5 @@ { + "address": "0x6b74D66210f78dF0Ffb3A0D6A87471A1345C1284", "_format": "hh-sol-artifact-1", "contractName": "CollSurplusPool", "sourceName": "contracts/CollSurplusPool.sol", @@ -271,6 +272,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b8152600401808060200182810382526022815260200180610d786022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b610c598061011f6000396000f3fe6080604052600436106100a05760003560e01c8063893d20e811610064578063893d20e8146101d55780639b56d6c9146101ea578063a3f4df7e1461021d578063b08bc722146102a7578063b32beb5b146102bc578063b7f8cf9b146102ef576100c5565b806313af4035146100ca57806314f6c3be146100ff578063363bf964146101265780633f10abab1461016b5780635a4d28bb146101a4576100c5565b366100c5576100ad610304565b6003546100c0903463ffffffff61034f16565b600355005b600080fd5b3480156100d657600080fd5b506100fd600480360360208110156100ed57600080fd5b50356001600160a01b03166103b0565b005b34801561010b57600080fd5b50610114610423565b60408051918252519081900360200190f35b34801561013257600080fd5b506100fd6004803603606081101561014957600080fd5b506001600160a01b038135811691602081013582169160409091013516610429565b34801561017757600080fd5b506100fd6004803603604081101561018e57600080fd5b506001600160a01b038135169060200135610595565b3480156101b057600080fd5b506101b9610621565b604080516001600160a01b039092168252519081900360200190f35b3480156101e157600080fd5b506101b9610630565b3480156101f657600080fd5b506101146004803603602081101561020d57600080fd5b50356001600160a01b031661065a565b34801561022957600080fd5b50610232610675565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561026c578181015183820152602001610254565b50505050905090810190601f1680156102995780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102b357600080fd5b506101b96106a0565b3480156102c857600080fd5b506100fd600480360360208110156102df57600080fd5b50356001600160a01b03166106af565b3480156102fb57600080fd5b506101b9610849565b6002546001600160a01b0316331461034d5760405162461bcd60e51b815260040180806020018281038252602a815260200180610b58602a913960400191505060405180910390fd5b565b6000828201838110156103a9576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6103b8610630565b6001600160a01b0316336001600160a01b031614610417576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61042081610858565b50565b60035490565b610431610630565b6001600160a01b0316336001600160a01b031614610490576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6104998361090d565b6104a28261090d565b6104ab8161090d565b600080546001600160a01b038086166001600160a01b0319928316811790935560018054868316908416179055600280549185169190921617905560408051918252517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1604080516001600160a01b038416815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038316815290517f78f058b189175430c48dc02699e3a0031ea4ff781536dc2fab847de4babdd8829181900360200190a1505050565b61059d6109c0565b6001600160a01b0382166000908152600460205260408120546105c6908363ffffffff61034f16565b6001600160a01b0384166000818152600460209081526040918290208490558151848152915193945091927ff0393a34d05e6567686ad4e097f9d9d2781565957394f1f0d984e5d8e6378f20929181900390910190a2505050565b6001546001600160a01b031681565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6001600160a01b031660009081526004602052604090205490565b6040518060400160405280600f81526020016e10dbdb1b14dd5c9c1b1d5cd41bdbdb608a1b81525081565b6002546001600160a01b031681565b6106b7610a09565b6001600160a01b0381166000908152600460205260409020548061070c5760405162461bcd60e51b8152600401808060200182810382526031815260200180610b276031913960400191505060405180910390fd5b6001600160a01b03821660008181526004602090815260408083208390558051928352517ff0393a34d05e6567686ad4e097f9d9d2781565957394f1f0d984e5d8e6378f209281900390910190a260035461076d908263ffffffff610a5216565b600355604080516001600160a01b03841681526020810183905281517f6109e2559dfa766aaec7118351d48a523f0a4157f49c8d68749c8ac41318ad12929181900390910190a16040516000906001600160a01b0384169083908381818185875af1925050503d80600081146107ff576040519150601f19603f3d011682016040523d82523d6000602084013e610804565b606091505b50509050806108445760405162461bcd60e51b8152600401808060200182810382526023815260200180610ba46023913960400191505060405180910390fd5b505050565b6000546001600160a01b031681565b6001600160a01b03811661089d5760405162461bcd60e51b8152600401808060200182810382526022815260200180610b826022913960400191505060405180910390fd5b806001600160a01b03166108af610630565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b038116610968576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806109bc576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b6001546001600160a01b0316331461034d5760405162461bcd60e51b815260040180806020018281038252602b815260200180610bf9602b913960400191505060405180910390fd5b6000546001600160a01b0316331461034d5760405162461bcd60e51b8152600401808060200182810382526032815260200180610bc76032913960400191505060405180910390fd5b60006103a983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060008184841115610b1e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ae3578181015183820152602001610acb565b50505050905090810190601f168015610b105780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe436f6c6c537572706c7573506f6f6c3a204e6f20636f6c6c61746572616c20617661696c61626c6520746f20636c61696d436f6c6c537572706c7573506f6f6c3a2043616c6c6572206973206e6f742041637469766520506f6f6c4f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373436f6c6c537572706c7573506f6f6c3a2073656e64696e6720455448206661696c6564436f6c6c537572706c7573506f6f6c3a2043616c6c6572206973206e6f7420426f72726f776572204f7065726174696f6e73436f6c6c537572706c7573506f6f6c3a2043616c6c6572206973206e6f742054726f76654d616e61676572a2646970667358221220ec19e79dbe7180a98cb7d6212d7b49be2e6c8b1fa1ef966e63158e1190ee1e1e64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", "deployedBytecode": "0x6080604052600436106100a05760003560e01c8063893d20e811610064578063893d20e8146101d55780639b56d6c9146101ea578063a3f4df7e1461021d578063b08bc722146102a7578063b32beb5b146102bc578063b7f8cf9b146102ef576100c5565b806313af4035146100ca57806314f6c3be146100ff578063363bf964146101265780633f10abab1461016b5780635a4d28bb146101a4576100c5565b366100c5576100ad610304565b6003546100c0903463ffffffff61034f16565b600355005b600080fd5b3480156100d657600080fd5b506100fd600480360360208110156100ed57600080fd5b50356001600160a01b03166103b0565b005b34801561010b57600080fd5b50610114610423565b60408051918252519081900360200190f35b34801561013257600080fd5b506100fd6004803603606081101561014957600080fd5b506001600160a01b038135811691602081013582169160409091013516610429565b34801561017757600080fd5b506100fd6004803603604081101561018e57600080fd5b506001600160a01b038135169060200135610595565b3480156101b057600080fd5b506101b9610621565b604080516001600160a01b039092168252519081900360200190f35b3480156101e157600080fd5b506101b9610630565b3480156101f657600080fd5b506101146004803603602081101561020d57600080fd5b50356001600160a01b031661065a565b34801561022957600080fd5b50610232610675565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561026c578181015183820152602001610254565b50505050905090810190601f1680156102995780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102b357600080fd5b506101b96106a0565b3480156102c857600080fd5b506100fd600480360360208110156102df57600080fd5b50356001600160a01b03166106af565b3480156102fb57600080fd5b506101b9610849565b6002546001600160a01b0316331461034d5760405162461bcd60e51b815260040180806020018281038252602a815260200180610b58602a913960400191505060405180910390fd5b565b6000828201838110156103a9576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6103b8610630565b6001600160a01b0316336001600160a01b031614610417576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61042081610858565b50565b60035490565b610431610630565b6001600160a01b0316336001600160a01b031614610490576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6104998361090d565b6104a28261090d565b6104ab8161090d565b600080546001600160a01b038086166001600160a01b0319928316811790935560018054868316908416179055600280549185169190921617905560408051918252517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1604080516001600160a01b038416815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038316815290517f78f058b189175430c48dc02699e3a0031ea4ff781536dc2fab847de4babdd8829181900360200190a1505050565b61059d6109c0565b6001600160a01b0382166000908152600460205260408120546105c6908363ffffffff61034f16565b6001600160a01b0384166000818152600460209081526040918290208490558151848152915193945091927ff0393a34d05e6567686ad4e097f9d9d2781565957394f1f0d984e5d8e6378f20929181900390910190a2505050565b6001546001600160a01b031681565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6001600160a01b031660009081526004602052604090205490565b6040518060400160405280600f81526020016e10dbdb1b14dd5c9c1b1d5cd41bdbdb608a1b81525081565b6002546001600160a01b031681565b6106b7610a09565b6001600160a01b0381166000908152600460205260409020548061070c5760405162461bcd60e51b8152600401808060200182810382526031815260200180610b276031913960400191505060405180910390fd5b6001600160a01b03821660008181526004602090815260408083208390558051928352517ff0393a34d05e6567686ad4e097f9d9d2781565957394f1f0d984e5d8e6378f209281900390910190a260035461076d908263ffffffff610a5216565b600355604080516001600160a01b03841681526020810183905281517f6109e2559dfa766aaec7118351d48a523f0a4157f49c8d68749c8ac41318ad12929181900390910190a16040516000906001600160a01b0384169083908381818185875af1925050503d80600081146107ff576040519150601f19603f3d011682016040523d82523d6000602084013e610804565b606091505b50509050806108445760405162461bcd60e51b8152600401808060200182810382526023815260200180610ba46023913960400191505060405180910390fd5b505050565b6000546001600160a01b031681565b6001600160a01b03811661089d5760405162461bcd60e51b8152600401808060200182810382526022815260200180610b826022913960400191505060405180910390fd5b806001600160a01b03166108af610630565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b038116610968576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806109bc576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b6001546001600160a01b0316331461034d5760405162461bcd60e51b815260040180806020018281038252602b815260200180610bf9602b913960400191505060405180910390fd5b6000546001600160a01b0316331461034d5760405162461bcd60e51b8152600401808060200182810382526032815260200180610bc76032913960400191505060405180910390fd5b60006103a983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060008184841115610b1e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ae3578181015183820152602001610acb565b50505050905090810190601f168015610b105780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe436f6c6c537572706c7573506f6f6c3a204e6f20636f6c6c61746572616c20617661696c61626c6520746f20636c61696d436f6c6c537572706c7573506f6f6c3a2043616c6c6572206973206e6f742041637469766520506f6f6c4f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373436f6c6c537572706c7573506f6f6c3a2073656e64696e6720455448206661696c6564436f6c6c537572706c7573506f6f6c3a2043616c6c6572206973206e6f7420426f72726f776572204f7065726174696f6e73436f6c6c537572706c7573506f6f6c3a2043616c6c6572206973206e6f742054726f76654d616e61676572a2646970667358221220ec19e79dbe7180a98cb7d6212d7b49be2e6c8b1fa1ef966e63158e1190ee1e1e64736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x310ec7Fe6e4943DA773De8948255E37CC45e34bb" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/CollSurplusPool_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/CollSurplusPool_Proxy.json new file mode 100644 index 00000000..b9c85c6e --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/CollSurplusPool_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0x6b74D66210f78dF0Ffb3A0D6A87471A1345C1284", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/CommunityIssuance.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/CommunityIssuance.json new file mode 100644 index 00000000..2d51b67f --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/CommunityIssuance.json @@ -0,0 +1,415 @@ +{ + "address": "0xD017396d2284699e0Ce34b236CcE5321Ee3078e5", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_APR", + "type": "uint256" + } + ], + "name": "APRSet", + "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": "_priceFeed", + "type": "address" + } + ], + "name": "PriceFeedAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_rewardManagerAddress", + "type": "address" + } + ], + "name": "RewardManagerAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_sovTokenAddress", + "type": "address" + } + ], + "name": "SOVTokenAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_stabilityPoolAddress", + "type": "address" + } + ], + "name": "StabilityPoolAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_latestSOVIssued", + "type": "uint256" + } + ], + "name": "TotalSOVIssuedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_zusdTokenAddress", + "type": "address" + } + ], + "name": "ZUSDTokenAddressSet", + "type": "event" + }, + { + "inputs": [], + "name": "APR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DECIMAL_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sovTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_zusdTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_stabilityPoolAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_priceFeed", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_APR", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_totalZUSDDeposits", + "type": "uint256" + } + ], + "name": "issueSOV", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastIssuanceTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceFeed", + "outputs": [ + { + "internalType": "contract IPriceFeedSovryn", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_SOVamount", + "type": "uint256" + } + ], + "name": "sendSOV", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_APR", + "type": "uint256" + } + ], + "name": "setAPR", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_priceFeedAddress", + "type": "address" + } + ], + "name": "setPriceFeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardManagerAddress", + "type": "address" + } + ], + "name": "setRewardManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sovToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stabilityPoolAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSOVIssued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "zusdToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x2acb898db67ad315c1154b584fa55511561d6cee643bba7c29dbd9a0d2d8567f", + "receipt": { + "to": null, + "from": "0xCF311E7375083b9513566a47B9f3e93F1FcdCfBF", + "contractAddress": "0xDC404557f5cD1932efFf160fa72b2f96e76b8a3c", + "transactionIndex": 0, + "gasUsed": "1208667", + "logsBloom": "0x00000000000000000000000000000000000000800000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000020000000400000000000200000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000020000000000000000000000000000000000000000000000100000000000000000000", + "blockHash": "0xb1a030aa0e37807b3fab930f9211ba9019d1cd6c08844dc18d29ae35f762c061", + "transactionHash": "0x2acb898db67ad315c1154b584fa55511561d6cee643bba7c29dbd9a0d2d8567f", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 3776876, + "transactionHash": "0x2acb898db67ad315c1154b584fa55511561d6cee643bba7c29dbd9a0d2d8567f", + "address": "0xDC404557f5cD1932efFf160fa72b2f96e76b8a3c", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cf311e7375083b9513566a47b9f3e93f1fcdcfbf" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0xb1a030aa0e37807b3fab930f9211ba9019d1cd6c08844dc18d29ae35f762c061" + } + ], + "blockNumber": 3776876, + "cumulativeGasUsed": "1208667", + "status": 1, + "byzantium": true + }, + "numDeployments": 6, + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610143565b6001600160a01b0381166100575760405162461bcd60e51b815260040161004e90610101565b60405180910390fd5b6001600160a01b0381166100726001600160e01b036100c516565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360006040516100b5906100e4565b6040519081900390209190915550565b6000806040516100d4906100e4565b6040519081900390205492915050565b7035b2bc9737bbb730b136329737bbb732b960791b815260110190565b60208082526022908201527f4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265604082015261737360f01b606082015260800190565b611042806101526000396000f3fe608060405234801561001057600080fd5b50600436106100f65760003560e01c8063893d20e811610092578063893d20e81461019f57806398afd294146101a7578063a20baee6146101af578063a3f4df7e146101b7578063ae601ac1146101cc578063bd30558e146101d4578063ec9f7d46146101dc578063f7013ef6146101e4578063f8c1dc6c146101f7576100f6565b80630b622ab2146100fb5780630f4ef8a61461011957806313af403514610121578063153ee5541461013657806360bf03ff146101495780636cbdcf471461015e578063724e78da14610171578063741bef1a14610184578063854303cf1461018c575b600080fd5b61010361020a565b6040516101109190610ced565b60405180910390f35b610103610219565b61013461012f366004610bd8565b610228565b005b610134610144366004610bd8565b610275565b610151610329565b6040516101109190610fee565b61015161016c366004610ca0565b61032f565b61013461017f366004610bd8565b610348565b6101036103d4565b61013461019a366004610ca0565b6103e3565b6101036104e0565b6101036104ff565b61015161050e565b6101bf61051a565b6040516101109190610d3e565b610151610547565b61015161054d565b610103610553565b6101346101f2366004610bf3565b610562565b610134610205366004610c56565b61077f565b6035546001600160a01b031681565b6039546001600160a01b031681565b6102306104e0565b6001600160a01b0316336001600160a01b0316146102695760405162461bcd60e51b815260040161026090610f45565b60405180910390fd5b61027281610830565b50565b61027d6104e0565b6001600160a01b0316336001600160a01b0316146102ad5760405162461bcd60e51b815260040161026090610f45565b6001600160a01b0381166102d35760405162461bcd60e51b815260040161026090610e7f565b603980546001600160a01b0319166001600160a01b0383161790556040517f1c7e8eeb20c95a47700378fd4dd1a7fe13a6f508d25615c5fb1f3d1099051daa9061031e908390610ced565b60405180910390a150565b60375481565b60006103396108bb565b610342826108e7565b92915050565b6103506104e0565b6001600160a01b0316336001600160a01b0316146103805760405162461bcd60e51b815260040161026090610f45565b61038981610999565b603a80546001600160a01b0319166001600160a01b0383161790556040517facd42642b5cb91804117282727eb92664d362985a4f353ccd03833d3049d16d99061031e908390610ced565b603a546001600160a01b031681565b6039546001600160a01b0316331461040d5760405162461bcd60e51b815260040161026090610dc8565b610416816109e2565b60355460408051635ed79bf560e11b815290516000926001600160a01b03169163bdaf37ea916004808301926020929190829003018186803b15801561045b57600080fd5b505afa15801561046f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104939190610cb8565b905061049e816108e7565b5060388290556040517fd6b99165a8b6705d5dbba79fccdcac9b98141cb0f6413824ebd39fdfbe611ba6906104d4908490610fee565b60405180910390a15050565b6000806040516104ef90610cd0565b6040519081900390205492915050565b6033546001600160a01b031681565b670de0b6b3a764000081565b60405180604001604052806011815260200170436f6d6d756e69747949737375616e636560781b81525081565b60365481565b60385481565b6034546001600160a01b031681565b600054610100900460ff168061057b575061057b610a04565b80610589575060005460ff16155b6105a55760405162461bcd60e51b815260040161026090610ef7565b600054610100900460ff161580156105d0576000805460ff1961ff0019909116610100171660011790555b6105d86104e0565b6001600160a01b0316336001600160a01b0316146106085760405162461bcd60e51b815260040161026090610f45565b61061186610999565b61061a85610999565b61062384610999565b61062c83610999565b610635826109e2565b603380546001600160a01b038089166001600160a01b0319928316179092556034805488841690831617905560358054878416908316179055603a8054928616929091169190911790556038829055426037556040517f5bce47da81ad81a6d5745ec7a1790bd9213dc36898110fd3681b037768a2b3c6906106b8908890610ced565b60405180910390a17f45c53611bc8ba9e11f4f8173bda9e3faf89c395ddb83f9a55230b156828db315846040516106ef9190610ced565b60405180910390a17facd42642b5cb91804117282727eb92664d362985a4f353ccd03833d3049d16d9836040516107269190610ced565b60405180910390a17fd6b99165a8b6705d5dbba79fccdcac9b98141cb0f6413824ebd39fdfbe611ba68260405161075d9190610fee565b60405180910390a18015610777576000805461ff00191690555b505050505050565b6107876108bb565b60335460405163a9059cbb60e01b81526000916001600160a01b03169063a9059cbb906107ba9086908690600401610d25565b602060405180830381600087803b1580156107d457600080fd5b505af11580156107e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080c9190610c80565b90508061082b5760405162461bcd60e51b815260040161026090610e10565b505050565b6001600160a01b0381166108565760405162461bcd60e51b815260040161026090610e3d565b806001600160a01b03166108686104e0565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360006040516108ab90610cd0565b6040519081900390209190915550565b6035546001600160a01b031633146108e55760405162461bcd60e51b815260040161026090610f76565b565b6000806108ff60375442610a0a90919063ffffffff16565b9050600061094a6109456301e1338061092d8561093961271061092d6038548c610a5390919063ffffffff16565b9063ffffffff610a8d16565b9063ffffffff610a5316565b610acf565b60368054820190819055426037556040519192507f47eb3c2a573d55ee40451cdc91a92eb7fe3dd8bcdb4d19c9acd32ecaa29f2d559161098a9190610fee565b60405180910390a19392505050565b6001600160a01b0381166109bf5760405162461bcd60e51b815260040161026090610e7f565b803b806109de5760405162461bcd60e51b815260040161026090610fb9565b5050565b6127108111156102725760405162461bcd60e51b815260040161026090610d91565b303b1590565b6000610a4c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610b5e565b9392505050565b600082610a6257506000610342565b82820282848281610a6f57fe5b0414610a4c5760405162461bcd60e51b815260040161026090610eb6565b6000610a4c83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610b8a565b603a5460345460335460405163d138f9a160e01b81526000936001600160a01b039081169363d138f9a193610b0e939183169216908790600401610d01565b60206040518083038186803b158015610b2657600080fd5b505afa158015610b3a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103429190610cb8565b60008184841115610b825760405162461bcd60e51b81526004016102609190610d3e565b505050900390565b60008183610bab5760405162461bcd60e51b81526004016102609190610d3e565b506000838581610bb757fe5b0495945050505050565b80356001600160a01b038116811461034257600080fd5b600060208284031215610be9578081fd5b610a4c8383610bc1565b600080600080600060a08688031215610c0a578081fd5b8535610c1581610ff7565b94506020860135610c2581610ff7565b93506040860135610c3581610ff7565b92506060860135610c4581610ff7565b949793965091946080013592915050565b60008060408385031215610c68578182fd5b610c728484610bc1565b946020939093013593505050565b600060208284031215610c91578081fd5b81518015158114610a4c578182fd5b600060208284031215610cb1578081fd5b5035919050565b600060208284031215610cc9578081fd5b5051919050565b7035b2bc9737bbb730b136329737bbb732b960791b815260110190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602080835283518082850152825b81811015610d6a57858101830151858201604001528201610d4e565b81811115610d7b5783604083870101525b50601f01601f1916929092016040019392505050565b6020808252601b908201527f415052206d757374206265206c657373207468616e2031303030300000000000604082015260600190565b60208082526028908201527f5065726d697373696f6e3a3a7265776172644d616e616765723a2061636365736040820152671cc819195b9a595960c21b606082015260800190565b6020808252601390820152724661696c656420746f2073656e64205a45524f60681b604082015260600190565b60208082526022908201527f4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265604082015261737360f01b606082015260800190565b6020808252601e908201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526017908201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604082015260600190565b60208082526023908201527f436f6d6d756e69747949737375616e63653a2063616c6c6572206973206e6f7460408201526202053560ec1b606082015260800190565b6020808252818101527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604082015260600190565b90815260200190565b6001600160a01b038116811461027257600080fdfea264697066735822122051b903c2ec1e851a057918eeb01dc6764d14b46ee244b0a35c68f6dc52321c3a64736f6c634300060b0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100f65760003560e01c8063893d20e811610092578063893d20e81461019f57806398afd294146101a7578063a20baee6146101af578063a3f4df7e146101b7578063ae601ac1146101cc578063bd30558e146101d4578063ec9f7d46146101dc578063f7013ef6146101e4578063f8c1dc6c146101f7576100f6565b80630b622ab2146100fb5780630f4ef8a61461011957806313af403514610121578063153ee5541461013657806360bf03ff146101495780636cbdcf471461015e578063724e78da14610171578063741bef1a14610184578063854303cf1461018c575b600080fd5b61010361020a565b6040516101109190610ced565b60405180910390f35b610103610219565b61013461012f366004610bd8565b610228565b005b610134610144366004610bd8565b610275565b610151610329565b6040516101109190610fee565b61015161016c366004610ca0565b61032f565b61013461017f366004610bd8565b610348565b6101036103d4565b61013461019a366004610ca0565b6103e3565b6101036104e0565b6101036104ff565b61015161050e565b6101bf61051a565b6040516101109190610d3e565b610151610547565b61015161054d565b610103610553565b6101346101f2366004610bf3565b610562565b610134610205366004610c56565b61077f565b6035546001600160a01b031681565b6039546001600160a01b031681565b6102306104e0565b6001600160a01b0316336001600160a01b0316146102695760405162461bcd60e51b815260040161026090610f45565b60405180910390fd5b61027281610830565b50565b61027d6104e0565b6001600160a01b0316336001600160a01b0316146102ad5760405162461bcd60e51b815260040161026090610f45565b6001600160a01b0381166102d35760405162461bcd60e51b815260040161026090610e7f565b603980546001600160a01b0319166001600160a01b0383161790556040517f1c7e8eeb20c95a47700378fd4dd1a7fe13a6f508d25615c5fb1f3d1099051daa9061031e908390610ced565b60405180910390a150565b60375481565b60006103396108bb565b610342826108e7565b92915050565b6103506104e0565b6001600160a01b0316336001600160a01b0316146103805760405162461bcd60e51b815260040161026090610f45565b61038981610999565b603a80546001600160a01b0319166001600160a01b0383161790556040517facd42642b5cb91804117282727eb92664d362985a4f353ccd03833d3049d16d99061031e908390610ced565b603a546001600160a01b031681565b6039546001600160a01b0316331461040d5760405162461bcd60e51b815260040161026090610dc8565b610416816109e2565b60355460408051635ed79bf560e11b815290516000926001600160a01b03169163bdaf37ea916004808301926020929190829003018186803b15801561045b57600080fd5b505afa15801561046f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104939190610cb8565b905061049e816108e7565b5060388290556040517fd6b99165a8b6705d5dbba79fccdcac9b98141cb0f6413824ebd39fdfbe611ba6906104d4908490610fee565b60405180910390a15050565b6000806040516104ef90610cd0565b6040519081900390205492915050565b6033546001600160a01b031681565b670de0b6b3a764000081565b60405180604001604052806011815260200170436f6d6d756e69747949737375616e636560781b81525081565b60365481565b60385481565b6034546001600160a01b031681565b600054610100900460ff168061057b575061057b610a04565b80610589575060005460ff16155b6105a55760405162461bcd60e51b815260040161026090610ef7565b600054610100900460ff161580156105d0576000805460ff1961ff0019909116610100171660011790555b6105d86104e0565b6001600160a01b0316336001600160a01b0316146106085760405162461bcd60e51b815260040161026090610f45565b61061186610999565b61061a85610999565b61062384610999565b61062c83610999565b610635826109e2565b603380546001600160a01b038089166001600160a01b0319928316179092556034805488841690831617905560358054878416908316179055603a8054928616929091169190911790556038829055426037556040517f5bce47da81ad81a6d5745ec7a1790bd9213dc36898110fd3681b037768a2b3c6906106b8908890610ced565b60405180910390a17f45c53611bc8ba9e11f4f8173bda9e3faf89c395ddb83f9a55230b156828db315846040516106ef9190610ced565b60405180910390a17facd42642b5cb91804117282727eb92664d362985a4f353ccd03833d3049d16d9836040516107269190610ced565b60405180910390a17fd6b99165a8b6705d5dbba79fccdcac9b98141cb0f6413824ebd39fdfbe611ba68260405161075d9190610fee565b60405180910390a18015610777576000805461ff00191690555b505050505050565b6107876108bb565b60335460405163a9059cbb60e01b81526000916001600160a01b03169063a9059cbb906107ba9086908690600401610d25565b602060405180830381600087803b1580156107d457600080fd5b505af11580156107e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080c9190610c80565b90508061082b5760405162461bcd60e51b815260040161026090610e10565b505050565b6001600160a01b0381166108565760405162461bcd60e51b815260040161026090610e3d565b806001600160a01b03166108686104e0565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360006040516108ab90610cd0565b6040519081900390209190915550565b6035546001600160a01b031633146108e55760405162461bcd60e51b815260040161026090610f76565b565b6000806108ff60375442610a0a90919063ffffffff16565b9050600061094a6109456301e1338061092d8561093961271061092d6038548c610a5390919063ffffffff16565b9063ffffffff610a8d16565b9063ffffffff610a5316565b610acf565b60368054820190819055426037556040519192507f47eb3c2a573d55ee40451cdc91a92eb7fe3dd8bcdb4d19c9acd32ecaa29f2d559161098a9190610fee565b60405180910390a19392505050565b6001600160a01b0381166109bf5760405162461bcd60e51b815260040161026090610e7f565b803b806109de5760405162461bcd60e51b815260040161026090610fb9565b5050565b6127108111156102725760405162461bcd60e51b815260040161026090610d91565b303b1590565b6000610a4c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610b5e565b9392505050565b600082610a6257506000610342565b82820282848281610a6f57fe5b0414610a4c5760405162461bcd60e51b815260040161026090610eb6565b6000610a4c83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610b8a565b603a5460345460335460405163d138f9a160e01b81526000936001600160a01b039081169363d138f9a193610b0e939183169216908790600401610d01565b60206040518083038186803b158015610b2657600080fd5b505afa158015610b3a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103429190610cb8565b60008184841115610b825760405162461bcd60e51b81526004016102609190610d3e565b505050900390565b60008183610bab5760405162461bcd60e51b81526004016102609190610d3e565b506000838581610bb757fe5b0495945050505050565b80356001600160a01b038116811461034257600080fd5b600060208284031215610be9578081fd5b610a4c8383610bc1565b600080600080600060a08688031215610c0a578081fd5b8535610c1581610ff7565b94506020860135610c2581610ff7565b93506040860135610c3581610ff7565b92506060860135610c4581610ff7565b949793965091946080013592915050565b60008060408385031215610c68578182fd5b610c728484610bc1565b946020939093013593505050565b600060208284031215610c91578081fd5b81518015158114610a4c578182fd5b600060208284031215610cb1578081fd5b5035919050565b600060208284031215610cc9578081fd5b5051919050565b7035b2bc9737bbb730b136329737bbb732b960791b815260110190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602080835283518082850152825b81811015610d6a57858101830151858201604001528201610d4e565b81811115610d7b5783604083870101525b50601f01601f1916929092016040019392505050565b6020808252601b908201527f415052206d757374206265206c657373207468616e2031303030300000000000604082015260600190565b60208082526028908201527f5065726d697373696f6e3a3a7265776172644d616e616765723a2061636365736040820152671cc819195b9a595960c21b606082015260800190565b6020808252601390820152724661696c656420746f2073656e64205a45524f60681b604082015260600190565b60208082526022908201527f4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265604082015261737360f01b606082015260800190565b6020808252601e908201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526017908201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604082015260600190565b60208082526023908201527f436f6d6d756e69747949737375616e63653a2063616c6c6572206973206e6f7460408201526202053560ec1b606082015260800190565b6020808252818101527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604082015260600190565b90815260200190565b6001600160a01b038116811461027257600080fdfea264697066735822122051b903c2ec1e851a057918eeb01dc6764d14b46ee244b0a35c68f6dc52321c3a64736f6c634300060b0033", + "implementation": "0xDC404557f5cD1932efFf160fa72b2f96e76b8a3c" +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/CommunityIssuance_Implementation.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/CommunityIssuance_Implementation.json new file mode 100644 index 00000000..5633b825 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/CommunityIssuance_Implementation.json @@ -0,0 +1,598 @@ +{ + "address": "0xDC404557f5cD1932efFf160fa72b2f96e76b8a3c", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_APR", + "type": "uint256" + } + ], + "name": "APRSet", + "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": "_priceFeed", + "type": "address" + } + ], + "name": "PriceFeedAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_rewardManagerAddress", + "type": "address" + } + ], + "name": "RewardManagerAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_sovTokenAddress", + "type": "address" + } + ], + "name": "SOVTokenAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_stabilityPoolAddress", + "type": "address" + } + ], + "name": "StabilityPoolAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_latestSOVIssued", + "type": "uint256" + } + ], + "name": "TotalSOVIssuedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_zusdTokenAddress", + "type": "address" + } + ], + "name": "ZUSDTokenAddressSet", + "type": "event" + }, + { + "inputs": [], + "name": "APR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DECIMAL_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sovTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_zusdTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_stabilityPoolAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_priceFeed", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_APR", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_totalZUSDDeposits", + "type": "uint256" + } + ], + "name": "issueSOV", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastIssuanceTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceFeed", + "outputs": [ + { + "internalType": "contract IPriceFeedSovryn", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_SOVamount", + "type": "uint256" + } + ], + "name": "sendSOV", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_APR", + "type": "uint256" + } + ], + "name": "setAPR", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_priceFeedAddress", + "type": "address" + } + ], + "name": "setPriceFeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardManagerAddress", + "type": "address" + } + ], + "name": "setRewardManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sovToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stabilityPoolAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSOVIssued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "zusdToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x2acb898db67ad315c1154b584fa55511561d6cee643bba7c29dbd9a0d2d8567f", + "receipt": { + "to": null, + "from": "0xCF311E7375083b9513566a47B9f3e93F1FcdCfBF", + "contractAddress": "0xDC404557f5cD1932efFf160fa72b2f96e76b8a3c", + "transactionIndex": 0, + "gasUsed": "1208667", + "logsBloom": "0x00000000000000000000000000000000000000800000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000020000000400000000000200000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000020000000000000000000000000000000000000000000000100000000000000000000", + "blockHash": "0xb1a030aa0e37807b3fab930f9211ba9019d1cd6c08844dc18d29ae35f762c061", + "transactionHash": "0x2acb898db67ad315c1154b584fa55511561d6cee643bba7c29dbd9a0d2d8567f", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 3776876, + "transactionHash": "0x2acb898db67ad315c1154b584fa55511561d6cee643bba7c29dbd9a0d2d8567f", + "address": "0xDC404557f5cD1932efFf160fa72b2f96e76b8a3c", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cf311e7375083b9513566a47b9f3e93f1fcdcfbf" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0xb1a030aa0e37807b3fab930f9211ba9019d1cd6c08844dc18d29ae35f762c061" + } + ], + "blockNumber": 3776876, + "cumulativeGasUsed": "1208667", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 5, + "solcInputHash": "be36e640ecbdc455165550d36df9feff", + "metadata": "{\"compiler\":{\"version\":\"0.6.11+commit.5ef660b1\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_APR\",\"type\":\"uint256\"}],\"name\":\"APRSet\",\"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\":\"_priceFeed\",\"type\":\"address\"}],\"name\":\"PriceFeedAddressSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_rewardManagerAddress\",\"type\":\"address\"}],\"name\":\"RewardManagerAddressSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sovTokenAddress\",\"type\":\"address\"}],\"name\":\"SOVTokenAddressSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_stabilityPoolAddress\",\"type\":\"address\"}],\"name\":\"StabilityPoolAddressSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_latestSOVIssued\",\"type\":\"uint256\"}],\"name\":\"TotalSOVIssuedUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_zusdTokenAddress\",\"type\":\"address\"}],\"name\":\"ZUSDTokenAddressSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"APR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DECIMAL_PRECISION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sovTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_zusdTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_stabilityPoolAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_APR\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_totalZUSDDeposits\",\"type\":\"uint256\"}],\"name\":\"issueSOV\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastIssuanceTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"priceFeed\",\"outputs\":[{\"internalType\":\"contract IPriceFeedSovryn\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_SOVamount\",\"type\":\"uint256\"}],\"name\":\"sendSOV\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_APR\",\"type\":\"uint256\"}],\"name\":\"setAPR\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_priceFeedAddress\",\"type\":\"address\"}],\"name\":\"setPriceFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_rewardManagerAddress\",\"type\":\"address\"}],\"name\":\"setRewardManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sovToken\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stabilityPoolAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSOVIssued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"zusdToken\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getOwner()\":{\"returns\":{\"_owner\":\"Address of the owner. \"}},\"initialize(address,address,address,address,uint256)\":{\"details\":\"initialization function to set configs. can only be initialized by owner.\",\"params\":{\"_APR\":\"apr in basis points.\",\"_priceFeed\":\"price feed address.\",\"_sovTokenAddress\":\"sov token address.\",\"_stabilityPoolAddress\":\"stability pool address.\",\"_zusdTokenAddress\":\"zero token address.\"}},\"setAPR(uint256)\":{\"details\":\"setter function to set the APR value in basis points. can only be called by reward manager.\",\"params\":{\"_APR\":\"apr value in basis points.\"}},\"setOwner(address)\":{\"params\":{\"_owner\":\"Address of the owner. \"}},\"setPriceFeed(address)\":{\"details\":\"setter function to set the price feed. can only be called by the owner.\",\"params\":{\"_priceFeedAddress\":\"price feed address.\"}},\"setRewardManager(address)\":{\"details\":\"setter function to set reward manager. can only be called by the owner.\",\"params\":{\"_rewardManagerAddress\":\"reward manager address.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getOwner()\":{\"notice\":\"Return address of the owner.\"},\"setOwner(address)\":{\"notice\":\"Set address of the owner (only owner can call this function)\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ZERO/CommunityIssuance.sol\":\"CommunityIssuance\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"contracts/Dependencies/BaseMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.6.11;\\n\\n\\ncontract BaseMath {\\n uint constant public DECIMAL_PRECISION = 1e18;\\n}\\n\",\"keccak256\":\"0x7e1369ca5cb09e818e345a2def19a261401f79c985a6030b55b7311dd6f53be4\",\"license\":\"MIT\"},\"contracts/Dependencies/CheckContract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.6.11;\\n\\n\\ncontract CheckContract {\\n /**\\n * @dev Check that the account is an already deployed non-destroyed contract.\\n * See: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L12\\n */\\n function checkContract(address _account) internal view {\\n require(_account != address(0), \\\"Account cannot be zero address\\\");\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(_account) }\\n require(size > 0, \\\"Account code size cannot be zero\\\");\\n }\\n}\\n\",\"keccak256\":\"0x4c7dc4d0197c27ebc7de671b00458a9ff45f57223aeb520e6ddd2eb6d2d89e5c\",\"license\":\"MIT\"},\"contracts/Dependencies/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.6.11;\\n\\n/**\\n * Based on the OpenZeppelin IER20 interface:\\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol\\n *\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n function increaseAllowance(address spender, uint256 addedValue) external returns (bool);\\n function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n function name() external view returns (string memory);\\n function symbol() external view returns (string memory);\\n function decimals() external view returns (uint8);\\n \\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\",\"keccak256\":\"0xe0b2473eba89df8d27d7cea2a99fce788c212f3fd393c9508e449e51a3f220fa\",\"license\":\"MIT\"},\"contracts/Dependencies/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.6.11;\\n\\n/**\\n * @title Initializable\\n *\\n * Based on OpenZeppelin's Initializable contract:\\n * https://github.com/OpenZeppelin/openzeppelin-upgrades/blob/master/packages/core/contracts/Initializable.sol\\n * \\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(\\n initializing || isConstructor() || !initialized,\\n \\\"Contract instance has already been initialized\\\"\\n );\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n /// @dev Returns true if and only if the function is running in the constructor\\n function isConstructor() private view returns (bool) {\\n // extcodesize checks the size of the code stored in an address, and\\n // address returns the current address. Since the code is still not\\n // deployed when running a constructor, any checks on its code size will\\n // yield zero, making it an effective way to detect if a contract is\\n // under construction or not.\\n address self = address(this);\\n uint256 cs;\\n assembly {\\n cs := extcodesize(self)\\n }\\n return cs == 0;\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\\n\",\"keccak256\":\"0xdb90b797b7b22d58ef72a380c870f3616957f6777ab3d5da48293bd3b935ce68\",\"license\":\"MIT\"},\"contracts/Dependencies/LiquityMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.6.11;\\n\\nimport \\\"./SafeMath.sol\\\";\\nimport \\\"./console.sol\\\";\\n\\nlibrary LiquityMath {\\n using SafeMath for uint;\\n\\n uint internal constant DECIMAL_PRECISION = 1e18;\\n\\n /* Precision for Nominal ICR (independent of price). Rationale for the value:\\n *\\n * - Making it \\u201ctoo high\\u201d could lead to overflows.\\n * - Making it \\u201ctoo low\\u201d could lead to an ICR equal to zero, due to truncation from Solidity floor division. \\n *\\n * This value of 1e20 is chosen for safety: the NICR will only overflow for numerator > ~1e39 ETH,\\n * and will only truncate to 0 if the denominator is at least 1e20 times greater than the numerator.\\n *\\n */\\n uint internal constant NICR_PRECISION = 1e20;\\n\\n function _min(uint _a, uint _b) internal pure returns (uint) {\\n return (_a < _b) ? _a : _b;\\n }\\n\\n function _max(uint _a, uint _b) internal pure returns (uint) {\\n return (_a >= _b) ? _a : _b;\\n }\\n\\n /* \\n * Multiply two decimal numbers and use normal rounding rules:\\n * -round product up if 19'th mantissa digit >= 5\\n * -round product down if 19'th mantissa digit < 5\\n *\\n * Used only inside the exponentiation, _decPow().\\n */\\n function decMul(uint x, uint y) internal pure returns (uint decProd) {\\n uint prod_xy = x.mul(y);\\n\\n decProd = prod_xy.add(DECIMAL_PRECISION / 2).div(DECIMAL_PRECISION);\\n }\\n\\n /* \\n * _decPow: Exponentiation function for 18-digit decimal base, and integer exponent n.\\n * \\n * Uses the efficient \\\"exponentiation by squaring\\\" algorithm. O(log(n)) complexity. \\n * \\n * Called by two functions that represent time in units of minutes:\\n * 1) TroveManager._calcDecayedBaseRate\\n * 2) CommunityIssuance._getCumulativeIssuanceFraction \\n * \\n * The exponent is capped to avoid reverting due to overflow. The cap 525600000 equals\\n * \\\"minutes in 1000 years\\\": 60 * 24 * 365 * 1000\\n * \\n * If a period of > 1000 years is ever used as an exponent in either of the above functions, the result will be\\n * negligibly different from just passing the cap, since: \\n *\\n * In function 1), the decayed base rate will be 0 for 1000 years or > 1000 years\\n * In function 2), the difference in tokens issued at 1000 years and any time > 1000 years, will be negligible\\n */\\n function _decPow(uint _base, uint _minutes) internal pure returns (uint) {\\n \\n if (_minutes > 525600000) {_minutes = 525600000;} // cap to avoid overflow\\n \\n if (_minutes == 0) {return DECIMAL_PRECISION;}\\n\\n uint y = DECIMAL_PRECISION;\\n uint x = _base;\\n uint n = _minutes;\\n\\n // Exponentiation-by-squaring\\n while (n > 1) {\\n if (n % 2 == 0) {\\n x = decMul(x, x);\\n n = n.div(2);\\n } else { // if (n % 2 != 0)\\n y = decMul(x, y);\\n x = decMul(x, x);\\n n = (n.sub(1)).div(2);\\n }\\n }\\n\\n return decMul(x, y);\\n }\\n\\n function _getAbsoluteDifference(uint _a, uint _b) internal pure returns (uint) {\\n return (_a >= _b) ? _a.sub(_b) : _b.sub(_a);\\n }\\n\\n function _computeNominalCR(uint _coll, uint _debt) internal pure returns (uint) {\\n if (_debt > 0) {\\n return _coll.mul(NICR_PRECISION).div(_debt);\\n }\\n // Return the maximal value for uint256 if the Trove has a debt of 0. Represents \\\"infinite\\\" CR.\\n else { // if (_debt == 0)\\n return 2**256 - 1;\\n }\\n }\\n\\n function _computeCR(uint _coll, uint _debt, uint _price) internal pure returns (uint) {\\n if (_debt > 0) {\\n uint newCollRatio = _coll.mul(_price).div(_debt);\\n\\n return newCollRatio;\\n }\\n // Return the maximal value for uint256 if the Trove has a debt of 0. Represents \\\"infinite\\\" CR.\\n else { // if (_debt == 0)\\n return 2**256 - 1; \\n }\\n }\\n}\\n\",\"keccak256\":\"0x7a95ed70d8937e0896c054b433ad0dfc87a9cfd028cae1694098e9d5d68127cd\",\"license\":\"MIT\"},\"contracts/Dependencies/Mynt/IMassetManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.6.11;\\n\\ninterface IMassetManager {\\n struct PermitParams {\\n uint256 deadline;\\n uint8 v;\\n bytes32 r;\\n bytes32 s;\\n }\\n\\n function mintTo(\\n address _bAsset,\\n uint256 _bAssetQuantity,\\n address _recipient\\n ) external returns (uint256);\\n\\n function getToken() external view returns (address);\\n\\n /**\\n * @dev Credits a recipient with a certain quantity of selected bAsset, in exchange for burning the\\n * relative mAsset quantity from the sender. Sender also incurs a small fee, if any.\\n * @param _bAsset Address of the bAsset to redeem.\\n * @param _massetQuantity Units of the masset to redeem.\\n * @param _recipient Address to credit with withdrawn bAssets.\\n * @return massetRedeemed Relative number of mAsset units burned to pay for the bAssets.\\n */\\n function redeemTo(\\n address _bAsset,\\n uint256 _massetQuantity,\\n address _recipient\\n ) external returns (uint256 massetRedeemed);\\n}\\n\",\"keccak256\":\"0x3e8de462d45e8f07ef83b6b6e7eb90a5d09f21d3bcbb1225e8f781488ab4a771\",\"license\":\"MIT\"},\"contracts/Dependencies/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.6.11;\\n\\n/**\\n * Based on OpenZeppelin's Ownable contract:\\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\\n *\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract Ownable {\\n bytes32 private constant KEY_OWNER = keccak256(\\\"key.ownable.owner\\\");\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () internal {\\n _setOwner(msg.sender);\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == getOwner(), \\\"Ownable:: access denied\\\");\\n _;\\n }\\n\\n /**\\n * @notice Set address of the owner.\\n * @param _owner Address of the owner.\\n * */\\n function _setOwner(address _owner) internal {\\n require(_owner != address(0), \\\"Ownable::setOwner: invalid address\\\");\\n emit OwnershipTransferred(getOwner(), _owner);\\n\\n bytes32 key = KEY_OWNER;\\n assembly {\\n sstore(key, _owner)\\n }\\n }\\n\\n /**\\n * @notice Set address of the owner (only owner can call this function)\\n * @param _owner Address of the owner.\\n * */\\n function setOwner(address _owner) public onlyOwner {\\n _setOwner(_owner);\\n }\\n\\n /**\\n * @notice Return address of the owner.\\n * @return _owner Address of the owner.\\n * */\\n function getOwner() public view returns (address _owner) {\\n bytes32 key = KEY_OWNER;\\n assembly {\\n _owner := sload(key)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5fc626e0b227fc0feb1d84440585015a0a5f586547d298534a604dd113efec6\",\"license\":\"MIT\"},\"contracts/Dependencies/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.6.11;\\n\\n/**\\n * Based on OpenZeppelin's SafeMath:\\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol\\n *\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x666b890992a066cc791f36c2975cd595d9761a014c654c385ed36ffaf658f3fd\",\"license\":\"MIT\"},\"contracts/Dependencies/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.6.11;\\n\\n// Buidler's helper contract for console logging\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction log() internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t\\tignored;\\n\\t}\\tfunction logInt(int p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(int)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logUint(uint p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logByte(byte p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(byte)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,uint)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,string,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(uint,address,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t\\tignored;\\n\\t}\\n\\n}\\n\",\"keccak256\":\"0x6fa1de4ffe22b8f58b0b64d65db11dd5037be9b9db47b365a72adb489e217000\",\"license\":\"MIT\"},\"contracts/Interfaces/ICommunityIssuance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.6.11;\\n\\ninterface ICommunityIssuance { \\n \\n // --- Events ---\\n \\n event SOVTokenAddressSet(address _zeroTokenAddress);\\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\\n event StabilityPoolAddressSet(address _stabilityPoolAddress);\\n event PriceFeedAddressSet(address _priceFeed);\\n event RewardManagerAddressSet(address _rewardManagerAddress);\\n event APRSet(uint256 _APR);\\n\\n // --- Functions ---\\n\\n /**\\n * @notice Called only once on init, to set addresses of other contracts. Callable only by owner.\\n * @dev initializer function, checks addresses are contracts\\n * @param _zeroTokenAddress ZEROToken contract address\\n * @param _communityPotAddress CommunityPot contract address\\n */\\n function initialize\\n (\\n address _zeroTokenAddress, \\n address _communityPotAddress,\\n address _fundingWalletAddress\\n ) external;\\n\\n /**\\n * @dev setter function to set the APR value in basis points.\\n * can only be called by reward manager.\\n * @param _APR apr value in basis points.\\n */\\n function setAPR(uint256 _APR) external;\\n\\n /**\\n * @dev setter function to set the price feed.\\n * can only be called by the owner.\\n * @param _priceFeedAddress price feed address.\\n */\\n function setPriceFeed(address _priceFeedAddress) external;\\n\\n /**\\n * @dev setter function to set reward manager.\\n * can only be called by the owner.\\n * @param _rewardManagerAddress reward manager address.\\n */\\n function setRewardManager(address _rewardManagerAddress) external;\\n\\n /// @notice issues SOV tokens based on total zusd is deposited.\\n /// @return SOV tokens issuance \\n function issueSOV(uint256 _totalZUSDDeposits) external returns (uint256);\\n\\n /// @notice sends ZERO tokens to given account\\n /// @param _account account to receive the tokens\\n /// @param _ZEROamount amount of tokens to transfer\\n function sendSOV(address _account, uint _ZEROamount) external;\\n}\\n\",\"keccak256\":\"0xd9a907d2c2bd1909091bde291ab61275e862f28e0278bcc8bc3a7a84e8f28f1b\",\"license\":\"MIT\"},\"contracts/Interfaces/IPriceFeedSovryn.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.6.11;\\n\\ninterface IPriceFeedSovryn {\\n function queryRate(address sourceToken, address destToken)\\n external\\n view\\n returns (uint256 rate, uint256 precision);\\n\\n function queryPrecision(address sourceToken, address destToken)\\n external\\n view\\n returns (uint256 precision);\\n\\n function queryReturn(\\n address sourceToken,\\n address destToken,\\n uint256 sourceAmount\\n ) external view returns (uint256 destAmount);\\n\\n function checkPriceDisagreement(\\n address sourceToken,\\n address destToken,\\n uint256 sourceAmount,\\n uint256 destAmount,\\n uint256 maxSlippage\\n ) external view returns (uint256 sourceToDestSwapRate);\\n\\n function amountInEth(address Token, uint256 amount) external view returns (uint256 ethAmount);\\n\\n function getMaxDrawdown(\\n address loanToken,\\n address collateralToken,\\n uint256 loanAmount,\\n uint256 collateralAmount,\\n uint256 maintenanceMargin\\n ) external view returns (uint256);\\n\\n function getCurrentMarginAndCollateralSize(\\n address loanToken,\\n address collateralToken,\\n uint256 loanAmount,\\n uint256 collateralAmount\\n ) external view returns (uint256 currentMargin, uint256 collateralInEthAmount);\\n\\n function getCurrentMargin(\\n address loanToken,\\n address collateralToken,\\n uint256 loanAmount,\\n uint256 collateralAmount\\n ) external view returns (uint256 currentMargin, uint256 collateralToLoanRate);\\n\\n function shouldLiquidate(\\n address loanToken,\\n address collateralToken,\\n uint256 loanAmount,\\n uint256 collateralAmount,\\n uint256 maintenanceMargin\\n ) external view returns (bool);\\n\\n function getFastGasPrice(address payToken) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xbdcf9310d02366a0b105369169f5488b1dfe705e53176cee0ae9229e3953ef13\",\"license\":\"MIT\"},\"contracts/Interfaces/IStabilityPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.6.11;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../Dependencies/Mynt/IMassetManager.sol\\\";\\n\\n/*\\n * The Stability Pool holds ZUSD tokens deposited by Stability Pool depositors.\\n *\\n * When a trove is liquidated, then depending on system conditions, some of its ZUSD debt gets offset with\\n * ZUSD in the Stability Pool: that is, the offset debt evaporates, and an equal amount of ZUSD tokens in the Stability Pool is burned.\\n *\\n * Thus, a liquidation causes each depositor to receive a ZUSD loss, in proportion to their deposit as a share of total deposits.\\n * They also receive an ETH gain, as the ETH collateral of the liquidated trove is distributed among Stability depositors,\\n * in the same proportion.\\n *\\n * When a liquidation occurs, it depletes every deposit by the same fraction: for example, a liquidation that depletes 40%\\n * of the total ZUSD in the Stability Pool, depletes 40% of each deposit.\\n *\\n * A deposit that has experienced a series of liquidations is termed a \\\"compounded deposit\\\": each liquidation depletes the deposit,\\n * multiplying it by some factor in range ]0,1[\\n *\\n * Please see the implementation spec in the proof document, which closely follows on from the compounded deposit / ETH gain derivations:\\n * https://github.com/liquity/liquity/blob/master/papers/Scalable_Reward_Distribution_with_Compounding_Stakes.pdf\\n *\\n * --- SOV ISSUANCE TO STABILITY POOL DEPOSITORS ---\\n *\\n * An SOV issuance event occurs at every deposit operation, and every liquidation.\\n *\\n * Each deposit is tagged with the address of the front end through which it was made.\\n *\\n * All deposits earn a share of the issued SOV in proportion to the deposit as a share of total deposits. The SOV earned\\n * by a given deposit, is split between the depositor and the front end through which the deposit was made, based on the front end's kickbackRate.\\n *\\n * Please see the system Readme for an overview:\\n * https://github.com/liquity/dev/blob/main/README.md#zero-issuance-to-stability-providers\\n */\\ninterface IStabilityPool {\\n // --- Events ---\\n\\n event StabilityPoolETHBalanceUpdated(uint _newBalance);\\n event StabilityPoolZUSDBalanceUpdated(uint _newBalance);\\n\\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\\n event ActivePoolAddressChanged(address _newActivePoolAddress);\\n event DefaultPoolAddressChanged(address _newDefaultPoolAddress);\\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\\n event SortedTrovesAddressChanged(address _newSortedTrovesAddress);\\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\\n event CommunityIssuanceAddressChanged(address _newCommunityIssuanceAddress);\\n\\n event P_Updated(uint _P);\\n event S_Updated(uint _S, uint128 _epoch, uint128 _scale);\\n event G_Updated(uint _G, uint128 _epoch, uint128 _scale);\\n event EpochUpdated(uint128 _currentEpoch);\\n event ScaleUpdated(uint128 _currentScale);\\n\\n event FrontEndRegistered(address indexed _frontEnd, uint _kickbackRate);\\n event FrontEndTagSet(address indexed _depositor, address indexed _frontEnd);\\n\\n event DepositSnapshotUpdated(address indexed _depositor, uint _P, uint _S, uint _G);\\n event FrontEndSnapshotUpdated(address indexed _frontEnd, uint _P, uint _G);\\n event UserDepositChanged(address indexed _depositor, uint _newDeposit);\\n event FrontEndStakeChanged(\\n address indexed _frontEnd,\\n uint _newFrontEndStake,\\n address _depositor\\n );\\n\\n event ETHGainWithdrawn(address indexed _depositor, uint _ETH, uint _ZUSDLoss);\\n event SOVPaidToDepositor(address indexed _depositor, uint _SOV);\\n event SOVPaidToFrontEnd(address indexed _frontEnd, uint _SOV);\\n event EtherSent(address _to, uint _amount);\\n\\n event WithdrawFromSpAndConvertToDLLR(\\n address _depositor,\\n uint256 _zusdAmountRequested,\\n uint256 _dllrAmountReceived\\n );\\n\\n // --- Functions ---\\n\\n /**\\n * @notice Called only once on init, to set addresses of other Liquity contracts. Callable only by owner\\n * @dev initializer function, checks addresses are contracts\\n * @param _liquityBaseParamsAddress LiquidityBaseParams contract address\\n * @param _borrowerOperationsAddress BorrowerOperations contract address\\n * @param _troveManagerAddress TroveManager contract address\\n * @param _activePoolAddress ActivePool contract address\\n * @param _zusdTokenAddress ZUSDToken contract address\\n * @param _sortedTrovesAddress SortedTroves contract address\\n * @param _priceFeedAddress PriceFeed contract address\\n * @param _communityIssuanceAddress CommunityIssuanceAddress\\n */\\n function setAddresses(\\n address _liquityBaseParamsAddress,\\n address _borrowerOperationsAddress,\\n address _troveManagerAddress,\\n address _activePoolAddress,\\n address _zusdTokenAddress,\\n address _sortedTrovesAddress,\\n address _priceFeedAddress,\\n address _communityIssuanceAddress\\n ) external;\\n\\n /**\\n * @notice Initial checks:\\n * - Frontend is registered or zero address\\n * - Sender is not a registered frontend\\n * - _amount is not zero\\n * ---\\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\\n * - Tags the deposit with the provided front end tag param, if it's a new deposit\\n * - Sends depositor's accumulated gains (SOV, ETH) to depositor\\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\\n * - Increases deposit and tagged front end's stake, and takes new snapshots for each.\\n * @param _amount amount to provide\\n * @param _frontEndTag frontend address to receive accumulated SOV gains\\n */\\n function provideToSP(uint _amount, address _frontEndTag) external;\\n\\n /**\\n * @notice Initial checks:\\n * - _amount is zero or there are no under collateralized troves left in the system\\n * - User has a non zero deposit\\n * ---\\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\\n * - Removes the deposit's front end tag if it is a full withdrawal\\n * - Sends all depositor's accumulated gains (SOV, ETH) to depositor\\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\\n * - Decreases deposit and tagged front end's stake, and takes new snapshots for each.\\n *\\n * If _amount > userDeposit, the user withdraws all of their compounded deposit.\\n * @param _amount amount to withdraw\\n */\\n function withdrawFromSP(uint _amount) external;\\n\\n /**\\n * @notice Initial checks:\\n * - User has a non zero deposit\\n * - User has an open trove\\n * - User has some ETH gain\\n * ---\\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\\n * - Sends all depositor's SOV gain to depositor\\n * - Sends all tagged front end's SOV gain to the tagged front end\\n * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove\\n * - Leaves their compounded deposit in the Stability Pool\\n * - Updates snapshots for deposit and tagged front end stake\\n * @param _upperHint upper trove id hint\\n * @param _lowerHint lower trove id hint\\n */\\n function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external;\\n\\n /**\\n * @notice Initial checks:\\n * - Frontend (sender) not already registered\\n * - User (sender) has no deposit\\n * - _kickbackRate is in the range [0, 100%]\\n * ---\\n * Front end makes a one-time selection of kickback rate upon registering\\n * @param _kickbackRate kickback rate selected by frontend\\n */\\n function registerFrontEnd(uint _kickbackRate) external;\\n\\n /**\\n * @notice Initial checks:\\n * - Caller is TroveManager\\n * ---\\n * Cancels out the specified debt against the ZUSD contained in the Stability Pool (as far as possible)\\n * and transfers the Trove's ETH collateral from ActivePool to StabilityPool.\\n * Only called by liquidation functions in the TroveManager.\\n * @param _debt debt to cancel\\n * @param _coll collateral to transfer\\n */\\n function offset(uint _debt, uint _coll) external;\\n\\n /**\\n * @return the total amount of ETH held by the pool, accounted in an internal variable instead of `balance`,\\n * to exclude edge cases like ETH received from a self-destruct.\\n */\\n function getETH() external view returns (uint);\\n\\n /**\\n * @return ZUSD held in the pool. Changes when users deposit/withdraw, and when Trove debt is offset.\\n */\\n function getTotalZUSDDeposits() external view returns (uint);\\n\\n /**\\n * @notice Calculates the ETH gain earned by the deposit since its last snapshots were taken.\\n * @param _depositor address to calculate ETH gain\\n * @return ETH gain from given depositor\\n */\\n function getDepositorETHGain(address _depositor) external view returns (uint);\\n\\n /**\\n * @notice Calculate the SOV gain earned by a deposit since its last snapshots were taken.\\n * If not tagged with a front end, the depositor gets a 100% cut of what their deposit earned.\\n * Otherwise, their cut of the deposit's earnings is equal to the kickbackRate, set by the front end through\\n * which they made their deposit.\\n * @param _depositor address to calculate ETH gain\\n * @return SOV gain from given depositor\\n */\\n function getDepositorSOVGain(address _depositor) external view returns (uint);\\n\\n /**\\n * @param _frontEnd front end address\\n * @return the SOV gain earned by the front end.\\n */\\n function getFrontEndSOVGain(address _frontEnd) external view returns (uint);\\n\\n /**\\n * @param _depositor depositor address\\n * @return the user's compounded deposit.\\n */\\n function getCompoundedZUSDDeposit(address _depositor) external view returns (uint);\\n\\n /**\\n * @notice The front end's compounded stake is equal to the sum of its depositors' compounded deposits.\\n * @param _frontEnd front end address\\n * @return the front end's compounded stake.\\n */\\n function getCompoundedFrontEndStake(address _frontEnd) external view returns (uint);\\n\\n //DLLR _owner or _spender can convert a specified amount of DLLR into ZUSD via Sovryn Mynt and deposit the ZUSD into the SOV Stability Pool, all in a single transaction\\n function provideToSpFromDLLR(\\n uint _dllrAmount,\\n IMassetManager.PermitParams calldata _permitParams\\n ) external;\\n\\n /// Stability Pool depositor can withdraw a specified amount of ZUSD from the SOV Stability Pool and optionally convert the ZUSD to DLLR via Sovryn Mynt, all in a single transaction\\n function withdrawFromSpAndConvertToDLLR(uint256 _zusdAmount) external;\\n\\n /**\\n * Fallback function\\n * Only callable by Active Pool, it just accounts for ETH received\\n * receive() external payable;\\n */\\n}\\n\",\"keccak256\":\"0x4c43dadc5e4a892a77a8374fcb9e66719bd5939b3b0880ad07d02f6cefdbe1e7\",\"license\":\"MIT\"},\"contracts/ZERO/CommunityIssuance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.6.11;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../Interfaces/ICommunityIssuance.sol\\\";\\nimport \\\"../Dependencies/BaseMath.sol\\\";\\nimport \\\"../Dependencies/LiquityMath.sol\\\";\\nimport \\\"../Dependencies/Ownable.sol\\\";\\nimport \\\"../Dependencies/CheckContract.sol\\\";\\nimport \\\"../Dependencies/SafeMath.sol\\\";\\nimport \\\"./CommunityIssuanceStorage.sol\\\";\\nimport \\\"../Interfaces/IStabilityPool.sol\\\";\\n\\ncontract CommunityIssuance is\\n CommunityIssuanceStorage,\\n CheckContract,\\n BaseMath\\n{\\n using SafeMath for uint256;\\n\\n // --- Events ---\\n\\n event SOVTokenAddressSet(address _sovTokenAddress);\\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\\n event StabilityPoolAddressSet(address _stabilityPoolAddress);\\n event PriceFeedAddressSet(address _priceFeed);\\n event RewardManagerAddressSet(address _rewardManagerAddress);\\n event TotalSOVIssuedUpdated(uint256 _latestSOVIssued);\\n event APRSet(uint256 _APR);\\n\\n // --- Modifier ---\\n modifier onlyRewardManager() {\\n require(msg.sender == rewardManager, \\\"Permission::rewardManager: access denied\\\");\\n _;\\n }\\n\\n // --- Functions ---\\n\\n /**\\n * @dev initialization function to set configs.\\n * can only be initialized by owner.\\n * @param _sovTokenAddress sov token address.\\n * @param _zusdTokenAddress zero token address.\\n * @param _stabilityPoolAddress stability pool address.\\n * @param _priceFeed price feed address.\\n * @param _APR apr in basis points.\\n */\\n function initialize(\\n address _sovTokenAddress,\\n address _zusdTokenAddress,\\n address _stabilityPoolAddress,\\n address _priceFeed,\\n uint256 _APR\\n ) external initializer onlyOwner {\\n checkContract(_sovTokenAddress);\\n checkContract(_zusdTokenAddress);\\n checkContract(_stabilityPoolAddress);\\n checkContract(_priceFeed);\\n\\n _validateAPR(_APR);\\n\\n sovToken = IERC20(_sovTokenAddress);\\n zusdToken = IERC20(_zusdTokenAddress);\\n stabilityPoolAddress = _stabilityPoolAddress;\\n priceFeed = IPriceFeedSovryn(_priceFeed);\\n APR = _APR;\\n lastIssuanceTime = block.timestamp;\\n\\n emit SOVTokenAddressSet(_sovTokenAddress);\\n emit StabilityPoolAddressSet(_stabilityPoolAddress);\\n emit PriceFeedAddressSet(_priceFeed);\\n emit APRSet(_APR);\\n }\\n\\n /**\\n * @dev setter function to set the APR value in basis points.\\n * can only be called by reward manager.\\n * @param _APR apr value in basis points.\\n */\\n function setAPR(uint256 _APR) external onlyRewardManager {\\n _validateAPR(_APR);\\n\\n // We need to trigger issueSOV function before set the new APR\\n // because otherwise, we will change the APR retrospectively for the time passed since last issuance.\\n uint256 _totalZUSDDeposits = IStabilityPool(stabilityPoolAddress).getTotalZUSDDeposits();\\n _issueSOV(_totalZUSDDeposits);\\n\\n APR = _APR;\\n\\n emit APRSet(_APR);\\n }\\n\\n /**\\n * @dev setter function to set the price feed.\\n * can only be called by the owner.\\n * @param _priceFeedAddress price feed address.\\n */\\n function setPriceFeed(address _priceFeedAddress) external onlyOwner {\\n checkContract(_priceFeedAddress);\\n\\n priceFeed = IPriceFeedSovryn(_priceFeedAddress);\\n\\n emit PriceFeedAddressSet(_priceFeedAddress);\\n }\\n\\n /**\\n * @dev setter function to set reward manager.\\n * can only be called by the owner.\\n * @param _rewardManagerAddress reward manager address.\\n */\\n function setRewardManager(address _rewardManagerAddress) external onlyOwner {\\n require(_rewardManagerAddress != address(0), \\\"Account cannot be zero address\\\");\\n\\n rewardManager = _rewardManagerAddress;\\n\\n emit RewardManagerAddressSet(_rewardManagerAddress);\\n }\\n\\n /**\\n * @dev validate the APR value.\\n * the value must be >= 0 <= MAX_BPS (10000)\\n */\\n function _validateAPR(uint256 _APR) private {\\n require(_APR <= MAX_BPS, \\\"APR must be less than 10000\\\");\\n }\\n\\n\\n function issueSOV(uint256 _totalZUSDDeposits) public returns (uint256) {\\n _requireCallerIsStabilityPool();\\n\\n return _issueSOV(_totalZUSDDeposits);\\n }\\n\\n function _issueSOV(uint256 _totalZUSDDeposits) private returns (uint256) {\\n uint256 timePassedSinceLastIssuance = (block.timestamp.sub(lastIssuanceTime));\\n uint256 issuance = _ZUSDToSOV(_totalZUSDDeposits.mul(APR).div(MAX_BPS).mul(timePassedSinceLastIssuance).div(365 days));\\n\\n totalSOVIssued = totalSOVIssued + issuance;\\n lastIssuanceTime = block.timestamp;\\n emit TotalSOVIssuedUpdated(totalSOVIssued);\\n\\n return issuance;\\n }\\n\\n function sendSOV(address _account, uint256 _SOVamount) public {\\n _requireCallerIsStabilityPool();\\n\\n bool success = sovToken.transfer(_account, _SOVamount);\\n require(success, \\\"Failed to send ZERO\\\");\\n }\\n\\n function _requireCallerIsStabilityPool() internal view {\\n require(msg.sender == stabilityPoolAddress, \\\"CommunityIssuance: caller is not SP\\\");\\n }\\n\\n /**\\n * @dev get the ZUSD to SOV rate conversion. Mostly will be using Sovryn's PriceFeed.\\n * @param _zusdAmount zusd amount to get the rate conversion\\n * @return the total SOV will be returned.\\n */\\n function _ZUSDToSOV(uint256 _zusdAmount) internal view returns (uint256) {\\n return priceFeed.queryReturn(address(zusdToken), address(sovToken), _zusdAmount);\\n }\\n}\\n\",\"keccak256\":\"0x85b3720a8bbd0cb6cbc500abf6e4b571565f4d9d369f77b9ae745e9b16520709\",\"license\":\"MIT\"},\"contracts/ZERO/CommunityIssuanceStorage.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.6.11;\\n\\nimport \\\"../Dependencies/Ownable.sol\\\";\\nimport \\\"../Dependencies/IERC20.sol\\\";\\nimport \\\"../Interfaces/IPriceFeedSovryn.sol\\\";\\nimport \\\"../Dependencies/Initializable.sol\\\";\\n\\ncontract CommunityIssuanceStorage is Ownable, Initializable {\\n // --- Data ---\\n\\n string constant public NAME = \\\"CommunityIssuance\\\";\\n\\n uint256 constant MAX_BPS = 10000;\\n\\n IERC20 public sovToken;\\n\\n IERC20 public zusdToken;\\n\\n address public stabilityPoolAddress;\\n\\n uint256 public totalSOVIssued;\\n\\n uint256 public lastIssuanceTime;\\n\\n uint256 public APR; //in basis points\\n\\n address public rewardManager;\\n\\n IPriceFeedSovryn public priceFeed;\\n}\\n\",\"keccak256\":\"0x686d3560df0bb371f5e808695ebebcfea39f344e0eda142b6e932a84113ddf0f\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610143565b6001600160a01b0381166100575760405162461bcd60e51b815260040161004e90610101565b60405180910390fd5b6001600160a01b0381166100726001600160e01b036100c516565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360006040516100b5906100e4565b6040519081900390209190915550565b6000806040516100d4906100e4565b6040519081900390205492915050565b7035b2bc9737bbb730b136329737bbb732b960791b815260110190565b60208082526022908201527f4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265604082015261737360f01b606082015260800190565b611042806101526000396000f3fe608060405234801561001057600080fd5b50600436106100f65760003560e01c8063893d20e811610092578063893d20e81461019f57806398afd294146101a7578063a20baee6146101af578063a3f4df7e146101b7578063ae601ac1146101cc578063bd30558e146101d4578063ec9f7d46146101dc578063f7013ef6146101e4578063f8c1dc6c146101f7576100f6565b80630b622ab2146100fb5780630f4ef8a61461011957806313af403514610121578063153ee5541461013657806360bf03ff146101495780636cbdcf471461015e578063724e78da14610171578063741bef1a14610184578063854303cf1461018c575b600080fd5b61010361020a565b6040516101109190610ced565b60405180910390f35b610103610219565b61013461012f366004610bd8565b610228565b005b610134610144366004610bd8565b610275565b610151610329565b6040516101109190610fee565b61015161016c366004610ca0565b61032f565b61013461017f366004610bd8565b610348565b6101036103d4565b61013461019a366004610ca0565b6103e3565b6101036104e0565b6101036104ff565b61015161050e565b6101bf61051a565b6040516101109190610d3e565b610151610547565b61015161054d565b610103610553565b6101346101f2366004610bf3565b610562565b610134610205366004610c56565b61077f565b6035546001600160a01b031681565b6039546001600160a01b031681565b6102306104e0565b6001600160a01b0316336001600160a01b0316146102695760405162461bcd60e51b815260040161026090610f45565b60405180910390fd5b61027281610830565b50565b61027d6104e0565b6001600160a01b0316336001600160a01b0316146102ad5760405162461bcd60e51b815260040161026090610f45565b6001600160a01b0381166102d35760405162461bcd60e51b815260040161026090610e7f565b603980546001600160a01b0319166001600160a01b0383161790556040517f1c7e8eeb20c95a47700378fd4dd1a7fe13a6f508d25615c5fb1f3d1099051daa9061031e908390610ced565b60405180910390a150565b60375481565b60006103396108bb565b610342826108e7565b92915050565b6103506104e0565b6001600160a01b0316336001600160a01b0316146103805760405162461bcd60e51b815260040161026090610f45565b61038981610999565b603a80546001600160a01b0319166001600160a01b0383161790556040517facd42642b5cb91804117282727eb92664d362985a4f353ccd03833d3049d16d99061031e908390610ced565b603a546001600160a01b031681565b6039546001600160a01b0316331461040d5760405162461bcd60e51b815260040161026090610dc8565b610416816109e2565b60355460408051635ed79bf560e11b815290516000926001600160a01b03169163bdaf37ea916004808301926020929190829003018186803b15801561045b57600080fd5b505afa15801561046f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104939190610cb8565b905061049e816108e7565b5060388290556040517fd6b99165a8b6705d5dbba79fccdcac9b98141cb0f6413824ebd39fdfbe611ba6906104d4908490610fee565b60405180910390a15050565b6000806040516104ef90610cd0565b6040519081900390205492915050565b6033546001600160a01b031681565b670de0b6b3a764000081565b60405180604001604052806011815260200170436f6d6d756e69747949737375616e636560781b81525081565b60365481565b60385481565b6034546001600160a01b031681565b600054610100900460ff168061057b575061057b610a04565b80610589575060005460ff16155b6105a55760405162461bcd60e51b815260040161026090610ef7565b600054610100900460ff161580156105d0576000805460ff1961ff0019909116610100171660011790555b6105d86104e0565b6001600160a01b0316336001600160a01b0316146106085760405162461bcd60e51b815260040161026090610f45565b61061186610999565b61061a85610999565b61062384610999565b61062c83610999565b610635826109e2565b603380546001600160a01b038089166001600160a01b0319928316179092556034805488841690831617905560358054878416908316179055603a8054928616929091169190911790556038829055426037556040517f5bce47da81ad81a6d5745ec7a1790bd9213dc36898110fd3681b037768a2b3c6906106b8908890610ced565b60405180910390a17f45c53611bc8ba9e11f4f8173bda9e3faf89c395ddb83f9a55230b156828db315846040516106ef9190610ced565b60405180910390a17facd42642b5cb91804117282727eb92664d362985a4f353ccd03833d3049d16d9836040516107269190610ced565b60405180910390a17fd6b99165a8b6705d5dbba79fccdcac9b98141cb0f6413824ebd39fdfbe611ba68260405161075d9190610fee565b60405180910390a18015610777576000805461ff00191690555b505050505050565b6107876108bb565b60335460405163a9059cbb60e01b81526000916001600160a01b03169063a9059cbb906107ba9086908690600401610d25565b602060405180830381600087803b1580156107d457600080fd5b505af11580156107e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080c9190610c80565b90508061082b5760405162461bcd60e51b815260040161026090610e10565b505050565b6001600160a01b0381166108565760405162461bcd60e51b815260040161026090610e3d565b806001600160a01b03166108686104e0565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360006040516108ab90610cd0565b6040519081900390209190915550565b6035546001600160a01b031633146108e55760405162461bcd60e51b815260040161026090610f76565b565b6000806108ff60375442610a0a90919063ffffffff16565b9050600061094a6109456301e1338061092d8561093961271061092d6038548c610a5390919063ffffffff16565b9063ffffffff610a8d16565b9063ffffffff610a5316565b610acf565b60368054820190819055426037556040519192507f47eb3c2a573d55ee40451cdc91a92eb7fe3dd8bcdb4d19c9acd32ecaa29f2d559161098a9190610fee565b60405180910390a19392505050565b6001600160a01b0381166109bf5760405162461bcd60e51b815260040161026090610e7f565b803b806109de5760405162461bcd60e51b815260040161026090610fb9565b5050565b6127108111156102725760405162461bcd60e51b815260040161026090610d91565b303b1590565b6000610a4c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610b5e565b9392505050565b600082610a6257506000610342565b82820282848281610a6f57fe5b0414610a4c5760405162461bcd60e51b815260040161026090610eb6565b6000610a4c83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610b8a565b603a5460345460335460405163d138f9a160e01b81526000936001600160a01b039081169363d138f9a193610b0e939183169216908790600401610d01565b60206040518083038186803b158015610b2657600080fd5b505afa158015610b3a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103429190610cb8565b60008184841115610b825760405162461bcd60e51b81526004016102609190610d3e565b505050900390565b60008183610bab5760405162461bcd60e51b81526004016102609190610d3e565b506000838581610bb757fe5b0495945050505050565b80356001600160a01b038116811461034257600080fd5b600060208284031215610be9578081fd5b610a4c8383610bc1565b600080600080600060a08688031215610c0a578081fd5b8535610c1581610ff7565b94506020860135610c2581610ff7565b93506040860135610c3581610ff7565b92506060860135610c4581610ff7565b949793965091946080013592915050565b60008060408385031215610c68578182fd5b610c728484610bc1565b946020939093013593505050565b600060208284031215610c91578081fd5b81518015158114610a4c578182fd5b600060208284031215610cb1578081fd5b5035919050565b600060208284031215610cc9578081fd5b5051919050565b7035b2bc9737bbb730b136329737bbb732b960791b815260110190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602080835283518082850152825b81811015610d6a57858101830151858201604001528201610d4e565b81811115610d7b5783604083870101525b50601f01601f1916929092016040019392505050565b6020808252601b908201527f415052206d757374206265206c657373207468616e2031303030300000000000604082015260600190565b60208082526028908201527f5065726d697373696f6e3a3a7265776172644d616e616765723a2061636365736040820152671cc819195b9a595960c21b606082015260800190565b6020808252601390820152724661696c656420746f2073656e64205a45524f60681b604082015260600190565b60208082526022908201527f4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265604082015261737360f01b606082015260800190565b6020808252601e908201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526017908201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604082015260600190565b60208082526023908201527f436f6d6d756e69747949737375616e63653a2063616c6c6572206973206e6f7460408201526202053560ec1b606082015260800190565b6020808252818101527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604082015260600190565b90815260200190565b6001600160a01b038116811461027257600080fdfea264697066735822122051b903c2ec1e851a057918eeb01dc6764d14b46ee244b0a35c68f6dc52321c3a64736f6c634300060b0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100f65760003560e01c8063893d20e811610092578063893d20e81461019f57806398afd294146101a7578063a20baee6146101af578063a3f4df7e146101b7578063ae601ac1146101cc578063bd30558e146101d4578063ec9f7d46146101dc578063f7013ef6146101e4578063f8c1dc6c146101f7576100f6565b80630b622ab2146100fb5780630f4ef8a61461011957806313af403514610121578063153ee5541461013657806360bf03ff146101495780636cbdcf471461015e578063724e78da14610171578063741bef1a14610184578063854303cf1461018c575b600080fd5b61010361020a565b6040516101109190610ced565b60405180910390f35b610103610219565b61013461012f366004610bd8565b610228565b005b610134610144366004610bd8565b610275565b610151610329565b6040516101109190610fee565b61015161016c366004610ca0565b61032f565b61013461017f366004610bd8565b610348565b6101036103d4565b61013461019a366004610ca0565b6103e3565b6101036104e0565b6101036104ff565b61015161050e565b6101bf61051a565b6040516101109190610d3e565b610151610547565b61015161054d565b610103610553565b6101346101f2366004610bf3565b610562565b610134610205366004610c56565b61077f565b6035546001600160a01b031681565b6039546001600160a01b031681565b6102306104e0565b6001600160a01b0316336001600160a01b0316146102695760405162461bcd60e51b815260040161026090610f45565b60405180910390fd5b61027281610830565b50565b61027d6104e0565b6001600160a01b0316336001600160a01b0316146102ad5760405162461bcd60e51b815260040161026090610f45565b6001600160a01b0381166102d35760405162461bcd60e51b815260040161026090610e7f565b603980546001600160a01b0319166001600160a01b0383161790556040517f1c7e8eeb20c95a47700378fd4dd1a7fe13a6f508d25615c5fb1f3d1099051daa9061031e908390610ced565b60405180910390a150565b60375481565b60006103396108bb565b610342826108e7565b92915050565b6103506104e0565b6001600160a01b0316336001600160a01b0316146103805760405162461bcd60e51b815260040161026090610f45565b61038981610999565b603a80546001600160a01b0319166001600160a01b0383161790556040517facd42642b5cb91804117282727eb92664d362985a4f353ccd03833d3049d16d99061031e908390610ced565b603a546001600160a01b031681565b6039546001600160a01b0316331461040d5760405162461bcd60e51b815260040161026090610dc8565b610416816109e2565b60355460408051635ed79bf560e11b815290516000926001600160a01b03169163bdaf37ea916004808301926020929190829003018186803b15801561045b57600080fd5b505afa15801561046f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104939190610cb8565b905061049e816108e7565b5060388290556040517fd6b99165a8b6705d5dbba79fccdcac9b98141cb0f6413824ebd39fdfbe611ba6906104d4908490610fee565b60405180910390a15050565b6000806040516104ef90610cd0565b6040519081900390205492915050565b6033546001600160a01b031681565b670de0b6b3a764000081565b60405180604001604052806011815260200170436f6d6d756e69747949737375616e636560781b81525081565b60365481565b60385481565b6034546001600160a01b031681565b600054610100900460ff168061057b575061057b610a04565b80610589575060005460ff16155b6105a55760405162461bcd60e51b815260040161026090610ef7565b600054610100900460ff161580156105d0576000805460ff1961ff0019909116610100171660011790555b6105d86104e0565b6001600160a01b0316336001600160a01b0316146106085760405162461bcd60e51b815260040161026090610f45565b61061186610999565b61061a85610999565b61062384610999565b61062c83610999565b610635826109e2565b603380546001600160a01b038089166001600160a01b0319928316179092556034805488841690831617905560358054878416908316179055603a8054928616929091169190911790556038829055426037556040517f5bce47da81ad81a6d5745ec7a1790bd9213dc36898110fd3681b037768a2b3c6906106b8908890610ced565b60405180910390a17f45c53611bc8ba9e11f4f8173bda9e3faf89c395ddb83f9a55230b156828db315846040516106ef9190610ced565b60405180910390a17facd42642b5cb91804117282727eb92664d362985a4f353ccd03833d3049d16d9836040516107269190610ced565b60405180910390a17fd6b99165a8b6705d5dbba79fccdcac9b98141cb0f6413824ebd39fdfbe611ba68260405161075d9190610fee565b60405180910390a18015610777576000805461ff00191690555b505050505050565b6107876108bb565b60335460405163a9059cbb60e01b81526000916001600160a01b03169063a9059cbb906107ba9086908690600401610d25565b602060405180830381600087803b1580156107d457600080fd5b505af11580156107e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080c9190610c80565b90508061082b5760405162461bcd60e51b815260040161026090610e10565b505050565b6001600160a01b0381166108565760405162461bcd60e51b815260040161026090610e3d565b806001600160a01b03166108686104e0565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360006040516108ab90610cd0565b6040519081900390209190915550565b6035546001600160a01b031633146108e55760405162461bcd60e51b815260040161026090610f76565b565b6000806108ff60375442610a0a90919063ffffffff16565b9050600061094a6109456301e1338061092d8561093961271061092d6038548c610a5390919063ffffffff16565b9063ffffffff610a8d16565b9063ffffffff610a5316565b610acf565b60368054820190819055426037556040519192507f47eb3c2a573d55ee40451cdc91a92eb7fe3dd8bcdb4d19c9acd32ecaa29f2d559161098a9190610fee565b60405180910390a19392505050565b6001600160a01b0381166109bf5760405162461bcd60e51b815260040161026090610e7f565b803b806109de5760405162461bcd60e51b815260040161026090610fb9565b5050565b6127108111156102725760405162461bcd60e51b815260040161026090610d91565b303b1590565b6000610a4c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610b5e565b9392505050565b600082610a6257506000610342565b82820282848281610a6f57fe5b0414610a4c5760405162461bcd60e51b815260040161026090610eb6565b6000610a4c83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610b8a565b603a5460345460335460405163d138f9a160e01b81526000936001600160a01b039081169363d138f9a193610b0e939183169216908790600401610d01565b60206040518083038186803b158015610b2657600080fd5b505afa158015610b3a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103429190610cb8565b60008184841115610b825760405162461bcd60e51b81526004016102609190610d3e565b505050900390565b60008183610bab5760405162461bcd60e51b81526004016102609190610d3e565b506000838581610bb757fe5b0495945050505050565b80356001600160a01b038116811461034257600080fd5b600060208284031215610be9578081fd5b610a4c8383610bc1565b600080600080600060a08688031215610c0a578081fd5b8535610c1581610ff7565b94506020860135610c2581610ff7565b93506040860135610c3581610ff7565b92506060860135610c4581610ff7565b949793965091946080013592915050565b60008060408385031215610c68578182fd5b610c728484610bc1565b946020939093013593505050565b600060208284031215610c91578081fd5b81518015158114610a4c578182fd5b600060208284031215610cb1578081fd5b5035919050565b600060208284031215610cc9578081fd5b5051919050565b7035b2bc9737bbb730b136329737bbb732b960791b815260110190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602080835283518082850152825b81811015610d6a57858101830151858201604001528201610d4e565b81811115610d7b5783604083870101525b50601f01601f1916929092016040019392505050565b6020808252601b908201527f415052206d757374206265206c657373207468616e2031303030300000000000604082015260600190565b60208082526028908201527f5065726d697373696f6e3a3a7265776172644d616e616765723a2061636365736040820152671cc819195b9a595960c21b606082015260800190565b6020808252601390820152724661696c656420746f2073656e64205a45524f60681b604082015260600190565b60208082526022908201527f4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265604082015261737360f01b606082015260800190565b6020808252601e908201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526017908201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604082015260600190565b60208082526023908201527f436f6d6d756e69747949737375616e63653a2063616c6c6572206973206e6f7460408201526202053560ec1b606082015260800190565b6020808252818101527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604082015260600190565b90815260200190565b6001600160a01b038116811461027257600080fdfea264697066735822122051b903c2ec1e851a057918eeb01dc6764d14b46ee244b0a35c68f6dc52321c3a64736f6c634300060b0033", + "devdoc": { + "kind": "dev", + "methods": { + "getOwner()": { + "returns": { + "_owner": "Address of the owner. " + } + }, + "initialize(address,address,address,address,uint256)": { + "details": "initialization function to set configs. can only be initialized by owner.", + "params": { + "_APR": "apr in basis points.", + "_priceFeed": "price feed address.", + "_sovTokenAddress": "sov token address.", + "_stabilityPoolAddress": "stability pool address.", + "_zusdTokenAddress": "zero token address." + } + }, + "setAPR(uint256)": { + "details": "setter function to set the APR value in basis points. can only be called by reward manager.", + "params": { + "_APR": "apr value in basis points." + } + }, + "setOwner(address)": { + "params": { + "_owner": "Address of the owner. " + } + }, + "setPriceFeed(address)": { + "details": "setter function to set the price feed. can only be called by the owner.", + "params": { + "_priceFeedAddress": "price feed address." + } + }, + "setRewardManager(address)": { + "details": "setter function to set reward manager. can only be called by the owner.", + "params": { + "_rewardManagerAddress": "reward manager address." + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "getOwner()": { + "notice": "Return address of the owner." + }, + "setOwner(address)": { + "notice": "Set address of the owner (only owner can call this function)" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 5125, + "contract": "contracts/ZERO/CommunityIssuance.sol:CommunityIssuance", + "label": "initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 5128, + "contract": "contracts/ZERO/CommunityIssuance.sol:CommunityIssuance", + "label": "initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 5193, + "contract": "contracts/ZERO/CommunityIssuance.sol:CommunityIssuance", + "label": "______gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 33984, + "contract": "contracts/ZERO/CommunityIssuance.sol:CommunityIssuance", + "label": "sovToken", + "offset": 0, + "slot": "51", + "type": "t_contract(IERC20)5074" + }, + { + "astId": 33986, + "contract": "contracts/ZERO/CommunityIssuance.sol:CommunityIssuance", + "label": "zusdToken", + "offset": 0, + "slot": "52", + "type": "t_contract(IERC20)5074" + }, + { + "astId": 33988, + "contract": "contracts/ZERO/CommunityIssuance.sol:CommunityIssuance", + "label": "stabilityPoolAddress", + "offset": 0, + "slot": "53", + "type": "t_address" + }, + { + "astId": 33990, + "contract": "contracts/ZERO/CommunityIssuance.sol:CommunityIssuance", + "label": "totalSOVIssued", + "offset": 0, + "slot": "54", + "type": "t_uint256" + }, + { + "astId": 33992, + "contract": "contracts/ZERO/CommunityIssuance.sol:CommunityIssuance", + "label": "lastIssuanceTime", + "offset": 0, + "slot": "55", + "type": "t_uint256" + }, + { + "astId": 33994, + "contract": "contracts/ZERO/CommunityIssuance.sol:CommunityIssuance", + "label": "APR", + "offset": 0, + "slot": "56", + "type": "t_uint256" + }, + { + "astId": 33996, + "contract": "contracts/ZERO/CommunityIssuance.sol:CommunityIssuance", + "label": "rewardManager", + "offset": 0, + "slot": "57", + "type": "t_address" + }, + { + "astId": 33998, + "contract": "contracts/ZERO/CommunityIssuance.sol:CommunityIssuance", + "label": "priceFeed", + "offset": 0, + "slot": "58", + "type": "t_contract(IPriceFeedSovryn)19883" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(IERC20)5074": { + "encoding": "inplace", + "label": "contract IERC20", + "numberOfBytes": "20" + }, + "t_contract(IPriceFeedSovryn)19883": { + "encoding": "inplace", + "label": "contract IPriceFeedSovryn", + "numberOfBytes": "20" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/CommunityIssuance_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/CommunityIssuance_Proxy.json new file mode 100644 index 00000000..cc58443f --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/CommunityIssuance_Proxy.json @@ -0,0 +1,191 @@ +{ + "address": "0xD017396d2284699e0Ce34b236CcE5321Ee3078e5", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x2eddbf737a352003b61b42413520ea7bd2ccb7468a01eb0a26467e6fe3422d77", + "receipt": { + "to": null, + "from": "0xCF311E7375083b9513566a47B9f3e93F1FcdCfBF", + "contractAddress": "0xD017396d2284699e0Ce34b236CcE5321Ee3078e5", + "transactionIndex": 0, + "gasUsed": "421195", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000200000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000002000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000100000000000000000000", + "blockHash": "0x68222c5340cf45e308080b27ca75ea11724608057bd388dad06d8212cd5562be", + "transactionHash": "0x2eddbf737a352003b61b42413520ea7bd2ccb7468a01eb0a26467e6fe3422d77", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 3773192, + "transactionHash": "0x2eddbf737a352003b61b42413520ea7bd2ccb7468a01eb0a26467e6fe3422d77", + "address": "0xD017396d2284699e0Ce34b236CcE5321Ee3078e5", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cf311e7375083b9513566a47b9f3e93f1fcdcfbf" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x68222c5340cf45e308080b27ca75ea11724608057bd388dad06d8212cd5562be" + } + ], + "blockNumber": 3773192, + "cumulativeGasUsed": "421195", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "754dff2eec82e13c98a907fdc90582aa", + "metadata": "{\"compiler\":{\"version\":\"0.6.11+commit.5ef660b1\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_oldImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newImplementation\",\"type\":\"address\"}],\"name\":\"ImplementationChanged\",\"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\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"getImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"setImplementation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getImplementation()\":{\"returns\":{\"_implementation\":\"Address of the implementation. \"}},\"getOwner()\":{\"returns\":{\"_owner\":\"Address of the owner. \"}},\"setImplementation(address)\":{\"details\":\"Wrapper for _setImplementation that exposes the function as public for owner to be able to set a new version of the contract as current pointing implementation.\",\"params\":{\"_implementation\":\"Address of the implementation. \"}},\"setOwner(address)\":{\"params\":{\"_owner\":\"Address of the owner. \"}}},\"title\":\"Upgradable Proxy contract. Adapted version of https://github.com/DistributedCollective/Sovryn-smart-contracts/blob/development/contracts/proxy/UpgradableProxy.sol \",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getImplementation()\":{\"notice\":\"Return address of the implementation.\"},\"getOwner()\":{\"notice\":\"Return address of the owner.\"},\"setImplementation(address)\":{\"notice\":\"Set address of the implementation.\"},\"setOwner(address)\":{\"notice\":\"Set address of the owner (only owner can call this function)\"}},\"notice\":\"A disadvantage of the immutable ledger is that nobody can change the source code of a smart contract after it\\u2019s been deployed. In order to fix bugs or introduce new features, smart contracts need to be upgradable somehow. Although it is not possible to upgrade the code of an already deployed smart contract, it is possible to set-up a proxy contract architecture that will allow to use new deployed contracts as if the main logic had been upgraded. A proxy architecture pattern is such that all message calls go through a Proxy contract that will redirect them to the latest deployed contract logic. To upgrade, a new version of the contract is deployed, and the Proxy is updated to reference the new contract address. \",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Proxy/UpgradableProxy.sol\":\"UpgradableProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"contracts/Dependencies/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.6.11;\\n\\n/**\\n * Based on OpenZeppelin's Ownable contract:\\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\\n *\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\ncontract Ownable {\\n bytes32 private constant KEY_OWNER = keccak256(\\\"key.ownable.owner\\\");\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () internal {\\n _setOwner(msg.sender);\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == getOwner(), \\\"Ownable:: access denied\\\");\\n _;\\n }\\n\\n /**\\n * @notice Set address of the owner.\\n * @param _owner Address of the owner.\\n * */\\n function _setOwner(address _owner) internal {\\n require(_owner != address(0), \\\"Ownable::setOwner: invalid address\\\");\\n emit OwnershipTransferred(getOwner(), _owner);\\n\\n bytes32 key = KEY_OWNER;\\n assembly {\\n sstore(key, _owner)\\n }\\n }\\n\\n /**\\n * @notice Set address of the owner (only owner can call this function)\\n * @param _owner Address of the owner.\\n * */\\n function setOwner(address _owner) public onlyOwner {\\n _setOwner(_owner);\\n }\\n\\n /**\\n * @notice Return address of the owner.\\n * @return _owner Address of the owner.\\n * */\\n function getOwner() public view returns (address _owner) {\\n bytes32 key = KEY_OWNER;\\n assembly {\\n _owner := sload(key)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5fc626e0b227fc0feb1d84440585015a0a5f586547d298534a604dd113efec6\",\"license\":\"MIT\"},\"contracts/Proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.6.11;\\n\\nimport \\\"../Dependencies/Ownable.sol\\\";\\n/**\\n * @title Base Proxy contract.\\n * \\n * Adapted version of https://github.com/DistributedCollective/Sovryn-smart-contracts/blob/development/contracts/proxy/Proxy.sol \\n *\\n * @notice The proxy performs delegated calls to the contract implementation\\n * it is pointing to. This way upgradable contracts are possible on blockchain.\\n *\\n * Delegating proxy contracts are widely used for both upgradeability and gas\\n * savings. These proxies rely on a logic contract (also known as implementation\\n * contract or master copy) that is called using delegatecall. This allows\\n * proxies to keep a persistent state (storage and balance) while the code is\\n * delegated to the logic contract.\\n *\\n * Proxy contract is meant to be inherited and its internal functions\\n * _setImplementation and _setOwner to be called when upgrades become\\n * neccessary.\\n *\\n * The loan token (iToken) contract as well as the protocol contract act as\\n * proxies, delegating all calls to underlying contracts. Therefore, if you\\n * want to interact with them using web3, you need to use the ABIs from the\\n * contracts containing the actual logic or the interface contract.\\n * ABI for LoanToken contracts: LoanTokenLogicStandard\\n * ABI for Protocol contract: ISovryn\\n *\\n * @dev UpgradableProxy is the contract that inherits Proxy and wraps these\\n * functions.\\n * */\\ncontract Proxy is Ownable {\\n bytes32 private constant KEY_IMPLEMENTATION = keccak256(\\\"key.implementation\\\");\\n\\n event ImplementationChanged(\\n address indexed _oldImplementation,\\n address indexed _newImplementation\\n );\\n\\n /**\\n * @notice Set address of the implementation.\\n * @param _implementation Address of the implementation.\\n * */\\n function _setImplementation(address _implementation) internal {\\n require(_implementation != address(0), \\\"Proxy::setImplementation: invalid address\\\");\\n emit ImplementationChanged(getImplementation(), _implementation);\\n\\n bytes32 key = KEY_IMPLEMENTATION;\\n assembly {\\n sstore(key, _implementation)\\n }\\n }\\n\\n /**\\n * @notice Return address of the implementation.\\n * @return _implementation Address of the implementation.\\n * */\\n function getImplementation() public view returns (address _implementation) {\\n bytes32 key = KEY_IMPLEMENTATION;\\n assembly {\\n _implementation := sload(key)\\n }\\n }\\n\\n /**\\n * @notice Fallback function performs a delegate call\\n * to the actual implementation address is pointing this proxy.\\n * Returns whatever the implementation call returns.\\n * */\\n fallback() external payable {\\n delegate();\\n }\\n\\n /**\\n * @notice Fallback function performs a delegate call\\n * to the actual implementation address is pointing this proxy.\\n * Returns whatever the implementation call returns.\\n * */\\n receive() external payable {\\n delegate();\\n }\\n\\n function delegate() internal {\\n address implementation = getImplementation();\\n require(implementation != address(0), \\\"Proxy::(): implementation not found\\\");\\n\\n assembly {\\n let pointer := mload(0x40)\\n calldatacopy(pointer, 0, calldatasize())\\n let result := delegatecall(gas(), implementation, pointer, calldatasize(), 0, 0)\\n let size := returndatasize()\\n returndatacopy(pointer, 0, size)\\n\\n switch result\\n case 0 {\\n revert(pointer, size)\\n }\\n default {\\n return(pointer, size)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xebadc363c4b07589b9d432da451c9f68f636a4fbe6da6f66cfbb360f12c05132\",\"license\":\"MIT\"},\"contracts/Proxy/UpgradableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.6.11;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\n/**\\n * @title Upgradable Proxy contract.\\n *\\n * Adapted version of https://github.com/DistributedCollective/Sovryn-smart-contracts/blob/development/contracts/proxy/UpgradableProxy.sol\\n * \\n * @notice A disadvantage of the immutable ledger is that nobody can change the\\n * source code of a smart contract after it\\u2019s been deployed. In order to fix\\n * bugs or introduce new features, smart contracts need to be upgradable somehow.\\n *\\n * Although it is not possible to upgrade the code of an already deployed smart\\n * contract, it is possible to set-up a proxy contract architecture that will\\n * allow to use new deployed contracts as if the main logic had been upgraded.\\n *\\n * A proxy architecture pattern is such that all message calls go through a\\n * Proxy contract that will redirect them to the latest deployed contract logic.\\n * To upgrade, a new version of the contract is deployed, and the Proxy is\\n * updated to reference the new contract address.\\n * */\\ncontract UpgradableProxy is Proxy {\\n /**\\n * @notice Set address of the implementation.\\n * @dev Wrapper for _setImplementation that exposes the function\\n * as public for owner to be able to set a new version of the\\n * contract as current pointing implementation.\\n * @param _implementation Address of the implementation.\\n * */\\n function setImplementation(address _implementation) public onlyOwner {\\n _setImplementation(_implementation);\\n }\\n\\n}\\n\",\"keccak256\":\"0x0841172f0b41b3e61cb76c8897132db520b875779897cb5cbc12ca2aab6329d5\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "devdoc": { + "kind": "dev", + "methods": { + "getImplementation()": { + "returns": { + "_implementation": "Address of the implementation. " + } + }, + "getOwner()": { + "returns": { + "_owner": "Address of the owner. " + } + }, + "setImplementation(address)": { + "details": "Wrapper for _setImplementation that exposes the function as public for owner to be able to set a new version of the contract as current pointing implementation.", + "params": { + "_implementation": "Address of the implementation. " + } + }, + "setOwner(address)": { + "params": { + "_owner": "Address of the owner. " + } + } + }, + "title": "Upgradable Proxy contract. Adapted version of https://github.com/DistributedCollective/Sovryn-smart-contracts/blob/development/contracts/proxy/UpgradableProxy.sol ", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "getImplementation()": { + "notice": "Return address of the implementation." + }, + "getOwner()": { + "notice": "Return address of the owner." + }, + "setImplementation(address)": { + "notice": "Set address of the implementation." + }, + "setOwner(address)": { + "notice": "Set address of the owner (only owner can call this function)" + } + }, + "notice": "A disadvantage of the immutable ledger is that nobody can change the source code of a smart contract after it’s been deployed. In order to fix bugs or introduce new features, smart contracts need to be upgradable somehow. Although it is not possible to upgrade the code of an already deployed smart contract, it is possible to set-up a proxy contract architecture that will allow to use new deployed contracts as if the main logic had been upgraded. A proxy architecture pattern is such that all message calls go through a Proxy contract that will redirect them to the latest deployed contract logic. To upgrade, a new version of the contract is deployed, and the Proxy is updated to reference the new contract address. ", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/defaultPool.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/DefaultPool.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/defaultPool.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/DefaultPool.json index 4770fe77..9729a62b 100644 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/defaultPool.json +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/DefaultPool.json @@ -1,4 +1,5 @@ { + "address": "0x037216Fa1916E37d82E1456469B635112CF372dd", "_format": "hh-sol-artifact-1", "contractName": "DefaultPool", "sourceName": "contracts/DefaultPool.sol", @@ -301,6 +302,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b8152600401808060200182810382526022815260200180610bd56022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b610ab68061011f6000396000f3fe6080604052600436106100a05760003560e01c8063893d20e811610064578063893d20e8146101ca57806390107afe146101df578063a3f4df7e1461021a578063b08bc722146102a4578063be41205f146102b9578063f2e91d71146102e3576100f9565b806313af4035146100fe57806314f6c3be146101335780632439789a1461015a5780633963e980146101845780635a4d28bb14610199576100f9565b366100f9576100ad61030d565b6002546100c0903463ffffffff61035816565b600281905560408051918252517f9a14ae677a60400af9176bed2e2d5ce8dfa6405e6c1702debb27668f567214289181900360200190a1005b600080fd5b34801561010a57600080fd5b506101316004803603602081101561012157600080fd5b50356001600160a01b03166103b9565b005b34801561013f57600080fd5b5061014861042c565b60408051918252519081900360200190f35b34801561016657600080fd5b506101316004803603602081101561017d57600080fd5b5035610432565b34801561019057600080fd5b50610148610487565b3480156101a557600080fd5b506101ae61048d565b604080516001600160a01b039092168252519081900360200190f35b3480156101d657600080fd5b506101ae61049c565b3480156101eb57600080fd5b506101316004803603604081101561020257600080fd5b506001600160a01b03813581169160200135166104c6565b34801561022657600080fd5b5061022f6105df565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610269578181015183820152602001610251565b50505050905090810190601f1680156102965780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102b057600080fd5b506101ae610606565b3480156102c557600080fd5b50610131600480360360208110156102dc57600080fd5b5035610615565b3480156102ef57600080fd5b506101316004803603602081101561030657600080fd5b5035610765565b6001546001600160a01b031633146103565760405162461bcd60e51b8152600401808060200182810382526029815260200180610a0b6029913960400191505060405180910390fd5b565b6000828201838110156103b2576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6103c161049c565b6001600160a01b0316336001600160a01b031614610420576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61042981610780565b50565b60025490565b61043a610835565b60035461044d908263ffffffff61087e16565b600381905560408051918252517f636083bfd8929ae461979d51af53349434cd5ee35f983909b704bded4142b9519181900360200190a150565b60035490565b6000546001600160a01b031681565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104ce61049c565b6001600160a01b0316336001600160a01b03161461052d576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b610536826108c0565b61053f816108c0565b600080546001600160a01b038085166001600160a01b03199283168117909355600180549185169190921617905560408051918252517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038316815290517f78f058b189175430c48dc02699e3a0031ea4ff781536dc2fab847de4babdd8829181900360200190a15050565b6040518060400160405280600b81526020016a111959985d5b1d141bdbdb60aa1b81525081565b6001546001600160a01b031681565b61061d610835565b6001546002546001600160a01b039091169061063f908363ffffffff61087e16565b600281905560408051918252517f9a14ae677a60400af9176bed2e2d5ce8dfa6405e6c1702debb27668f567214289181900360200190a1604080516001600160a01b03831681526020810184905281517f6109e2559dfa766aaec7118351d48a523f0a4157f49c8d68749c8ac41318ad12929181900390910190a16040516000906001600160a01b0383169084908381818185875af1925050503d8060008114610705576040519150601f19603f3d011682016040523d82523d6000602084013e61070a565b606091505b5050905080610760576040805162461bcd60e51b815260206004820152601f60248201527f44656661756c74506f6f6c3a2073656e64696e6720455448206661696c656400604482015290519081900360640190fd5b505050565b61076d610835565b60035461044d908263ffffffff61035816565b6001600160a01b0381166107c55760405162461bcd60e51b8152600401808060200182810382526022815260200180610a346022913960400191505060405180910390fd5b806001600160a01b03166107d761049c565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6000546001600160a01b031633146103565760405162461bcd60e51b815260040180806020018281038252602b815260200180610a56602b913960400191505060405180910390fd5b60006103b283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610973565b6001600160a01b03811661091b576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b8061096f576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b60008184841115610a025760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156109c75781810151838201526020016109af565b50505050905090810190601f1680156109f45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe44656661756c74506f6f6c3a2043616c6c6572206973206e6f742074686520416374697665506f6f6c4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737344656661756c74506f6f6c3a2043616c6c6572206973206e6f74207468652054726f76654d616e61676572a2646970667358221220d99aea28c644c442996807d1a9df6b9c6fcb9a4741349be927c8e86d5886d30464736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", "deployedBytecode": "0x6080604052600436106100a05760003560e01c8063893d20e811610064578063893d20e8146101ca57806390107afe146101df578063a3f4df7e1461021a578063b08bc722146102a4578063be41205f146102b9578063f2e91d71146102e3576100f9565b806313af4035146100fe57806314f6c3be146101335780632439789a1461015a5780633963e980146101845780635a4d28bb14610199576100f9565b366100f9576100ad61030d565b6002546100c0903463ffffffff61035816565b600281905560408051918252517f9a14ae677a60400af9176bed2e2d5ce8dfa6405e6c1702debb27668f567214289181900360200190a1005b600080fd5b34801561010a57600080fd5b506101316004803603602081101561012157600080fd5b50356001600160a01b03166103b9565b005b34801561013f57600080fd5b5061014861042c565b60408051918252519081900360200190f35b34801561016657600080fd5b506101316004803603602081101561017d57600080fd5b5035610432565b34801561019057600080fd5b50610148610487565b3480156101a557600080fd5b506101ae61048d565b604080516001600160a01b039092168252519081900360200190f35b3480156101d657600080fd5b506101ae61049c565b3480156101eb57600080fd5b506101316004803603604081101561020257600080fd5b506001600160a01b03813581169160200135166104c6565b34801561022657600080fd5b5061022f6105df565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610269578181015183820152602001610251565b50505050905090810190601f1680156102965780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102b057600080fd5b506101ae610606565b3480156102c557600080fd5b50610131600480360360208110156102dc57600080fd5b5035610615565b3480156102ef57600080fd5b506101316004803603602081101561030657600080fd5b5035610765565b6001546001600160a01b031633146103565760405162461bcd60e51b8152600401808060200182810382526029815260200180610a0b6029913960400191505060405180910390fd5b565b6000828201838110156103b2576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6103c161049c565b6001600160a01b0316336001600160a01b031614610420576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61042981610780565b50565b60025490565b61043a610835565b60035461044d908263ffffffff61087e16565b600381905560408051918252517f636083bfd8929ae461979d51af53349434cd5ee35f983909b704bded4142b9519181900360200190a150565b60035490565b6000546001600160a01b031681565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104ce61049c565b6001600160a01b0316336001600160a01b03161461052d576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b610536826108c0565b61053f816108c0565b600080546001600160a01b038085166001600160a01b03199283168117909355600180549185169190921617905560408051918252517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038316815290517f78f058b189175430c48dc02699e3a0031ea4ff781536dc2fab847de4babdd8829181900360200190a15050565b6040518060400160405280600b81526020016a111959985d5b1d141bdbdb60aa1b81525081565b6001546001600160a01b031681565b61061d610835565b6001546002546001600160a01b039091169061063f908363ffffffff61087e16565b600281905560408051918252517f9a14ae677a60400af9176bed2e2d5ce8dfa6405e6c1702debb27668f567214289181900360200190a1604080516001600160a01b03831681526020810184905281517f6109e2559dfa766aaec7118351d48a523f0a4157f49c8d68749c8ac41318ad12929181900390910190a16040516000906001600160a01b0383169084908381818185875af1925050503d8060008114610705576040519150601f19603f3d011682016040523d82523d6000602084013e61070a565b606091505b5050905080610760576040805162461bcd60e51b815260206004820152601f60248201527f44656661756c74506f6f6c3a2073656e64696e6720455448206661696c656400604482015290519081900360640190fd5b505050565b61076d610835565b60035461044d908263ffffffff61035816565b6001600160a01b0381166107c55760405162461bcd60e51b8152600401808060200182810382526022815260200180610a346022913960400191505060405180910390fd5b806001600160a01b03166107d761049c565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6000546001600160a01b031633146103565760405162461bcd60e51b815260040180806020018281038252602b815260200180610a56602b913960400191505060405180910390fd5b60006103b283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610973565b6001600160a01b03811661091b576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b8061096f576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b60008184841115610a025760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156109c75781810151838201526020016109af565b50505050905090810190601f1680156109f45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe44656661756c74506f6f6c3a2043616c6c6572206973206e6f742074686520416374697665506f6f6c4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737344656661756c74506f6f6c3a2043616c6c6572206973206e6f74207468652054726f76654d616e61676572a2646970667358221220d99aea28c644c442996807d1a9df6b9c6fcb9a4741349be927c8e86d5886d30464736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x037216Fa1916E37d82E1456469B635112CF372dd" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/DefaultPool_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/DefaultPool_Proxy.json new file mode 100644 index 00000000..559ebe4e --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/DefaultPool_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0x037216Fa1916E37d82E1456469B635112CF372dd", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/feeDistributor.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/FeeDistributor.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynMainnet/feeDistributor.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/FeeDistributor.json index 0b465c28..80decd36 100644 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/feeDistributor.json +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/FeeDistributor.json @@ -1,4 +1,5 @@ { + "address": "0x6e825a3569D46510c0f707eb625e456679dff721", "_format": "hh-sol-artifact-1", "contractName": "FeeDistributor", "sourceName": "contracts/FeeDistributor.sol", @@ -353,6 +354,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b815260040180806020018281038252602281526020018061129c6022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b61117d8061011f6000396000f3fe6080604052600436106100c15760003560e01c8063b08bc7221161006f578063b08bc72214610229578063bb57ad201461023e578063d9db1a6814610253578063eaa8ba7f14610268578063ec5472fd146102cd578063ec9f7d46146102e2578063f231f7cd146102f7576100d0565b806313af4035146100d55780633d83908a146101085780636b7dbb2d1461013957806377553ad41461014e578063893d20e8146101635780638e93c64914610178578063a3f4df7e1461019f576100d0565b366100d0576100ce610321565b005b600080fd5b3480156100e157600080fd5b506100ce600480360360208110156100f857600080fd5b50356001600160a01b031661036c565b34801561011457600080fd5b5061011d6103df565b604080516001600160a01b039092168252519081900360200190f35b34801561014557600080fd5b5061011d6103ee565b34801561015a57600080fd5b5061011d6103fd565b34801561016f57600080fd5b5061011d61040c565b34801561018457600080fd5b5061018d610436565b60408051918252519081900360200190f35b3480156101ab57600080fd5b506101b461043c565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101ee5781810151838201526020016101d6565b50505050905090810190601f16801561021b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023557600080fd5b5061011d610466565b34801561024a57600080fd5b506100ce610475565b34801561025f57600080fd5b5061011d610585565b34801561027457600080fd5b506100ce600480360360e081101561028b57600080fd5b506001600160a01b038135811691602081013582169160408201358116916060810135821691608082013581169160a081013582169160c09091013516610594565b3480156102d957600080fd5b5061011d610857565b3480156102ee57600080fd5b5061011d610866565b34801561030357600080fd5b506100ce6004803603602081101561031a57600080fd5b5035610875565b6006546001600160a01b0316331461036a5760405162461bcd60e51b81526004018080602001828103825260288152602001806111206028913960400191505060405180910390fd5b565b61037461040c565b6001600160a01b0316336001600160a01b0316146103d3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6103dc816108e1565b50565b6003546001600160a01b031681565b6000546001600160a01b031681565b6002546001600160a01b031681565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b60075481565b6040518060400160405280600e81526020016d2332b2a234b9ba3934b13aba37b960911b81525081565b6006546001600160a01b031681565b6002546001600160a01b031633148061049857506003546001600160a01b031633145b6104e9576040805162461bcd60e51b815260206004820152601e60248201527f4665654469737472696275746f723a20696e76616c69642063616c6c65720000604482015290519081900360640190fd5b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561053457600080fd5b505afa158015610548573d6000803e3d6000fd5b505050506040513d602081101561055e57600080fd5b505190504781156105725761057282610996565b80156105815761058181610c58565b5050565b6004546001600160a01b031681565b61059c61040c565b6001600160a01b0316336001600160a01b0316146105fb576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61060487610e29565b61060d86610e29565b61061685610e29565b61061f84610e29565b61062883610e29565b61063182610e29565b61063a81610e29565b600080546001600160a01b03199081166001600160a01b038a81169182179093556001805483168a851617905560028054831689851617905560038054831688851617905560048054831687851617905560058054831686851617905560068054909216928416929092179055670de0b6b3a764000060075560408051918252517f963023df1091dc8c0e46db982274139953d69a4d688a740bee4aa40fa318497e916020908290030190a1604080516001600160a01b038816815290517fc7b150c129c1c24ff23a07f2d3c9579928b1a51697a8a1f79dd07888fc904b849181900360200190a1604080516001600160a01b038716815290517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1604080516001600160a01b038616815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038516815290517f35bae0aeb0bdf7e62f85dbfcc7876b98015f550d75ae3deb0505c0565db12f4b9181900360200190a1604080516001600160a01b038416815290517fcdf33850c44a1a874b5fefb51dae615ac6afebd581ef90d571f81b06541d8e9d9181900360200190a1604080516001600160a01b038316815290517f8f6a6e7d20a3233e0a79883272259ffbd7a243734e397bc2b4642c79d7fa8a6d9181900360200190a150505050505050565b6001546001600160a01b031681565b6005546001600160a01b031681565b61087d61040c565b6001600160a01b0316336001600160a01b0316146108dc576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b600755565b6001600160a01b0381166109265760405162461bcd60e51b81526004018080602001828103825260228152602001806110bb6022913960400191505060405180910390fd5b806001600160a01b031661093861040c565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b60006109c5670de0b6b3a76400006109b960075485610ed890919063ffffffff16565b9063ffffffff610f3a16565b600554600080546040805163095ea7b360e01b81526001600160a01b03928316600482015260248101869052905194955092169263095ea7b3926044808201936020939283900390910190829087803b158015610a2157600080fd5b505af1158015610a35573d6000803e3d6000fd5b505050506040513d6020811015610a4b57600080fd5b5050600080546005546040805163abe979e160e01b81526001600160a01b0392831660048201526bffffffffffffffffffffffff861660248201529051919092169263abe979e1926044808201939182900301818387803b158015610aaf57600080fd5b505af1158015610ac3573d6000803e3d6000fd5b505050506000610adc8284610f7c90919063ffffffff16565b90508015610c20576005546001546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b158015610b3d57600080fd5b505af1158015610b51573d6000803e3d6000fd5b505050506040513d6020811015610b6757600080fd5b5051610bba576040805162461bcd60e51b815260206004820152601d60248201527f436f75646e27742065786563757465205a555344207472616e73666572000000604482015290519081900360640190fd5b6001546040805163187daae360e21b81526004810184905290516001600160a01b03909216916361f6ab8c9160248082019260009290919082900301818387803b158015610c0757600080fd5b505af1158015610c1b573d6000803e3d6000fd5b505050505b6040805184815290517f3168880c2a9a8e657d1de00769e3baefa8c1153f1847a85b43070ee5fed512959181900360200190a1505050565b6000610c7b670de0b6b3a76400006109b960075485610ed890919063ffffffff16565b60008054604080516322a6fd9560e01b815290519394506001600160a01b03909116926322a6fd959285926004808201939182900301818588803b158015610cc257600080fd5b505af1158015610cd6573d6000803e3d6000fd5b50505050506000610cf08284610f7c90919063ffffffff16565b90508015610df1576001546040516000916001600160a01b03169083908381818185875af1925050503d8060008114610d45576040519150601f19603f3d011682016040523d82523d6000602084013e610d4a565b606091505b5050905080610d8a5760405162461bcd60e51b81526004018080602001828103825260228152602001806110dd6022913960400191505060405180910390fd5b60015460408051630f1f150d60e11b81526004810185905290516001600160a01b0390921691631e3e2a1a9160248082019260009290919082900301818387803b158015610dd757600080fd5b505af1158015610deb573d6000803e3d6000fd5b50505050505b6040805184815290517f3289490aa1b0ec56454cbd5d18bd6b8d79609982b2abe74eee579eb6f67581919181900360200190a1505050565b6001600160a01b038116610e84576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b80610581576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b600082610ee757506000610f34565b82820282848281610ef457fe5b0414610f315760405162461bcd60e51b81526004018080602001828103825260218152602001806110ff6021913960400191505060405180910390fd5b90505b92915050565b6000610f3183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610fbe565b6000610f3183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611060565b6000818361104a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561100f578181015183820152602001610ff7565b50505050905090810190601f16801561103c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161105657fe5b0495945050505050565b600081848411156110b25760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561100f578181015183820152602001610ff7565b50505090039056fe4f776e61626c653a3a7365744f776e65723a20696e76616c696420616464726573734665654469737472696275746f723a2073656e64696e6720455448206661696c6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774665654469737472696275746f723a2063616c6c6572206973206e6f7420416374697665506f6f6ca264697066735822122068cbf3a893e2b9713149ddceb6b3570b9d11482f5f07b3b3066ad70f4eec87e264736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", "deployedBytecode": "0x6080604052600436106100c15760003560e01c8063b08bc7221161006f578063b08bc72214610229578063bb57ad201461023e578063d9db1a6814610253578063eaa8ba7f14610268578063ec5472fd146102cd578063ec9f7d46146102e2578063f231f7cd146102f7576100d0565b806313af4035146100d55780633d83908a146101085780636b7dbb2d1461013957806377553ad41461014e578063893d20e8146101635780638e93c64914610178578063a3f4df7e1461019f576100d0565b366100d0576100ce610321565b005b600080fd5b3480156100e157600080fd5b506100ce600480360360208110156100f857600080fd5b50356001600160a01b031661036c565b34801561011457600080fd5b5061011d6103df565b604080516001600160a01b039092168252519081900360200190f35b34801561014557600080fd5b5061011d6103ee565b34801561015a57600080fd5b5061011d6103fd565b34801561016f57600080fd5b5061011d61040c565b34801561018457600080fd5b5061018d610436565b60408051918252519081900360200190f35b3480156101ab57600080fd5b506101b461043c565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101ee5781810151838201526020016101d6565b50505050905090810190601f16801561021b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023557600080fd5b5061011d610466565b34801561024a57600080fd5b506100ce610475565b34801561025f57600080fd5b5061011d610585565b34801561027457600080fd5b506100ce600480360360e081101561028b57600080fd5b506001600160a01b038135811691602081013582169160408201358116916060810135821691608082013581169160a081013582169160c09091013516610594565b3480156102d957600080fd5b5061011d610857565b3480156102ee57600080fd5b5061011d610866565b34801561030357600080fd5b506100ce6004803603602081101561031a57600080fd5b5035610875565b6006546001600160a01b0316331461036a5760405162461bcd60e51b81526004018080602001828103825260288152602001806111206028913960400191505060405180910390fd5b565b61037461040c565b6001600160a01b0316336001600160a01b0316146103d3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6103dc816108e1565b50565b6003546001600160a01b031681565b6000546001600160a01b031681565b6002546001600160a01b031681565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b60075481565b6040518060400160405280600e81526020016d2332b2a234b9ba3934b13aba37b960911b81525081565b6006546001600160a01b031681565b6002546001600160a01b031633148061049857506003546001600160a01b031633145b6104e9576040805162461bcd60e51b815260206004820152601e60248201527f4665654469737472696275746f723a20696e76616c69642063616c6c65720000604482015290519081900360640190fd5b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561053457600080fd5b505afa158015610548573d6000803e3d6000fd5b505050506040513d602081101561055e57600080fd5b505190504781156105725761057282610996565b80156105815761058181610c58565b5050565b6004546001600160a01b031681565b61059c61040c565b6001600160a01b0316336001600160a01b0316146105fb576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b61060487610e29565b61060d86610e29565b61061685610e29565b61061f84610e29565b61062883610e29565b61063182610e29565b61063a81610e29565b600080546001600160a01b03199081166001600160a01b038a81169182179093556001805483168a851617905560028054831689851617905560038054831688851617905560048054831687851617905560058054831686851617905560068054909216928416929092179055670de0b6b3a764000060075560408051918252517f963023df1091dc8c0e46db982274139953d69a4d688a740bee4aa40fa318497e916020908290030190a1604080516001600160a01b038816815290517fc7b150c129c1c24ff23a07f2d3c9579928b1a51697a8a1f79dd07888fc904b849181900360200190a1604080516001600160a01b038716815290517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1604080516001600160a01b038616815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038516815290517f35bae0aeb0bdf7e62f85dbfcc7876b98015f550d75ae3deb0505c0565db12f4b9181900360200190a1604080516001600160a01b038416815290517fcdf33850c44a1a874b5fefb51dae615ac6afebd581ef90d571f81b06541d8e9d9181900360200190a1604080516001600160a01b038316815290517f8f6a6e7d20a3233e0a79883272259ffbd7a243734e397bc2b4642c79d7fa8a6d9181900360200190a150505050505050565b6001546001600160a01b031681565b6005546001600160a01b031681565b61087d61040c565b6001600160a01b0316336001600160a01b0316146108dc576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b600755565b6001600160a01b0381166109265760405162461bcd60e51b81526004018080602001828103825260228152602001806110bb6022913960400191505060405180910390fd5b806001600160a01b031661093861040c565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b60006109c5670de0b6b3a76400006109b960075485610ed890919063ffffffff16565b9063ffffffff610f3a16565b600554600080546040805163095ea7b360e01b81526001600160a01b03928316600482015260248101869052905194955092169263095ea7b3926044808201936020939283900390910190829087803b158015610a2157600080fd5b505af1158015610a35573d6000803e3d6000fd5b505050506040513d6020811015610a4b57600080fd5b5050600080546005546040805163abe979e160e01b81526001600160a01b0392831660048201526bffffffffffffffffffffffff861660248201529051919092169263abe979e1926044808201939182900301818387803b158015610aaf57600080fd5b505af1158015610ac3573d6000803e3d6000fd5b505050506000610adc8284610f7c90919063ffffffff16565b90508015610c20576005546001546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b158015610b3d57600080fd5b505af1158015610b51573d6000803e3d6000fd5b505050506040513d6020811015610b6757600080fd5b5051610bba576040805162461bcd60e51b815260206004820152601d60248201527f436f75646e27742065786563757465205a555344207472616e73666572000000604482015290519081900360640190fd5b6001546040805163187daae360e21b81526004810184905290516001600160a01b03909216916361f6ab8c9160248082019260009290919082900301818387803b158015610c0757600080fd5b505af1158015610c1b573d6000803e3d6000fd5b505050505b6040805184815290517f3168880c2a9a8e657d1de00769e3baefa8c1153f1847a85b43070ee5fed512959181900360200190a1505050565b6000610c7b670de0b6b3a76400006109b960075485610ed890919063ffffffff16565b60008054604080516322a6fd9560e01b815290519394506001600160a01b03909116926322a6fd959285926004808201939182900301818588803b158015610cc257600080fd5b505af1158015610cd6573d6000803e3d6000fd5b50505050506000610cf08284610f7c90919063ffffffff16565b90508015610df1576001546040516000916001600160a01b03169083908381818185875af1925050503d8060008114610d45576040519150601f19603f3d011682016040523d82523d6000602084013e610d4a565b606091505b5050905080610d8a5760405162461bcd60e51b81526004018080602001828103825260228152602001806110dd6022913960400191505060405180910390fd5b60015460408051630f1f150d60e11b81526004810185905290516001600160a01b0390921691631e3e2a1a9160248082019260009290919082900301818387803b158015610dd757600080fd5b505af1158015610deb573d6000803e3d6000fd5b50505050505b6040805184815290517f3289490aa1b0ec56454cbd5d18bd6b8d79609982b2abe74eee579eb6f67581919181900360200190a1505050565b6001600160a01b038116610e84576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b80610581576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b600082610ee757506000610f34565b82820282848281610ef457fe5b0414610f315760405162461bcd60e51b81526004018080602001828103825260218152602001806110ff6021913960400191505060405180910390fd5b90505b92915050565b6000610f3183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610fbe565b6000610f3183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611060565b6000818361104a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561100f578181015183820152602001610ff7565b50505050905090810190601f16801561103c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161105657fe5b0495945050505050565b600081848411156110b25760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561100f578181015183820152602001610ff7565b50505090039056fe4f776e61626c653a3a7365744f776e65723a20696e76616c696420616464726573734665654469737472696275746f723a2073656e64696e6720455448206661696c6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774665654469737472696275746f723a2063616c6c6572206973206e6f7420416374697665506f6f6ca264697066735822122068cbf3a893e2b9713149ddceb6b3570b9d11482f5f07b3b3066ad70f4eec87e264736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x1261d5872d56e2Ab61B3C68451D015b752105027" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/FeeDistributor_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/FeeDistributor_Proxy.json new file mode 100644 index 00000000..be6b7134 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/FeeDistributor_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0x6e825a3569D46510c0f707eb625e456679dff721", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/hintHelpers.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/HintHelpers.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynMainnet/hintHelpers.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/HintHelpers.json index f6a22a09..ddc65f8f 100644 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/hintHelpers.json +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/HintHelpers.json @@ -1,4 +1,5 @@ { + "address": "0xc7Bf159d6259ce5a4Fbdd0e3d060875F76605Dba", "_format": "hh-sol-artifact-1", "contractName": "HintHelpers", "sourceName": "contracts/HintHelpers.sol", @@ -401,6 +402,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806116d46022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6115b58061011f6000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c8063795d26c3116100ad5780639f070670116100715780639f070670146102b2578063a20baee614610251578063a3f4df7e146102ba578063ae91875414610337578063c394a7fa1461033f5761012c565b8063795d26c3146102695780637b41bdbe146102715780637f7dde4a1461029a578063887105d3146102a2578063893d20e8146102aa5761012c565b80633d83908a116100f45780633d83908a14610220578063525acdbb1461022857806372fe25aa14610251578063741bef1a14610259578063759b3034146102615761012c565b806313144dba1461013157806313af4035146101825780631bf43555146101aa578063363bf964146101c45780633cc74225146101fc575b600080fd5b61015a6004803603606081101561014757600080fd5b5080359060208101359060400135610362565b604080516001600160a01b039094168452602084019290925282820152519081900360600190f35b6101a86004803603602081101561019857600080fd5b50356001600160a01b0316610951565b005b6101b26109c4565b60408051918252519081900360200190f35b6101a8600480360360608110156101da57600080fd5b506001600160a01b0381358116916020810135821691604090910135166109d1565b610204610b05565b604080516001600160a01b039092168252519081900360200190f35b610204610b14565b6101b26004803603606081101561023e57600080fd5b5080359060208101359060400135610b23565b6101b2610b3a565b610204610b46565b6101b2610b55565b6101b2610b62565b61015a6004803603606081101561028757600080fd5b5080359060208101359060400135610c61565b610204610f72565b6101b2610f81565b61020461103d565b610204611067565b6102c2611076565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102fc5781810151838201526020016102e4565b50505050905090810190601f1680156103295780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61020461109d565b6101b26004803603604081101561035557600080fd5b50803590602001356110ac565b6004805460408051634d62283160e01b81529051600093849384936001600160a01b0390911692899285928592634d62283192828101926020929190829003018186803b1580156103b257600080fd5b505afa1580156103c6573d6000803e3d6000fd5b505050506040513d60208110156103dc57600080fd5b505190505b6001600160a01b038116158015906104f05750600360009054906101000a90046001600160a01b03166001600160a01b031663794e57246040518163ffffffff1660e01b815260040160206040518083038186803b15801561044257600080fd5b505afa158015610456573d6000803e3d6000fd5b505050506040513d602081101561046c57600080fd5b505160055460408051630d293c7160e41b81526001600160a01b038581166004830152602482018d90529151919092169163d293c710916044808301926020929190829003018186803b1580156104c257600080fd5b505afa1580156104d6573d6000803e3d6000fd5b505050506040513d60208110156104ec57600080fd5b5051105b1561057e57826001600160a01b031663b72703ac826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561054b57600080fd5b505afa15801561055f573d6000803e3d6000fd5b505050506040513d602081101561057557600080fd5b505190506103e1565b9450848661058c5760001996505b6001600160a01b038116158015906105a45750600082115b80156105b4575060001987019615155b1561093357600554604080516317c62b1760e01b81526001600160a01b03848116600483015291516000936106c59316916317c62b17916024808301926020929190829003018186803b15801561060a57600080fd5b505afa15801561061e573d6000803e3d6000fd5b505050506040513d602081101561063457600080fd5b50516005546040805163d66a255360e01b81526001600160a01b03878116600483015291516106b993929092169163d66a255391602480820192602092909190829003018186803b15801561068857600080fd5b505afa15801561069c573d6000803e3d6000fd5b505050506040513d60208110156106b257600080fd5b50516110c1565b9063ffffffff6110dc16565b905082811115610896576809c2007651b2500000811115610890576000610704846106ff846809c2007651b250000063ffffffff61113616565b611178565b60055460408051635d8c960960e01b81526001600160a01b038781166004830152915193945060009361080d939290921691635d8c960991602480820192602092909190829003018186803b15801561075c57600080fd5b505afa158015610770573d6000803e3d6000fd5b505050506040513d602081101561078657600080fd5b5051600554604080516309019aaf60e31b81526001600160a01b0389811660048301529151919092169163480cd578916024808301926020929190829003018186803b1580156107d557600080fd5b505afa1580156107e9573d6000803e3d6000fd5b505050506040513d60208110156107ff57600080fd5b50519063ffffffff6110dc16565b9050600061084961083c8d61083086670de0b6b3a764000063ffffffff61118e16565b9063ffffffff6111e716565b839063ffffffff61113616565b9050600061085d858563ffffffff61113616565b9050600061086a82611229565b90506108768382611244565b9a50610888888663ffffffff61113616565b975050505050505b50610933565b6108a6838263ffffffff61113616565b9250836001600160a01b031663b72703ac836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156108fe57600080fd5b505afa158015610912573d6000803e3d6000fd5b505050506040513d602081101561092857600080fd5b5051915061058c9050565b610943898363ffffffff61113616565b935050505093509350939050565b61095961103d565b6001600160a01b0316336001600160a01b0316146109b8576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6109c181611279565b50565b6809c2007651b250000081565b6109d961103d565b6001600160a01b0316336001600160a01b031614610a38576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b610a418361132e565b610a4a8261132e565b610a538161132e565b600380546001600160a01b038086166001600160a01b031992831617909255600480548584169083168117909155600580549385169390921692909217905560408051918252517f65f4cf077bc01e4742eb5ad98326f6e95b63548ea24b17f8d5e823111fe788009181900360200190a1604080516001600160a01b038316815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1505050565b6001546001600160a01b031681565b6005546001600160a01b031681565b6000610b308484846113e1565b90505b9392505050565b670de0b6b3a764000081565b6002546001600160a01b031681565b6801158e460913d0000081565b60008054604080516272c7d360e71b8152905183926001600160a01b031691633963e980916004808301926020929190829003018186803b158015610ba657600080fd5b505afa158015610bba573d6000803e3d6000fd5b505050506040513d6020811015610bd057600080fd5b5051600154604080516272c7d360e71b815290519293506000926001600160a01b0390921691633963e98091600480820192602092909190829003018186803b158015610c1c57600080fd5b505afa158015610c30573d6000803e3d6000fd5b505050506040513d6020811015610c4657600080fd5b50519050610c5a828263ffffffff6110dc16565b9250505090565b600080600080600560009054906101000a90046001600160a01b03166001600160a01b03166349eefeee6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cb557600080fd5b505afa158015610cc9573d6000803e3d6000fd5b505050506040513d6020811015610cdf57600080fd5b5051905080610cf8575060009250829150839050610f69565b6004805460408051634d62283160e01b815290516001600160a01b0390921692634d622831928282019260209290829003018186803b158015610d3a57600080fd5b505afa158015610d4e573d6000803e3d6000fd5b505050506040513d6020811015610d6457600080fd5b50516005546040805163b0d8e18160e01b81526001600160a01b0380851660048301529151939750610dee938b93929092169163b0d8e18191602480820192602092909190829003018186803b158015610dbd57600080fd5b505afa158015610dd1573d6000803e3d6000fd5b505050506040513d6020811015610de757600080fd5b5051611411565b925084915060015b86811015610f6657604080516020808201959095528151808203860181529082019091528051930192909220916000828481610e2e57fe5b0690506000600560009054906101000a90046001600160a01b03166001600160a01b031663d9a72444836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610e8c57600080fd5b505afa158015610ea0573d6000803e3d6000fd5b505050506040513d6020811015610eb657600080fd5b50516005546040805163b0d8e18160e01b81526001600160a01b0380851660048301529151939450600093919092169163b0d8e181916024808301926020929190829003018186803b158015610f0b57600080fd5b505afa158015610f1f573d6000803e3d6000fd5b505050506040513d6020811015610f3557600080fd5b505190506000610f45828d611411565b905087811015610f56578097508298505b505060019092019150610df69050565b50505b93509350939050565b6000546001600160a01b031681565b6000805460408051630a7b61df60e11b8152905183926001600160a01b0316916314f6c3be916004808301926020929190829003018186803b158015610fc657600080fd5b505afa158015610fda573d6000803e3d6000fd5b505050506040513d6020811015610ff057600080fd5b505160015460408051630a7b61df60e11b815290519293506000926001600160a01b03909216916314f6c3be91600480820192602092909190829003018186803b158015610c1c57600080fd5b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6003546001600160a01b031681565b6040518060400160405280600b81526020016a48696e7448656c7065727360a81b81525081565b6004546001600160a01b031681565b60006110b88383611244565b90505b92915050565b60006110bb826801158e460913d0000063ffffffff61113616565b6000828201838110156110b8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006110b883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611440565b600081831061118757816110b8565b5090919050565b60008261119d575060006110bb565b828202828482816111aa57fe5b04146110b85760405162461bcd60e51b815260040180806020018281038252602181526020018061155f6021913960400191505060405180910390fd5b60006110b883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506114d7565b60006110bb826801158e460913d0000063ffffffff6110dc16565b6000811561127057611269826108308568056bc75e2d6310000063ffffffff61118e16565b90506110bb565b506000196110bb565b6001600160a01b0381166112be5760405162461bcd60e51b815260040180806020018281038252602281526020018061153d6022913960400191505060405180910390fd5b806001600160a01b03166112d061103d565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b038116611389576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806113dd576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b600082156114085760006113ff84610830878663ffffffff61118e16565b9150610b339050565b50600019610b33565b6000818310156114305761142b828463ffffffff61113616565b6110b8565b6110b8838363ffffffff61113616565b600081848411156114cf5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561149457818101518382015260200161147c565b50505050905090810190601f1680156114c15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836115265760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561149457818101518382015260200161147c565b50600083858161153257fe5b049594505050505056fe4f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220b45699dc70b63074cc3f4814bee259edea28c29802a6fd53970398c4e3e6509564736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061012c5760003560e01c8063795d26c3116100ad5780639f070670116100715780639f070670146102b2578063a20baee614610251578063a3f4df7e146102ba578063ae91875414610337578063c394a7fa1461033f5761012c565b8063795d26c3146102695780637b41bdbe146102715780637f7dde4a1461029a578063887105d3146102a2578063893d20e8146102aa5761012c565b80633d83908a116100f45780633d83908a14610220578063525acdbb1461022857806372fe25aa14610251578063741bef1a14610259578063759b3034146102615761012c565b806313144dba1461013157806313af4035146101825780631bf43555146101aa578063363bf964146101c45780633cc74225146101fc575b600080fd5b61015a6004803603606081101561014757600080fd5b5080359060208101359060400135610362565b604080516001600160a01b039094168452602084019290925282820152519081900360600190f35b6101a86004803603602081101561019857600080fd5b50356001600160a01b0316610951565b005b6101b26109c4565b60408051918252519081900360200190f35b6101a8600480360360608110156101da57600080fd5b506001600160a01b0381358116916020810135821691604090910135166109d1565b610204610b05565b604080516001600160a01b039092168252519081900360200190f35b610204610b14565b6101b26004803603606081101561023e57600080fd5b5080359060208101359060400135610b23565b6101b2610b3a565b610204610b46565b6101b2610b55565b6101b2610b62565b61015a6004803603606081101561028757600080fd5b5080359060208101359060400135610c61565b610204610f72565b6101b2610f81565b61020461103d565b610204611067565b6102c2611076565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102fc5781810151838201526020016102e4565b50505050905090810190601f1680156103295780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61020461109d565b6101b26004803603604081101561035557600080fd5b50803590602001356110ac565b6004805460408051634d62283160e01b81529051600093849384936001600160a01b0390911692899285928592634d62283192828101926020929190829003018186803b1580156103b257600080fd5b505afa1580156103c6573d6000803e3d6000fd5b505050506040513d60208110156103dc57600080fd5b505190505b6001600160a01b038116158015906104f05750600360009054906101000a90046001600160a01b03166001600160a01b031663794e57246040518163ffffffff1660e01b815260040160206040518083038186803b15801561044257600080fd5b505afa158015610456573d6000803e3d6000fd5b505050506040513d602081101561046c57600080fd5b505160055460408051630d293c7160e41b81526001600160a01b038581166004830152602482018d90529151919092169163d293c710916044808301926020929190829003018186803b1580156104c257600080fd5b505afa1580156104d6573d6000803e3d6000fd5b505050506040513d60208110156104ec57600080fd5b5051105b1561057e57826001600160a01b031663b72703ac826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561054b57600080fd5b505afa15801561055f573d6000803e3d6000fd5b505050506040513d602081101561057557600080fd5b505190506103e1565b9450848661058c5760001996505b6001600160a01b038116158015906105a45750600082115b80156105b4575060001987019615155b1561093357600554604080516317c62b1760e01b81526001600160a01b03848116600483015291516000936106c59316916317c62b17916024808301926020929190829003018186803b15801561060a57600080fd5b505afa15801561061e573d6000803e3d6000fd5b505050506040513d602081101561063457600080fd5b50516005546040805163d66a255360e01b81526001600160a01b03878116600483015291516106b993929092169163d66a255391602480820192602092909190829003018186803b15801561068857600080fd5b505afa15801561069c573d6000803e3d6000fd5b505050506040513d60208110156106b257600080fd5b50516110c1565b9063ffffffff6110dc16565b905082811115610896576809c2007651b2500000811115610890576000610704846106ff846809c2007651b250000063ffffffff61113616565b611178565b60055460408051635d8c960960e01b81526001600160a01b038781166004830152915193945060009361080d939290921691635d8c960991602480820192602092909190829003018186803b15801561075c57600080fd5b505afa158015610770573d6000803e3d6000fd5b505050506040513d602081101561078657600080fd5b5051600554604080516309019aaf60e31b81526001600160a01b0389811660048301529151919092169163480cd578916024808301926020929190829003018186803b1580156107d557600080fd5b505afa1580156107e9573d6000803e3d6000fd5b505050506040513d60208110156107ff57600080fd5b50519063ffffffff6110dc16565b9050600061084961083c8d61083086670de0b6b3a764000063ffffffff61118e16565b9063ffffffff6111e716565b839063ffffffff61113616565b9050600061085d858563ffffffff61113616565b9050600061086a82611229565b90506108768382611244565b9a50610888888663ffffffff61113616565b975050505050505b50610933565b6108a6838263ffffffff61113616565b9250836001600160a01b031663b72703ac836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156108fe57600080fd5b505afa158015610912573d6000803e3d6000fd5b505050506040513d602081101561092857600080fd5b5051915061058c9050565b610943898363ffffffff61113616565b935050505093509350939050565b61095961103d565b6001600160a01b0316336001600160a01b0316146109b8576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6109c181611279565b50565b6809c2007651b250000081565b6109d961103d565b6001600160a01b0316336001600160a01b031614610a38576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b610a418361132e565b610a4a8261132e565b610a538161132e565b600380546001600160a01b038086166001600160a01b031992831617909255600480548584169083168117909155600580549385169390921692909217905560408051918252517f65f4cf077bc01e4742eb5ad98326f6e95b63548ea24b17f8d5e823111fe788009181900360200190a1604080516001600160a01b038316815290517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1505050565b6001546001600160a01b031681565b6005546001600160a01b031681565b6000610b308484846113e1565b90505b9392505050565b670de0b6b3a764000081565b6002546001600160a01b031681565b6801158e460913d0000081565b60008054604080516272c7d360e71b8152905183926001600160a01b031691633963e980916004808301926020929190829003018186803b158015610ba657600080fd5b505afa158015610bba573d6000803e3d6000fd5b505050506040513d6020811015610bd057600080fd5b5051600154604080516272c7d360e71b815290519293506000926001600160a01b0390921691633963e98091600480820192602092909190829003018186803b158015610c1c57600080fd5b505afa158015610c30573d6000803e3d6000fd5b505050506040513d6020811015610c4657600080fd5b50519050610c5a828263ffffffff6110dc16565b9250505090565b600080600080600560009054906101000a90046001600160a01b03166001600160a01b03166349eefeee6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cb557600080fd5b505afa158015610cc9573d6000803e3d6000fd5b505050506040513d6020811015610cdf57600080fd5b5051905080610cf8575060009250829150839050610f69565b6004805460408051634d62283160e01b815290516001600160a01b0390921692634d622831928282019260209290829003018186803b158015610d3a57600080fd5b505afa158015610d4e573d6000803e3d6000fd5b505050506040513d6020811015610d6457600080fd5b50516005546040805163b0d8e18160e01b81526001600160a01b0380851660048301529151939750610dee938b93929092169163b0d8e18191602480820192602092909190829003018186803b158015610dbd57600080fd5b505afa158015610dd1573d6000803e3d6000fd5b505050506040513d6020811015610de757600080fd5b5051611411565b925084915060015b86811015610f6657604080516020808201959095528151808203860181529082019091528051930192909220916000828481610e2e57fe5b0690506000600560009054906101000a90046001600160a01b03166001600160a01b031663d9a72444836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610e8c57600080fd5b505afa158015610ea0573d6000803e3d6000fd5b505050506040513d6020811015610eb657600080fd5b50516005546040805163b0d8e18160e01b81526001600160a01b0380851660048301529151939450600093919092169163b0d8e181916024808301926020929190829003018186803b158015610f0b57600080fd5b505afa158015610f1f573d6000803e3d6000fd5b505050506040513d6020811015610f3557600080fd5b505190506000610f45828d611411565b905087811015610f56578097508298505b505060019092019150610df69050565b50505b93509350939050565b6000546001600160a01b031681565b6000805460408051630a7b61df60e11b8152905183926001600160a01b0316916314f6c3be916004808301926020929190829003018186803b158015610fc657600080fd5b505afa158015610fda573d6000803e3d6000fd5b505050506040513d6020811015610ff057600080fd5b505160015460408051630a7b61df60e11b815290519293506000926001600160a01b03909216916314f6c3be91600480820192602092909190829003018186803b158015610c1c57600080fd5b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6003546001600160a01b031681565b6040518060400160405280600b81526020016a48696e7448656c7065727360a81b81525081565b6004546001600160a01b031681565b60006110b88383611244565b90505b92915050565b60006110bb826801158e460913d0000063ffffffff61113616565b6000828201838110156110b8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006110b883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611440565b600081831061118757816110b8565b5090919050565b60008261119d575060006110bb565b828202828482816111aa57fe5b04146110b85760405162461bcd60e51b815260040180806020018281038252602181526020018061155f6021913960400191505060405180910390fd5b60006110b883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506114d7565b60006110bb826801158e460913d0000063ffffffff6110dc16565b6000811561127057611269826108308568056bc75e2d6310000063ffffffff61118e16565b90506110bb565b506000196110bb565b6001600160a01b0381166112be5760405162461bcd60e51b815260040180806020018281038252602281526020018061153d6022913960400191505060405180910390fd5b806001600160a01b03166112d061103d565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b038116611389576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806113dd576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b600082156114085760006113ff84610830878663ffffffff61118e16565b9150610b339050565b50600019610b33565b6000818310156114305761142b828463ffffffff61113616565b6110b8565b6110b8838363ffffffff61113616565b600081848411156114cf5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561149457818101518382015260200161147c565b50505050905090810190601f1680156114c15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836115265760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561149457818101518382015260200161147c565b50600083858161153257fe5b049594505050505056fe4f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220b45699dc70b63074cc3f4814bee259edea28c29802a6fd53970398c4e3e6509564736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x1D7DaC5a63A35540bE9e031212ecf39584AE5595" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/HintHelpers_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/HintHelpers_Proxy.json new file mode 100644 index 00000000..10121eae --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/HintHelpers_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0xc7Bf159d6259ce5a4Fbdd0e3d060875F76605Dba", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/LiquityBaseParams.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/LiquityBaseParams.json index 6d1a9afa..c821a0b6 100644 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/LiquityBaseParams.json +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/LiquityBaseParams.json @@ -1,234 +1,233 @@ { - "_format": "hh-sol-artifact-1", - "contractName": "LiquityBaseParams", - "sourceName": "contracts/LiquityBaseParams.sol", - "address": "0x8B1cB2Ffc9aFe4344503824898098d2E4c883873", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "BORROWING_FEE_FLOOR", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "CCR", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "DECIMAL_PRECISION", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MAX_BORROWING_FEE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MCR", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PERCENT_DIVISOR", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "REDEMPTION_FEE_FLOOR", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "BORROWING_FEE_FLOOR_", - "type": "uint256" - } - ], - "name": "setBorrowingFeeFloor", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "CCR_", - "type": "uint256" - } - ], - "name": "setCCR", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "MCR_", - "type": "uint256" - } - ], - "name": "setMCR", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "MAX_BORROWING_FEE_", - "type": "uint256" - } - ], - "name": "setMaxBorrowingFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "PERCENT_DIVISOR_", - "type": "uint256" - } - ], - "name": "setPercentDivisor", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "REDEMPTION_FEE_FLOOR_", - "type": "uint256" - } - ], - "name": "setRedemptionFeeFloor", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806108e66022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6107c78061011f6000396000f3fe608060405234801561001057600080fd5b50600436106100e05760003560e01c80636030cc8c116100875780636030cc8c146101965780636d454561146101b3578063794e5724146101d057806380038a0b146101d85780638129fc1c146101f5578063893d20e8146101fd578063a20baee614610221578063f92d343314610229576100e0565b806313af4035146100e5578063240926691461010d57806328d28b5b146101275780632e2465f81461012f578063385a128f1461014c5780634139ad60146101695780634870dd9a146101865780635733d58f1461018e575b600080fd5b61010b600480360360208110156100fb57600080fd5b50356001600160a01b0316610231565b005b610115610298565b60408051918252519081900360200190f35b61011561029e565b61010b6004803603602081101561014557600080fd5b50356102a4565b61010b6004803603602081101561016257600080fd5b5035610304565b61010b6004803603602081101561017f57600080fd5b5035610364565b6101156103c4565b6101156103ca565b61010b600480360360208110156101ac57600080fd5b50356103d0565b61010b600480360360208110156101c957600080fd5b5035610430565b610115610490565b61010b600480360360208110156101ee57600080fd5b5035610496565b61010b6104f6565b61020561062a565b604080516001600160a01b039092168252519081900360200190f35b610115610654565b610115610660565b61023961062a565b6001600160a01b0316336001600160a01b03161461028c576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b61029581610666565b50565b60385481565b60375481565b6102ac61062a565b6001600160a01b0316336001600160a01b0316146102ff576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603655565b61030c61062a565b6001600160a01b0316336001600160a01b03161461035f576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603355565b61036c61062a565b6001600160a01b0316336001600160a01b0316146103bf576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603455565b60355481565b60345481565b6103d861062a565b6001600160a01b0316336001600160a01b03161461042b576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603755565b61043861062a565b6001600160a01b0316336001600160a01b03161461048b576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603555565b60335481565b61049e61062a565b6001600160a01b0316336001600160a01b0316146104f1576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603855565b600054610100900460ff168061050f575061050f61071b565b8061051d575060005460ff16155b6105585760405162461bcd60e51b815260040180806020018281038252602e815260200180610764602e913960400191505060405180910390fd5b600054610100900460ff16158015610583576000805460ff1961ff0019909116610100171660011790555b61058b61062a565b6001600160a01b0316336001600160a01b0316146105de576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b670f43fc2c04ee00006033556714d1120d7b16000060345560c86035556611c37937e08000603681905560375566b1a2bc2ec500006038558015610295576000805461ff001916905550565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b670de0b6b3a764000081565b60365481565b6001600160a01b0381166106ab5760405162461bcd60e51b81526004018080602001828103825260228152602001806107426022913960400191505060405180910390fd5b806001600160a01b03166106bd61062a565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b303b159056fe4f776e61626c653a3a206163636573732064656e6965640000000000000000004f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a26469706673582212209b1fc4ebe36b013e04c33c8b1574ab765154511a9b95fe7e760cf2d686fd7abb64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100e05760003560e01c80636030cc8c116100875780636030cc8c146101965780636d454561146101b3578063794e5724146101d057806380038a0b146101d85780638129fc1c146101f5578063893d20e8146101fd578063a20baee614610221578063f92d343314610229576100e0565b806313af4035146100e5578063240926691461010d57806328d28b5b146101275780632e2465f81461012f578063385a128f1461014c5780634139ad60146101695780634870dd9a146101865780635733d58f1461018e575b600080fd5b61010b600480360360208110156100fb57600080fd5b50356001600160a01b0316610231565b005b610115610298565b60408051918252519081900360200190f35b61011561029e565b61010b6004803603602081101561014557600080fd5b50356102a4565b61010b6004803603602081101561016257600080fd5b5035610304565b61010b6004803603602081101561017f57600080fd5b5035610364565b6101156103c4565b6101156103ca565b61010b600480360360208110156101ac57600080fd5b50356103d0565b61010b600480360360208110156101c957600080fd5b5035610430565b610115610490565b61010b600480360360208110156101ee57600080fd5b5035610496565b61010b6104f6565b61020561062a565b604080516001600160a01b039092168252519081900360200190f35b610115610654565b610115610660565b61023961062a565b6001600160a01b0316336001600160a01b03161461028c576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b61029581610666565b50565b60385481565b60375481565b6102ac61062a565b6001600160a01b0316336001600160a01b0316146102ff576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603655565b61030c61062a565b6001600160a01b0316336001600160a01b03161461035f576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603355565b61036c61062a565b6001600160a01b0316336001600160a01b0316146103bf576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603455565b60355481565b60345481565b6103d861062a565b6001600160a01b0316336001600160a01b03161461042b576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603755565b61043861062a565b6001600160a01b0316336001600160a01b03161461048b576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603555565b60335481565b61049e61062a565b6001600160a01b0316336001600160a01b0316146104f1576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603855565b600054610100900460ff168061050f575061050f61071b565b8061051d575060005460ff16155b6105585760405162461bcd60e51b815260040180806020018281038252602e815260200180610764602e913960400191505060405180910390fd5b600054610100900460ff16158015610583576000805460ff1961ff0019909116610100171660011790555b61058b61062a565b6001600160a01b0316336001600160a01b0316146105de576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b670f43fc2c04ee00006033556714d1120d7b16000060345560c86035556611c37937e08000603681905560375566b1a2bc2ec500006038558015610295576000805461ff001916905550565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b670de0b6b3a764000081565b60365481565b6001600160a01b0381166106ab5760405162461bcd60e51b81526004018080602001828103825260228152602001806107426022913960400191505060405180910390fd5b806001600160a01b03166106bd61062a565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b303b159056fe4f776e61626c653a3a206163636573732064656e6965640000000000000000004f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a26469706673582212209b1fc4ebe36b013e04c33c8b1574ab765154511a9b95fe7e760cf2d686fd7abb64736f6c634300060b0033", - "implementation": "0x4584A4f903821ebC9e83aaC129d5Af12d9024C3b", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file + "_format": "hh-sol-artifact-1", + "contractName": "LiquityBaseParams", + "sourceName": "contracts/LiquityBaseParams.sol", + "address": "0x8B1cB2Ffc9aFe4344503824898098d2E4c883873", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "BORROWING_FEE_FLOOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CCR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DECIMAL_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_BORROWING_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MCR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERCENT_DIVISOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REDEMPTION_FEE_FLOOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "BORROWING_FEE_FLOOR_", + "type": "uint256" + } + ], + "name": "setBorrowingFeeFloor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "CCR_", + "type": "uint256" + } + ], + "name": "setCCR", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "MCR_", + "type": "uint256" + } + ], + "name": "setMCR", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "MAX_BORROWING_FEE_", + "type": "uint256" + } + ], + "name": "setMaxBorrowingFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "PERCENT_DIVISOR_", + "type": "uint256" + } + ], + "name": "setPercentDivisor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "REDEMPTION_FEE_FLOOR_", + "type": "uint256" + } + ], + "name": "setRedemptionFeeFloor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806108e66022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6107c78061011f6000396000f3fe608060405234801561001057600080fd5b50600436106100e05760003560e01c80636030cc8c116100875780636030cc8c146101965780636d454561146101b3578063794e5724146101d057806380038a0b146101d85780638129fc1c146101f5578063893d20e8146101fd578063a20baee614610221578063f92d343314610229576100e0565b806313af4035146100e5578063240926691461010d57806328d28b5b146101275780632e2465f81461012f578063385a128f1461014c5780634139ad60146101695780634870dd9a146101865780635733d58f1461018e575b600080fd5b61010b600480360360208110156100fb57600080fd5b50356001600160a01b0316610231565b005b610115610298565b60408051918252519081900360200190f35b61011561029e565b61010b6004803603602081101561014557600080fd5b50356102a4565b61010b6004803603602081101561016257600080fd5b5035610304565b61010b6004803603602081101561017f57600080fd5b5035610364565b6101156103c4565b6101156103ca565b61010b600480360360208110156101ac57600080fd5b50356103d0565b61010b600480360360208110156101c957600080fd5b5035610430565b610115610490565b61010b600480360360208110156101ee57600080fd5b5035610496565b61010b6104f6565b61020561062a565b604080516001600160a01b039092168252519081900360200190f35b610115610654565b610115610660565b61023961062a565b6001600160a01b0316336001600160a01b03161461028c576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b61029581610666565b50565b60385481565b60375481565b6102ac61062a565b6001600160a01b0316336001600160a01b0316146102ff576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603655565b61030c61062a565b6001600160a01b0316336001600160a01b03161461035f576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603355565b61036c61062a565b6001600160a01b0316336001600160a01b0316146103bf576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603455565b60355481565b60345481565b6103d861062a565b6001600160a01b0316336001600160a01b03161461042b576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603755565b61043861062a565b6001600160a01b0316336001600160a01b03161461048b576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603555565b60335481565b61049e61062a565b6001600160a01b0316336001600160a01b0316146104f1576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603855565b600054610100900460ff168061050f575061050f61071b565b8061051d575060005460ff16155b6105585760405162461bcd60e51b815260040180806020018281038252602e815260200180610764602e913960400191505060405180910390fd5b600054610100900460ff16158015610583576000805460ff1961ff0019909116610100171660011790555b61058b61062a565b6001600160a01b0316336001600160a01b0316146105de576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b670f43fc2c04ee00006033556714d1120d7b16000060345560c86035556611c37937e08000603681905560375566b1a2bc2ec500006038558015610295576000805461ff001916905550565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b670de0b6b3a764000081565b60365481565b6001600160a01b0381166106ab5760405162461bcd60e51b81526004018080602001828103825260228152602001806107426022913960400191505060405180910390fd5b806001600160a01b03166106bd61062a565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b303b159056fe4f776e61626c653a3a206163636573732064656e6965640000000000000000004f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a26469706673582212209b1fc4ebe36b013e04c33c8b1574ab765154511a9b95fe7e760cf2d686fd7abb64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100e05760003560e01c80636030cc8c116100875780636030cc8c146101965780636d454561146101b3578063794e5724146101d057806380038a0b146101d85780638129fc1c146101f5578063893d20e8146101fd578063a20baee614610221578063f92d343314610229576100e0565b806313af4035146100e5578063240926691461010d57806328d28b5b146101275780632e2465f81461012f578063385a128f1461014c5780634139ad60146101695780634870dd9a146101865780635733d58f1461018e575b600080fd5b61010b600480360360208110156100fb57600080fd5b50356001600160a01b0316610231565b005b610115610298565b60408051918252519081900360200190f35b61011561029e565b61010b6004803603602081101561014557600080fd5b50356102a4565b61010b6004803603602081101561016257600080fd5b5035610304565b61010b6004803603602081101561017f57600080fd5b5035610364565b6101156103c4565b6101156103ca565b61010b600480360360208110156101ac57600080fd5b50356103d0565b61010b600480360360208110156101c957600080fd5b5035610430565b610115610490565b61010b600480360360208110156101ee57600080fd5b5035610496565b61010b6104f6565b61020561062a565b604080516001600160a01b039092168252519081900360200190f35b610115610654565b610115610660565b61023961062a565b6001600160a01b0316336001600160a01b03161461028c576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b61029581610666565b50565b60385481565b60375481565b6102ac61062a565b6001600160a01b0316336001600160a01b0316146102ff576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603655565b61030c61062a565b6001600160a01b0316336001600160a01b03161461035f576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603355565b61036c61062a565b6001600160a01b0316336001600160a01b0316146103bf576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603455565b60355481565b60345481565b6103d861062a565b6001600160a01b0316336001600160a01b03161461042b576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603755565b61043861062a565b6001600160a01b0316336001600160a01b03161461048b576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603555565b60335481565b61049e61062a565b6001600160a01b0316336001600160a01b0316146104f1576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b603855565b600054610100900460ff168061050f575061050f61071b565b8061051d575060005460ff16155b6105585760405162461bcd60e51b815260040180806020018281038252602e815260200180610764602e913960400191505060405180910390fd5b600054610100900460ff16158015610583576000805460ff1961ff0019909116610100171660011790555b61058b61062a565b6001600160a01b0316336001600160a01b0316146105de576040805162461bcd60e51b81526020600482015260176024820152600080516020610722833981519152604482015290519081900360640190fd5b670f43fc2c04ee00006033556714d1120d7b16000060345560c86035556611c37937e08000603681905560375566b1a2bc2ec500006038558015610295576000805461ff001916905550565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b670de0b6b3a764000081565b60365481565b6001600160a01b0381166106ab5760405162461bcd60e51b81526004018080602001828103825260228152602001806107426022913960400191505060405180910390fd5b806001600160a01b03166106bd61062a565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b303b159056fe4f776e61626c653a3a206163636573732064656e6965640000000000000000004f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a26469706673582212209b1fc4ebe36b013e04c33c8b1574ab765154511a9b95fe7e760cf2d686fd7abb64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/LiquityBaseParams_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/LiquityBaseParams_Proxy.json index f457080a..bdcf3d0b 100644 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/LiquityBaseParams_Proxy.json +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/LiquityBaseParams_Proxy.json @@ -1,110 +1,110 @@ { - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "address": "0x8B1cB2Ffc9aFe4344503824898098d2E4c883873", - "abi": [ - { - "anonymous": false, - "inputs": [ + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "address": "0x8B1cB2Ffc9aFe4344503824898098d2E4c883873", + "abi": [ { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "type": "event" }, { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" + "stateMutability": "payable", + "type": "fallback" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { - "internalType": "address", - "name": "_owner", - "type": "address" + "stateMutability": "payable", + "type": "receive" } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/packages/contracts/deployment/deployments/rskSovrynMainnet/multiTroveGetter.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/MultiTroveGetter.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynMainnet/multiTroveGetter.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/MultiTroveGetter.json index eec6f034..8d13b2dd 100644 --- a/packages/contracts/deployment/deployments/rskSovrynMainnet/multiTroveGetter.json +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/MultiTroveGetter.json @@ -1,4 +1,5 @@ { + "address": "0x3adF6FAe3C494F0CF151abA537E60fCCbAC0e0a0", "_format": "hh-sol-artifact-1", "contractName": "MultiTroveGetter", "sourceName": "contracts/MultiTroveGetter.sol", @@ -152,6 +153,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610143565b6001600160a01b0381166100575760405162461bcd60e51b815260040161004e90610101565b60405180910390fd5b6001600160a01b0381166100726001600160e01b036100c516565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360006040516100b5906100e4565b6040519081900390209190915550565b6000806040516100d4906100e4565b6040519081900390205492915050565b7035b2bc9737bbb730b136329737bbb732b960791b815260110190565b60208082526022908201527f4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265604082015261737360f01b606082015260800190565b610dc7806101526000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c806313af4035146100675780633d83908a1461007c578063893d20e81461009a57806390107afe146100a2578063ae918754146100b5578063b90bce45146100bd575b600080fd5b61007a610075366004610b20565b6100dd565b005b61008461012a565b6040516100919190610c74565b60405180910390f35b610084610139565b61007a6100b0366004610b5f565b610158565b6100846101be565b6100d06100cb366004610b97565b6101cd565b6040516100919190610c88565b6100e5610139565b6001600160a01b0316336001600160a01b03161461011e5760405162461bcd60e51b815260040161011590610d4b565b60405180910390fd5b610127816102f0565b50565b6000546001600160a01b031681565b60008060405161014890610c57565b6040519081900390205492915050565b610160610139565b6001600160a01b0316336001600160a01b0316146101905760405162461bcd60e51b815260040161011590610d4b565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6001546001600160a01b031681565b6060600080600085126101e5575083905060016101f3565b846001016000039150600090505b6001546040805163de8fa43160e01b815290516000926001600160a01b03169163de8fa431916004808301926020929190829003018186803b15801561023857600080fd5b505afa15801561024c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102709190610bb8565b90508083106102b25760408051600080825260208201909252906102aa565b610297610ae1565b81526020019060019003908161028f5790505b5093506102e7565b828103808611156102c1578095505b82156102d8576102d1848761037b565b94506102e5565b6102e28487610732565b94505b505b50505092915050565b6001600160a01b0381166103165760405162461bcd60e51b815260040161011590610d09565b806001600160a01b0316610328610139565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600060405161036b90610c57565b6040519081900390209190915550565b60606000600160009054906101000a90046001600160a01b03166001600160a01b0316631e2231436040518163ffffffff1660e01b815260040160206040518083038186803b1580156103cd57600080fd5b505afa1580156103e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104059190610b43565b905060005b8481101561049c5760015460405163765e015960e01b81526001600160a01b039091169063765e015990610442908590600401610c74565b60206040518083038186803b15801561045a57600080fd5b505afa15801561046e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104929190610b43565b915060010161040a565b508267ffffffffffffffff811180156104b457600080fd5b506040519080825280602002602001820160405280156104ee57816020015b6104db610ae1565b8152602001906001900390816104d35790505b50915060005b8381101561072a578183828151811061050957fe5b60209081029190910101516001600160a01b039182169052600054604051630ddec86760e31b8152911690636ef6433890610548908590600401610c74565b60a06040518083038186803b15801561056057600080fd5b505afa158015610574573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105989190610bf3565b9050508584815181106105a757fe5b60200260200101516020018685815181106105be57fe5b60200260200101516040018786815181106105d557fe5b60209081029190910101516060019290925291905252600054604051630b39e3cd60e11b81526001600160a01b0390911690631673c79a9061061b908590600401610c74565b604080518083038186803b15801561063257600080fd5b505afa158015610646573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066a9190610bd0565b84838151811061067657fe5b602002602001015160800185848151811061068d57fe5b602090810291909101015160a001919091525260015460405163765e015960e01b81526001600160a01b039091169063765e0159906106d0908590600401610c74565b60206040518083038186803b1580156106e857600080fd5b505afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190610b43565b91506001016104f4565b505092915050565b60606000600160009054906101000a90046001600160a01b03166001600160a01b0316634d6228316040518163ffffffff1660e01b815260040160206040518083038186803b15801561078457600080fd5b505afa158015610798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107bc9190610b43565b905060005b8481101561085357600154604051632dc9c0eb60e21b81526001600160a01b039091169063b72703ac906107f9908590600401610c74565b60206040518083038186803b15801561081157600080fd5b505afa158015610825573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108499190610b43565b91506001016107c1565b508267ffffffffffffffff8111801561086b57600080fd5b506040519080825280602002602001820160405280156108a557816020015b610892610ae1565b81526020019060019003908161088a5790505b50915060005b8381101561072a57818382815181106108c057fe5b60209081029190910101516001600160a01b039182169052600054604051630ddec86760e31b8152911690636ef64338906108ff908590600401610c74565b60a06040518083038186803b15801561091757600080fd5b505afa15801561092b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094f9190610bf3565b90505085848151811061095e57fe5b602002602001015160200186858151811061097557fe5b602002602001015160400187868151811061098c57fe5b60209081029190910101516060019290925291905252600054604051630b39e3cd60e11b81526001600160a01b0390911690631673c79a906109d2908590600401610c74565b604080518083038186803b1580156109e957600080fd5b505afa1580156109fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a219190610bd0565b848381518110610a2d57fe5b6020026020010151608001858481518110610a4457fe5b602090810291909101015160a0019190915252600154604051632dc9c0eb60e21b81526001600160a01b039091169063b72703ac90610a87908590600401610c74565b60206040518083038186803b158015610a9f57600080fd5b505afa158015610ab3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad79190610b43565b91506001016108ab565b6040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b600060208284031215610b31578081fd5b8135610b3c81610d7c565b9392505050565b600060208284031215610b54578081fd5b8151610b3c81610d7c565b60008060408385031215610b71578081fd5b8235610b7c81610d7c565b91506020830135610b8c81610d7c565b809150509250929050565b60008060408385031215610ba9578182fd5b50508035926020909101359150565b600060208284031215610bc9578081fd5b5051919050565b60008060408385031215610be2578182fd5b505080516020909101519092909150565b600080600080600060a08688031215610c0a578081fd5b855194506020860151935060408601519250606086015160058110610c2d578182fd5b60808701519092506001600160801b0381168114610c49578182fd5b809150509295509295909350565b7035b2bc9737bbb730b136329737bbb732b960791b815260110190565b6001600160a01b0391909116815260200190565b602080825282518282018190526000919060409081850190868401855b82811015610cfc57815180516001600160a01b0316855286810151878601528581015186860152606080820151908601526080808201519086015260a0908101519085015260c09093019290850190600101610ca5565b5091979650505050505050565b60208082526022908201527f4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265604082015261737360f01b606082015260800190565b60208082526017908201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604082015260600190565b6001600160a01b038116811461012757600080fdfea2646970667358221220659f4dc0a25b28f8b8a559e447b60b3ff6f5f3d8084d3627ee2f90efdfe1a25864736f6c634300060b0033", "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100625760003560e01c806313af4035146100675780633d83908a1461007c578063893d20e81461009a57806390107afe146100a2578063ae918754146100b5578063b90bce45146100bd575b600080fd5b61007a610075366004610b20565b6100dd565b005b61008461012a565b6040516100919190610c74565b60405180910390f35b610084610139565b61007a6100b0366004610b5f565b610158565b6100846101be565b6100d06100cb366004610b97565b6101cd565b6040516100919190610c88565b6100e5610139565b6001600160a01b0316336001600160a01b03161461011e5760405162461bcd60e51b815260040161011590610d4b565b60405180910390fd5b610127816102f0565b50565b6000546001600160a01b031681565b60008060405161014890610c57565b6040519081900390205492915050565b610160610139565b6001600160a01b0316336001600160a01b0316146101905760405162461bcd60e51b815260040161011590610d4b565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6001546001600160a01b031681565b6060600080600085126101e5575083905060016101f3565b846001016000039150600090505b6001546040805163de8fa43160e01b815290516000926001600160a01b03169163de8fa431916004808301926020929190829003018186803b15801561023857600080fd5b505afa15801561024c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102709190610bb8565b90508083106102b25760408051600080825260208201909252906102aa565b610297610ae1565b81526020019060019003908161028f5790505b5093506102e7565b828103808611156102c1578095505b82156102d8576102d1848761037b565b94506102e5565b6102e28487610732565b94505b505b50505092915050565b6001600160a01b0381166103165760405162461bcd60e51b815260040161011590610d09565b806001600160a01b0316610328610139565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600060405161036b90610c57565b6040519081900390209190915550565b60606000600160009054906101000a90046001600160a01b03166001600160a01b0316631e2231436040518163ffffffff1660e01b815260040160206040518083038186803b1580156103cd57600080fd5b505afa1580156103e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104059190610b43565b905060005b8481101561049c5760015460405163765e015960e01b81526001600160a01b039091169063765e015990610442908590600401610c74565b60206040518083038186803b15801561045a57600080fd5b505afa15801561046e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104929190610b43565b915060010161040a565b508267ffffffffffffffff811180156104b457600080fd5b506040519080825280602002602001820160405280156104ee57816020015b6104db610ae1565b8152602001906001900390816104d35790505b50915060005b8381101561072a578183828151811061050957fe5b60209081029190910101516001600160a01b039182169052600054604051630ddec86760e31b8152911690636ef6433890610548908590600401610c74565b60a06040518083038186803b15801561056057600080fd5b505afa158015610574573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105989190610bf3565b9050508584815181106105a757fe5b60200260200101516020018685815181106105be57fe5b60200260200101516040018786815181106105d557fe5b60209081029190910101516060019290925291905252600054604051630b39e3cd60e11b81526001600160a01b0390911690631673c79a9061061b908590600401610c74565b604080518083038186803b15801561063257600080fd5b505afa158015610646573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066a9190610bd0565b84838151811061067657fe5b602002602001015160800185848151811061068d57fe5b602090810291909101015160a001919091525260015460405163765e015960e01b81526001600160a01b039091169063765e0159906106d0908590600401610c74565b60206040518083038186803b1580156106e857600080fd5b505afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190610b43565b91506001016104f4565b505092915050565b60606000600160009054906101000a90046001600160a01b03166001600160a01b0316634d6228316040518163ffffffff1660e01b815260040160206040518083038186803b15801561078457600080fd5b505afa158015610798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107bc9190610b43565b905060005b8481101561085357600154604051632dc9c0eb60e21b81526001600160a01b039091169063b72703ac906107f9908590600401610c74565b60206040518083038186803b15801561081157600080fd5b505afa158015610825573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108499190610b43565b91506001016107c1565b508267ffffffffffffffff8111801561086b57600080fd5b506040519080825280602002602001820160405280156108a557816020015b610892610ae1565b81526020019060019003908161088a5790505b50915060005b8381101561072a57818382815181106108c057fe5b60209081029190910101516001600160a01b039182169052600054604051630ddec86760e31b8152911690636ef64338906108ff908590600401610c74565b60a06040518083038186803b15801561091757600080fd5b505afa15801561092b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094f9190610bf3565b90505085848151811061095e57fe5b602002602001015160200186858151811061097557fe5b602002602001015160400187868151811061098c57fe5b60209081029190910101516060019290925291905252600054604051630b39e3cd60e11b81526001600160a01b0390911690631673c79a906109d2908590600401610c74565b604080518083038186803b1580156109e957600080fd5b505afa1580156109fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a219190610bd0565b848381518110610a2d57fe5b6020026020010151608001858481518110610a4457fe5b602090810291909101015160a0019190915252600154604051632dc9c0eb60e21b81526001600160a01b039091169063b72703ac90610a87908590600401610c74565b60206040518083038186803b158015610a9f57600080fd5b505afa158015610ab3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad79190610b43565b91506001016108ab565b6040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b600060208284031215610b31578081fd5b8135610b3c81610d7c565b9392505050565b600060208284031215610b54578081fd5b8151610b3c81610d7c565b60008060408385031215610b71578081fd5b8235610b7c81610d7c565b91506020830135610b8c81610d7c565b809150509250929050565b60008060408385031215610ba9578182fd5b50508035926020909101359150565b600060208284031215610bc9578081fd5b5051919050565b60008060408385031215610be2578182fd5b505080516020909101519092909150565b600080600080600060a08688031215610c0a578081fd5b855194506020860151935060408601519250606086015160058110610c2d578182fd5b60808701519092506001600160801b0381168114610c49578182fd5b809150509295509295909350565b7035b2bc9737bbb730b136329737bbb732b960791b815260110190565b6001600160a01b0391909116815260200190565b602080825282518282018190526000919060409081850190868401855b82811015610cfc57815180516001600160a01b0316855286810151878601528581015186860152606080820151908601526080808201519086015260a0908101519085015260c09093019290850190600101610ca5565b5091979650505050505050565b60208082526022908201527f4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265604082015261737360f01b606082015260800190565b60208082526017908201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604082015260600190565b6001600160a01b038116811461012757600080fdfea2646970667358221220659f4dc0a25b28f8b8a559e447b60b3ff6f5f3d8084d3627ee2f90efdfe1a25864736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0xF265a169191348c02829B62650B025BdeAf00AE4" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/MultiTroveGetter_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/MultiTroveGetter_Proxy.json new file mode 100644 index 00000000..dcd7e880 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/MultiTroveGetter_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0x3adF6FAe3C494F0CF151abA537E60fCCbAC0e0a0", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/sortedTroves.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/SortedTroves.json similarity index 99% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/sortedTroves.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/SortedTroves.json index 630a9dda..6b1b6fc9 100644 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/sortedTroves.json +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/SortedTroves.json @@ -1,4 +1,5 @@ { + "address": "0x9414974B00A4E5d8437E6402d44821ee4C2A08F1", "_format": "hh-sol-artifact-1", "contractName": "SortedTroves", "sourceName": "contracts/SortedTroves.sol", @@ -480,6 +481,5 @@ "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b8152600401808060200182810382526022815260200180611b186022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6119f98061011f6000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806363e1d57c116100b8578063a3f4df7e1161007c578063a3f4df7e14610388578063b72703ac14610405578063b7f8cf9b1461042b578063babd3d9a14610433578063de8fa4311461043b578063f376d7981461044357610137565b806363e1d57c146102fe578063681fe70c1461031857806373d4a13a14610320578063765e01591461035a578063893d20e81461038057610137565b80633fce12d5116100ff5780633fce12d5146101f2578063416980dc1461023a57806346f7cf87146102945780634d622831146102d05780635dbe47e8146102d857610137565b806313af40351461013c5780631e2231431461016457806329092d0e146101885780632be21260146101ae5780633d83908a146101ea575b600080fd5b6101626004803603602081101561015257600080fd5b50356001600160a01b0316610477565b005b61016c6104ea565b604080516001600160a01b039092168252519081900360200190f35b6101626004803603602081101561019e57600080fd5b50356001600160a01b03166104f9565b610162600480360360808110156101c457600080fd5b506001600160a01b0381358116916020810135916040820135811691606001351661050a565b61016c6105bf565b6102266004803603606081101561020857600080fd5b508035906001600160a01b03602082013581169160400135166105ce565b604080519115158252519081900360200190f35b61026e6004803603606081101561025057600080fd5b508035906001600160a01b03602082013581169160400135166105f1565b604080516001600160a01b03938416815291909216602082015281519081900390910190f35b610162600480360360808110156102aa57600080fd5b506001600160a01b0381358116916020810135916040820135811691606001351661061b565b61016c610630565b610226600480360360208110156102ee57600080fd5b50356001600160a01b031661063f565b61030661065d565b60408051918252519081900360200190f35b610226610663565b61032861066a565b604080516001600160a01b03958616815293909416602084015282840191909152606082015290519081900360800190f35b61016c6004803603602081101561037057600080fd5b50356001600160a01b0316610689565b61016c6106ac565b6103906106d6565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103ca5781810151838201526020016103b2565b50505050905090810190601f1680156103f75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61016c6004803603602081101561041b57600080fd5b50356001600160a01b03166106fe565b61016c61071f565b61022661072e565b610306610738565b6101626004803603606081101561045957600080fd5b508035906001600160a01b036020820135811691604001351661073e565b61047f6106ac565b6001600160a01b0316336001600160a01b0316146104de576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6104e78161089c565b50565b6002546001600160a01b031690565b610501610951565b6104e78161099c565b6001546001600160a01b031661051f81610bd0565b6105288561063f565b6105635760405162461bcd60e51b815260040180806020018281038252602a8152602001806118da602a913960400191505060405180910390fd5b600084116105a25760405162461bcd60e51b81526004018080602001828103825260238152602001806119a16023913960400191505060405180910390fd5b6105ab8561099c565b6105b88186868686610c2c565b5050505050565b6001546001600160a01b031681565b6001546000906105e9906001600160a01b0316858585610fb0565b949350505050565b600154600090819061060e906001600160a01b0316868686611257565b915091505b935093915050565b6001546001600160a01b03166105ab81610bd0565b6003546001600160a01b031690565b6001600160a01b031660009081526006602052604090205460ff1690565b60045490565b6005541590565b6002546003546004546005546001600160a01b03938416939092169184565b6001600160a01b0390811660009081526006602052604090205461010090041690565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6040518060400160405280600c81526020016b536f7274656454726f76657360a01b81525081565b6001600160a01b039081166000908152600660205260409020600101541690565b6000546001600160a01b031681565b6004546005541490565b60055490565b6107466106ac565b6001600160a01b0316336001600160a01b0316146107a5576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b600083116107e45760405162461bcd60e51b81526004018080602001828103825260228152602001806119046022913960400191505060405180910390fd5b6107ed82611444565b6107f681611444565b6004839055600180546001600160a01b038085166001600160a01b03199283168117909355600080549185169190921617905560408051918252517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038316815290517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1505050565b6001600160a01b0381166108e15760405162461bcd60e51b81526004018080602001828103825260228152602001806119526022913960400191505060405180910390fd5b806001600160a01b03166108f36106ac565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001546001600160a01b0316331461099a5760405162461bcd60e51b815260040180806020018281038252602c815260200180611926602c913960400191505060405180910390fd5b565b6109a58161063f565b6109e05760405162461bcd60e51b815260040180806020018281038252602a8152602001806118da602a913960400191505060405180910390fd5b60055460011015610b26576002546001600160a01b0382811691161415610a4f576001600160a01b03818116600090815260066020526040808220546002805461010090920485166001600160a01b031992831617908190559093168252902060010180549091169055610b21565b6003546001600160a01b0382811691161415610ab6576001600160a01b0380821660009081526006602052604080822060010154600380546001600160a01b03191691851691909117908190559092168152208054610100600160a81b0319169055610b21565b6001600160a01b038082166000908152600660205260408082208054600180830180548716865284862080546101009485900489168502610100600160a81b03199091161790555492549190910485168452919092200180546001600160a01b031916919092161790555b610b43565b600280546001600160a01b03199081169091556003805490911690555b6001600160a01b038116600090815260066020526040902080546001600160a81b0319168155600190810180546001600160a01b0319169055600554610b8e9163ffffffff6114f716565b600555604080516001600160a01b038316815290517fcfc24166db4bb677e857cacabd1541fb2b30645021b27c5130419589b84db52b9181900360200190a150565b6000546001600160a01b0316331480610bf15750336001600160a01b038216145b6104e75760405162461bcd60e51b815260040180806020018281038252602d815260200180611974602d913960400191505060405180910390fd5b610c3461072e565b15610c86576040805162461bcd60e51b815260206004820152601a60248201527f536f7274656454726f7665733a204c6973742069732066756c6c000000000000604482015290519081900360640190fd5b610c8f8461063f565b15610ccb5760405162461bcd60e51b815260040180806020018281038252602c8152602001806118ae602c913960400191505060405180910390fd5b6001600160a01b038416610d26576040805162461bcd60e51b815260206004820152601f60248201527f536f7274656454726f7665733a2049642063616e6e6f74206265207a65726f00604482015290519081900360640190fd5b60008311610d655760405162461bcd60e51b81526004018080602001828103825260238152602001806119a16023913960400191505060405180910390fd5b8181610d7387868484610fb0565b610d8957610d8387868484611257565b90925090505b6001600160a01b038087166000908152600660205260409020805460ff191660011790558216158015610dc357506001600160a01b038116155b15610df857600280546001600160a01b0388166001600160a01b03199182168117909255600380549091169091179055610f4c565b6001600160a01b038216610e6c57600280546001600160a01b03888116600081815260066020526040808220805495851661010002610100600160a81b0319909616959095179094558454909216825291902060010180546001600160a01b03199081168317909155825416179055610f4c565b6001600160a01b038116610edc57600380546001600160a01b0388811660008181526006602052604080822060010180549585166001600160a01b031996871617905585549093168152919091208054610100600160a81b03191661010083021790558254909116179055610f4c565b6001600160a01b038087166000818152600660205260408082208054858716610100818102610100600160a81b031993841617845560019384018054988b166001600160a01b0319998a168117909155865284862080549188029190931617909155835291200180549092161790555b600554610f6090600163ffffffff61154016565b600555604080516001600160a01b03881681526020810187905281517fe02b43adbee0c123de070a04554a71877a0007e2fc161466299cae3c094fe82f929181900390910190a150505050505050565b60006001600160a01b038316158015610fd057506001600160a01b038216155b15610fe457610fdd610663565b90506105e9565b6001600160a01b038316611096576002546001600160a01b038381169116148015610fdd5750846001600160a01b031663b0d8e181836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561106057600080fd5b505afa158015611074573d6000803e3d6000fd5b505050506040513d602081101561108a57600080fd5b505184101590506105e9565b6001600160a01b038216611148576003546001600160a01b038481169116148015610fdd5750846001600160a01b031663b0d8e181846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561111257600080fd5b505afa158015611126573d6000803e3d6000fd5b505050506040513d602081101561113c57600080fd5b505184111590506105e9565b6001600160a01b03838116600090815260066020526040902054610100900481169083161480156111fa575083856001600160a01b031663b0d8e181856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156111cb57600080fd5b505afa1580156111df573d6000803e3d6000fd5b505050506040513d60208110156111f557600080fd5b505110155b8015610fdd5750846001600160a01b031663b0d8e181836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561106057600080fd5b60008083836001600160a01b0382161561130a576112748261063f565b15806113005750876001600160a01b031663b0d8e181836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156112d157600080fd5b505afa1580156112e5573d6000803e3d6000fd5b505050506040513d60208110156112fb57600080fd5b505187115b1561130a57600091505b6001600160a01b038116156113b7576113228161063f565b15806113ae5750876001600160a01b031663b0d8e181826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561137f57600080fd5b505afa158015611393573d6000803e3d6000fd5b505050506040513d60208110156113a957600080fd5b505187105b156113b7575060005b6001600160a01b0382161580156113d557506001600160a01b038116155b156113fe576002546113f390899089906001600160a01b031661159a565b93509350505061143b565b6001600160a01b038216611417576113f38888836116db565b6001600160a01b038116611430576113f388888461159a565b6113f388888461159a565b94509492505050565b6001600160a01b03811661149f576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806114f3576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b600061153983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611816565b9392505050565b600082820183811015611539576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60025460009081906001600160a01b03848116911614801561163d5750846001600160a01b031663b0d8e181846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561160d57600080fd5b505afa158015611621573d6000803e3d6000fd5b505050506040513d602081101561163757600080fd5b50518410155b1561164d57506000905081610613565b6001600160a01b038084166000908152600660205260409020548491610100909104165b6001600160a01b03821615801590611692575061169087878484610fb0565b155b156116cf57506001600160a01b03908116600090815260066020526040808220546101009081900484168084529190922054909291900416611671565b90969095509350505050565b60035460009081906001600160a01b03848116911614801561177e5750846001600160a01b031663b0d8e181846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561174e57600080fd5b505afa158015611762573d6000803e3d6000fd5b505050506040513d602081101561177857600080fd5b50518411155b1561178e57508190506000610613565b6001600160a01b038084166000908152600660205260409020600101548491165b6001600160a01b038216158015906117d057506117ce87878385610fb0565b155b1561180b57506001600160a01b03908116600090815260066020526040808220600190810154841680845291909220909101549091166117af565b969095509350505050565b600081848411156118a55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561186a578181015183820152602001611852565b50505050905090810190601f1680156118975780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe536f7274656454726f7665733a204c69737420616c726561647920636f6e7461696e7320746865206e6f6465536f7274656454726f7665733a204c69737420646f6573206e6f7420636f6e7461696e20746865206964536f7274656454726f7665733a2053697a652063616ee2809974206265207a65726f536f7274656454726f7665733a2043616c6c6572206973206e6f74207468652054726f76654d616e616765724f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373536f7274656454726f7665733a2043616c6c6572206973206e65697468657220424f206e6f722054726f76654d536f7274656454726f7665733a204e494352206d75737420626520706f736974697665a264697066735822122032b466fa1ae0f54c795858e19523f6f623b02846824d1e4a37750d801b21599064736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101375760003560e01c806363e1d57c116100b8578063a3f4df7e1161007c578063a3f4df7e14610388578063b72703ac14610405578063b7f8cf9b1461042b578063babd3d9a14610433578063de8fa4311461043b578063f376d7981461044357610137565b806363e1d57c146102fe578063681fe70c1461031857806373d4a13a14610320578063765e01591461035a578063893d20e81461038057610137565b80633fce12d5116100ff5780633fce12d5146101f2578063416980dc1461023a57806346f7cf87146102945780634d622831146102d05780635dbe47e8146102d857610137565b806313af40351461013c5780631e2231431461016457806329092d0e146101885780632be21260146101ae5780633d83908a146101ea575b600080fd5b6101626004803603602081101561015257600080fd5b50356001600160a01b0316610477565b005b61016c6104ea565b604080516001600160a01b039092168252519081900360200190f35b6101626004803603602081101561019e57600080fd5b50356001600160a01b03166104f9565b610162600480360360808110156101c457600080fd5b506001600160a01b0381358116916020810135916040820135811691606001351661050a565b61016c6105bf565b6102266004803603606081101561020857600080fd5b508035906001600160a01b03602082013581169160400135166105ce565b604080519115158252519081900360200190f35b61026e6004803603606081101561025057600080fd5b508035906001600160a01b03602082013581169160400135166105f1565b604080516001600160a01b03938416815291909216602082015281519081900390910190f35b610162600480360360808110156102aa57600080fd5b506001600160a01b0381358116916020810135916040820135811691606001351661061b565b61016c610630565b610226600480360360208110156102ee57600080fd5b50356001600160a01b031661063f565b61030661065d565b60408051918252519081900360200190f35b610226610663565b61032861066a565b604080516001600160a01b03958616815293909416602084015282840191909152606082015290519081900360800190f35b61016c6004803603602081101561037057600080fd5b50356001600160a01b0316610689565b61016c6106ac565b6103906106d6565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103ca5781810151838201526020016103b2565b50505050905090810190601f1680156103f75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61016c6004803603602081101561041b57600080fd5b50356001600160a01b03166106fe565b61016c61071f565b61022661072e565b610306610738565b6101626004803603606081101561045957600080fd5b508035906001600160a01b036020820135811691604001351661073e565b61047f6106ac565b6001600160a01b0316336001600160a01b0316146104de576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6104e78161089c565b50565b6002546001600160a01b031690565b610501610951565b6104e78161099c565b6001546001600160a01b031661051f81610bd0565b6105288561063f565b6105635760405162461bcd60e51b815260040180806020018281038252602a8152602001806118da602a913960400191505060405180910390fd5b600084116105a25760405162461bcd60e51b81526004018080602001828103825260238152602001806119a16023913960400191505060405180910390fd5b6105ab8561099c565b6105b88186868686610c2c565b5050505050565b6001546001600160a01b031681565b6001546000906105e9906001600160a01b0316858585610fb0565b949350505050565b600154600090819061060e906001600160a01b0316868686611257565b915091505b935093915050565b6001546001600160a01b03166105ab81610bd0565b6003546001600160a01b031690565b6001600160a01b031660009081526006602052604090205460ff1690565b60045490565b6005541590565b6002546003546004546005546001600160a01b03938416939092169184565b6001600160a01b0390811660009081526006602052604090205461010090041690565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6040518060400160405280600c81526020016b536f7274656454726f76657360a01b81525081565b6001600160a01b039081166000908152600660205260409020600101541690565b6000546001600160a01b031681565b6004546005541490565b60055490565b6107466106ac565b6001600160a01b0316336001600160a01b0316146107a5576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b600083116107e45760405162461bcd60e51b81526004018080602001828103825260228152602001806119046022913960400191505060405180910390fd5b6107ed82611444565b6107f681611444565b6004839055600180546001600160a01b038085166001600160a01b03199283168117909355600080549185169190921617905560408051918252517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a56789181900360200190a1604080516001600160a01b038316815290517f3ca631ffcd2a9b5d9ae18543fc82f58eb4ca33af9e6ab01b7a8e95331e6ed9859181900360200190a1505050565b6001600160a01b0381166108e15760405162461bcd60e51b81526004018080602001828103825260228152602001806119526022913960400191505060405180910390fd5b806001600160a01b03166108f36106ac565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001546001600160a01b0316331461099a5760405162461bcd60e51b815260040180806020018281038252602c815260200180611926602c913960400191505060405180910390fd5b565b6109a58161063f565b6109e05760405162461bcd60e51b815260040180806020018281038252602a8152602001806118da602a913960400191505060405180910390fd5b60055460011015610b26576002546001600160a01b0382811691161415610a4f576001600160a01b03818116600090815260066020526040808220546002805461010090920485166001600160a01b031992831617908190559093168252902060010180549091169055610b21565b6003546001600160a01b0382811691161415610ab6576001600160a01b0380821660009081526006602052604080822060010154600380546001600160a01b03191691851691909117908190559092168152208054610100600160a81b0319169055610b21565b6001600160a01b038082166000908152600660205260408082208054600180830180548716865284862080546101009485900489168502610100600160a81b03199091161790555492549190910485168452919092200180546001600160a01b031916919092161790555b610b43565b600280546001600160a01b03199081169091556003805490911690555b6001600160a01b038116600090815260066020526040902080546001600160a81b0319168155600190810180546001600160a01b0319169055600554610b8e9163ffffffff6114f716565b600555604080516001600160a01b038316815290517fcfc24166db4bb677e857cacabd1541fb2b30645021b27c5130419589b84db52b9181900360200190a150565b6000546001600160a01b0316331480610bf15750336001600160a01b038216145b6104e75760405162461bcd60e51b815260040180806020018281038252602d815260200180611974602d913960400191505060405180910390fd5b610c3461072e565b15610c86576040805162461bcd60e51b815260206004820152601a60248201527f536f7274656454726f7665733a204c6973742069732066756c6c000000000000604482015290519081900360640190fd5b610c8f8461063f565b15610ccb5760405162461bcd60e51b815260040180806020018281038252602c8152602001806118ae602c913960400191505060405180910390fd5b6001600160a01b038416610d26576040805162461bcd60e51b815260206004820152601f60248201527f536f7274656454726f7665733a2049642063616e6e6f74206265207a65726f00604482015290519081900360640190fd5b60008311610d655760405162461bcd60e51b81526004018080602001828103825260238152602001806119a16023913960400191505060405180910390fd5b8181610d7387868484610fb0565b610d8957610d8387868484611257565b90925090505b6001600160a01b038087166000908152600660205260409020805460ff191660011790558216158015610dc357506001600160a01b038116155b15610df857600280546001600160a01b0388166001600160a01b03199182168117909255600380549091169091179055610f4c565b6001600160a01b038216610e6c57600280546001600160a01b03888116600081815260066020526040808220805495851661010002610100600160a81b0319909616959095179094558454909216825291902060010180546001600160a01b03199081168317909155825416179055610f4c565b6001600160a01b038116610edc57600380546001600160a01b0388811660008181526006602052604080822060010180549585166001600160a01b031996871617905585549093168152919091208054610100600160a81b03191661010083021790558254909116179055610f4c565b6001600160a01b038087166000818152600660205260408082208054858716610100818102610100600160a81b031993841617845560019384018054988b166001600160a01b0319998a168117909155865284862080549188029190931617909155835291200180549092161790555b600554610f6090600163ffffffff61154016565b600555604080516001600160a01b03881681526020810187905281517fe02b43adbee0c123de070a04554a71877a0007e2fc161466299cae3c094fe82f929181900390910190a150505050505050565b60006001600160a01b038316158015610fd057506001600160a01b038216155b15610fe457610fdd610663565b90506105e9565b6001600160a01b038316611096576002546001600160a01b038381169116148015610fdd5750846001600160a01b031663b0d8e181836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561106057600080fd5b505afa158015611074573d6000803e3d6000fd5b505050506040513d602081101561108a57600080fd5b505184101590506105e9565b6001600160a01b038216611148576003546001600160a01b038481169116148015610fdd5750846001600160a01b031663b0d8e181846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561111257600080fd5b505afa158015611126573d6000803e3d6000fd5b505050506040513d602081101561113c57600080fd5b505184111590506105e9565b6001600160a01b03838116600090815260066020526040902054610100900481169083161480156111fa575083856001600160a01b031663b0d8e181856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156111cb57600080fd5b505afa1580156111df573d6000803e3d6000fd5b505050506040513d60208110156111f557600080fd5b505110155b8015610fdd5750846001600160a01b031663b0d8e181836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561106057600080fd5b60008083836001600160a01b0382161561130a576112748261063f565b15806113005750876001600160a01b031663b0d8e181836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156112d157600080fd5b505afa1580156112e5573d6000803e3d6000fd5b505050506040513d60208110156112fb57600080fd5b505187115b1561130a57600091505b6001600160a01b038116156113b7576113228161063f565b15806113ae5750876001600160a01b031663b0d8e181826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561137f57600080fd5b505afa158015611393573d6000803e3d6000fd5b505050506040513d60208110156113a957600080fd5b505187105b156113b7575060005b6001600160a01b0382161580156113d557506001600160a01b038116155b156113fe576002546113f390899089906001600160a01b031661159a565b93509350505061143b565b6001600160a01b038216611417576113f38888836116db565b6001600160a01b038116611430576113f388888461159a565b6113f388888461159a565b94509492505050565b6001600160a01b03811661149f576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806114f3576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b5050565b600061153983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611816565b9392505050565b600082820183811015611539576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60025460009081906001600160a01b03848116911614801561163d5750846001600160a01b031663b0d8e181846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561160d57600080fd5b505afa158015611621573d6000803e3d6000fd5b505050506040513d602081101561163757600080fd5b50518410155b1561164d57506000905081610613565b6001600160a01b038084166000908152600660205260409020548491610100909104165b6001600160a01b03821615801590611692575061169087878484610fb0565b155b156116cf57506001600160a01b03908116600090815260066020526040808220546101009081900484168084529190922054909291900416611671565b90969095509350505050565b60035460009081906001600160a01b03848116911614801561177e5750846001600160a01b031663b0d8e181846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561174e57600080fd5b505afa158015611762573d6000803e3d6000fd5b505050506040513d602081101561177857600080fd5b50518411155b1561178e57508190506000610613565b6001600160a01b038084166000908152600660205260409020600101548491165b6001600160a01b038216158015906117d057506117ce87878385610fb0565b155b1561180b57506001600160a01b03908116600090815260066020526040808220600190810154841680845291909220909101549091166117af565b969095509350505050565b600081848411156118a55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561186a578181015183820152602001611852565b50505050905090810190601f1680156118975780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505090039056fe536f7274656454726f7665733a204c69737420616c726561647920636f6e7461696e7320746865206e6f6465536f7274656454726f7665733a204c69737420646f6573206e6f7420636f6e7461696e20746865206964536f7274656454726f7665733a2053697a652063616ee2809974206265207a65726f536f7274656454726f7665733a2043616c6c6572206973206e6f74207468652054726f76654d616e616765724f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373536f7274656454726f7665733a2043616c6c6572206973206e65697468657220424f206e6f722054726f76654d536f7274656454726f7665733a204e494352206d75737420626520706f736974697665a264697066735822122032b466fa1ae0f54c795858e19523f6f623b02846824d1e4a37750d801b21599064736f6c634300060b0033", "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x9414974B00A4E5d8437E6402d44821ee4C2A08F1" + "deployedLinkReferences": {} } \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/SortedTroves_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/SortedTroves_Proxy.json new file mode 100644 index 00000000..351c17f0 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/SortedTroves_Proxy.json @@ -0,0 +1,110 @@ +{ + "address": "0x9414974B00A4E5d8437E6402d44821ee4C2A08F1", + "_format": "hh-sol-artifact-1", + "contractName": "UpgradableProxy", + "sourceName": "contracts/Proxy/UpgradableProxy.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_oldImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newImplementation", + "type": "address" + } + ], + "name": "ImplementationChanged", + "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" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", + "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/stabilityPool.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/StabilityPool.json similarity index 100% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/stabilityPool.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/StabilityPool.json diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/stabilityPool_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/StabilityPool_Proxy.json similarity index 100% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/stabilityPool_Proxy.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/StabilityPool_Proxy.json index e995a675..74ba8bf0 100644 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/stabilityPool_Proxy.json +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/StabilityPool_Proxy.json @@ -1,8 +1,8 @@ { + "address": "0x176D218CaB70002CEF08e15271476187c37ed25f", "_format": "hh-sol-artifact-1", "contractName": "UpgradableProxy", "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "address": "0x176D218CaB70002CEF08e15271476187c37ed25f", "abi": [ { "anonymous": false, diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/troveManager.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/TroveManager.json similarity index 100% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/troveManager.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/TroveManager.json diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/troveManager_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/TroveManager_Proxy.json similarity index 100% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/troveManager_Proxy.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/TroveManager_Proxy.json index 9d1b6af3..1816db24 100644 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/troveManager_Proxy.json +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/TroveManager_Proxy.json @@ -1,8 +1,8 @@ { + "address": "0xd8aB7EC3bd20A0Ce3084e124bFBC9Aa96a6D7FdD", "_format": "hh-sol-artifact-1", "contractName": "UpgradableProxy", "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "address": "0xd8aB7EC3bd20A0Ce3084e124bFBC9Aa96a6D7FdD", "abi": [ { "anonymous": false, diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/zusdToken.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/ZUSDToken.json similarity index 100% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/zusdToken.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/ZUSDToken.json diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/zusdToken_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/ZUSDToken_Proxy.json similarity index 100% rename from packages/contracts/deployment/deployments/rskSovrynTestnet/zusdToken_Proxy.json rename to packages/contracts/deployment/deployments/rskSovrynTestnet/ZUSDToken_Proxy.json index 2b6d3537..e64e2bf5 100644 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/zusdToken_Proxy.json +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/ZUSDToken_Proxy.json @@ -1,8 +1,8 @@ { + "address": "0xe67cbA98C183A1693fC647d63AeeEC4053656dBB", "_format": "hh-sol-artifact-1", "contractName": "UpgradableProxy", "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "address": "0xe67cbA98C183A1693fC647d63AeeEC4053656dBB", "abi": [ { "anonymous": false, diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/activePool_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/activePool_Proxy.json deleted file mode 100644 index 27e1dd96..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/activePool_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0xAD16eBA4EF0ff4C1aB5ffd89c485D5CfC51b5E61" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/collSurplusPool_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/collSurplusPool_Proxy.json deleted file mode 100644 index 360bca54..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/collSurplusPool_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x6b74D66210f78dF0Ffb3A0D6A87471A1345C1284" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/defaultPool_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/defaultPool_Proxy.json deleted file mode 100644 index 2f81d90e..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/defaultPool_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x037216Fa1916E37d82E1456469B635112CF372dd" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/feeDistributor_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/feeDistributor_Proxy.json deleted file mode 100644 index 33bfebb7..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/feeDistributor_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x6e825a3569D46510c0f707eb625e456679dff721" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/hintHelpers_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/hintHelpers_Proxy.json deleted file mode 100644 index cf31a30c..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/hintHelpers_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0xc7Bf159d6259ce5a4Fbdd0e3d060875F76605Dba" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/multiTroveGetter_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/multiTroveGetter_Proxy.json deleted file mode 100644 index d8db6720..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/multiTroveGetter_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x3adF6FAe3C494F0CF151abA537E60fCCbAC0e0a0" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/663a65e7f929c4555a67124fb1575a7f.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/663a65e7f929c4555a67124fb1575a7f.json new file mode 100644 index 00000000..633a9223 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/663a65e7f929c4555a67124fb1575a7f.json @@ -0,0 +1,376 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n // Check the signature length\n if (signature.length != 65) {\n revert(\"ECDSA: invalid signature length\");\n }\n\n // Divide the signature in r, s and v variables\n bytes32 r;\n bytes32 s;\n uint8 v;\n\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n\n return recover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover-bytes32-bytes-} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, \"ECDSA: invalid signature 's' value\");\n require(v == 27 || v == 28, \"ECDSA: invalid signature 'v' value\");\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n require(signer != address(0), \"ECDSA: invalid signature\");\n\n return signer;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * replicates the behavior of the\n * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]\n * JSON-RPC method.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n}\n" + }, + "@openzeppelin/contracts/drafts/EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) internal {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = _getChainId();\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view virtual returns (bytes32) {\n if (_getChainId() == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(bytes32 typeHash, bytes32 name, bytes32 version) private view returns (bytes32) {\n return keccak256(\n abi.encode(\n typeHash,\n name,\n version,\n _getChainId(),\n address(this)\n )\n );\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", _domainSeparatorV4(), structHash));\n }\n\n function _getChainId() private view returns (uint256 chainId) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n // solhint-disable-next-line no-inline-assembly\n assembly {\n chainId := chainid()\n }\n }\n}\n" + }, + "@openzeppelin/contracts/drafts/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.5 <0.8.0;\n\nimport \"../token/ERC20/ERC20.sol\";\nimport \"./IERC20Permit.sol\";\nimport \"../cryptography/ECDSA.sol\";\nimport \"../utils/Counters.sol\";\nimport \"./EIP712.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping (address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private immutable _PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) internal EIP712(name, \"1\") {\n }\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\n // solhint-disable-next-line not-rely-on-time\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n _nonces[owner].current(),\n deadline\n )\n );\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _nonces[owner].increment();\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n}\n" + }, + "@openzeppelin/contracts/drafts/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens,\n * given `owner`'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for `permit`, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a, \"SafeMath: subtraction overflow\");\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: modulo by zero\");\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name_, string memory symbol_) public {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n * called.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../math/SafeMath.sol\";\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\n * directly accessed.\n */\nlibrary Counters {\n using SafeMath for uint256;\n\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n" + }, + "contracts/ActivePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IActivePool.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\n\nimport \"./ActivePoolStorage.sol\";\n\n/**\n * @title Active Pool\n * @notice The Active Pool holds the ETH collateral and ZUSD debt (but not ZUSD tokens) for all active troves.\n *\n * When a trove is liquidated, it's ETH and ZUSD debt are transferred from the Active Pool, to either the\n * Stability Pool, the Default Pool, or both, depending on the liquidation conditions.\n */\ncontract ActivePool is CheckContract, IActivePool, ActivePoolStorage {\n using SafeMath for uint256;\n // --- Events ---\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolZUSDDebtUpdated(uint256 _ZUSDDebt);\n event ActivePoolETHBalanceUpdated(uint256 _ETH);\n\n // --- Contract setters ---\n /// @notice initializer function that sets required addresses\n /// @dev Checks addresses are contracts. Only callable by contract owner.\n /// @param _borrowerOperationsAddress BorrowerOperations contract address\n /// @param _troveManagerAddress TroveManager contract address\n /// @param _stabilityPoolAddress StabilityPool contract address\n /// @param _defaultPoolAddress DefaultPool contract address\n function setAddresses(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _defaultPoolAddress\n ) external onlyOwner {\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_defaultPoolAddress);\n\n borrowerOperationsAddress = _borrowerOperationsAddress;\n troveManagerAddress = _troveManagerAddress;\n stabilityPoolAddress = _stabilityPoolAddress;\n defaultPoolAddress = _defaultPoolAddress;\n\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit StabilityPoolAddressChanged(_stabilityPoolAddress);\n emit DefaultPoolAddressChanged(_defaultPoolAddress);\n }\n\n // --- Getters for public variables. Required by IPool interface ---\n\n /// @notice Not necessarily equal to the the contract's raw ETH balance - ether can be forcibly sent to contracts.\n /// @return the ETH state variable.\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n /// @return the ZUSD debt state variable\n function getZUSDDebt() external view override returns (uint256) {\n return ZUSDDebt;\n }\n\n // --- Pool functionality ---\n\n /// @notice Send ETH amount to given account. Updates ActivePool balance. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _account account to receive the ETH amount\n /// @param _amount ETH amount to send\n function sendETH(address _account, uint256 _amount) external override {\n _requireCallerIsBOorTroveMorSP();\n ETH = ETH.sub(_amount);\n emit ActivePoolETHBalanceUpdated(ETH);\n emit EtherSent(_account, _amount);\n\n (bool success, ) = _account.call{ value: _amount }(\"\");\n require(success, \"ActivePool: sending ETH failed\");\n }\n\n /// @notice Increases ZUSD debt of the active pool. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _amount ZUSD amount to add to the pool debt\n function increaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsBOorTroveM();\n ZUSDDebt = ZUSDDebt.add(_amount);\n ActivePoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n /// @notice Decreases ZUSD debt of the active pool. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _amount ZUSD amount to sub to the pool debt\n function decreaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsBOorTroveMorSP();\n ZUSDDebt = ZUSDDebt.sub(_amount);\n ActivePoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsBorrowerOperationsOrDefaultPool() internal view {\n require(\n msg.sender == borrowerOperationsAddress || msg.sender == defaultPoolAddress,\n \"ActivePool: Caller is neither BO nor Default Pool\"\n );\n }\n\n function _requireCallerIsBOorTroveMorSP() internal view {\n require(\n msg.sender == borrowerOperationsAddress ||\n msg.sender == troveManagerAddress ||\n msg.sender == stabilityPoolAddress,\n \"ActivePool: Caller is neither BorrowerOperations nor TroveManager nor StabilityPool\"\n );\n }\n\n function _requireCallerIsBOorTroveM() internal view {\n require(\n msg.sender == borrowerOperationsAddress || msg.sender == troveManagerAddress,\n \"ActivePool: Caller is neither BorrowerOperations nor TroveManager\"\n );\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsBorrowerOperationsOrDefaultPool();\n ETH = ETH.add(msg.value);\n emit ActivePoolETHBalanceUpdated(ETH);\n }\n}\n" + }, + "contracts/ActivePoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Dependencies/Ownable.sol\";\n\n/**\n * @title Active Pool Storage\n * @dev Stores Active Pool required addresses and internal ETH and ZUSD debt states\n * Extends Ownable\n */\ncontract ActivePoolStorage is Ownable {\n string public constant NAME = \"ActivePool\";\n\n address public borrowerOperationsAddress;\n address public troveManagerAddress;\n address public stabilityPoolAddress;\n address public defaultPoolAddress;\n uint256 internal ETH; // deposited ether tracker\n uint256 internal ZUSDDebt;\n}\n" + }, + "contracts/BorrowerOperations.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./BorrowerOperationsStorage.sol\";\nimport \"./Dependencies/Mynt/MyntLib.sol\";\n\ncontract BorrowerOperations is\n LiquityBase,\n BorrowerOperationsStorage,\n CheckContract,\n IBorrowerOperations\n{\n /* --- Variable container structs ---\n\n Used to hold, return and assign variables inside a function, in order to avoid the error:\n \"CompilerError: Stack too deep\". */\n\n struct LocalVariables_adjustTrove {\n uint256 price;\n uint256 collChange;\n uint256 netDebtChange;\n bool isCollIncrease;\n uint256 debt;\n uint256 coll;\n uint256 oldICR;\n uint256 newICR;\n uint256 newTCR;\n uint256 ZUSDFee;\n uint256 newDebt;\n uint256 newColl;\n uint256 stake;\n uint256 newNICR;\n bool isRecoveryMode;\n }\n\n struct LocalVariables_openTrove {\n uint256 price;\n uint256 ZUSDFee;\n uint256 netDebt;\n uint256 compositeDebt;\n uint256 ICR;\n uint256 NICR;\n uint256 stake;\n uint256 arrayIndex;\n }\n\n struct ContractsCache {\n ITroveManager troveManager;\n IActivePool activePool;\n IZUSDToken zusdToken;\n }\n\n enum BorrowerOperation {\n openTrove,\n closeTrove,\n adjustTrove\n }\n\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n event MassetManagerAddressChanged(address _massetManagerAddress);\n\n event TroveCreated(address indexed _borrower, uint256 arrayIndex);\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 stake,\n BorrowerOperation operation\n );\n event ZUSDBorrowingFeePaid(address indexed _borrower, uint256 _ZUSDFee);\n\n // --- Dependency setters ---\n\n function setAddresses(\n address _feeDistributorAddress,\n address _liquityBaseParamsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _defaultPoolAddress,\n address _stabilityPoolAddress,\n address _gasPoolAddress,\n address _collSurplusPoolAddress,\n address _priceFeedAddress,\n address _sortedTrovesAddress,\n address _zusdTokenAddress,\n address _zeroStakingAddress\n ) external override onlyOwner {\n // This makes impossible to open a trove with zero withdrawn ZUSD\n assert(MIN_NET_DEBT > 0);\n\n checkContract(_feeDistributorAddress);\n checkContract(_liquityBaseParamsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n checkContract(_defaultPoolAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_gasPoolAddress);\n checkContract(_collSurplusPoolAddress);\n checkContract(_priceFeedAddress);\n checkContract(_sortedTrovesAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_zeroStakingAddress);\n\n feeDistributor = IFeeDistributor(_feeDistributorAddress);\n liquityBaseParams = ILiquityBaseParams(_liquityBaseParamsAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n activePool = IActivePool(_activePoolAddress);\n defaultPool = IDefaultPool(_defaultPoolAddress);\n stabilityPoolAddress = _stabilityPoolAddress;\n gasPoolAddress = _gasPoolAddress;\n collSurplusPool = ICollSurplusPool(_collSurplusPoolAddress);\n priceFeed = IPriceFeed(_priceFeedAddress);\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n zeroStakingAddress = _zeroStakingAddress;\n zeroStaking = IZEROStaking(_zeroStakingAddress);\n\n emit FeeDistributorAddressChanged(_feeDistributorAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n emit DefaultPoolAddressChanged(_defaultPoolAddress);\n emit StabilityPoolAddressChanged(_stabilityPoolAddress);\n emit GasPoolAddressChanged(_gasPoolAddress);\n emit CollSurplusPoolAddressChanged(_collSurplusPoolAddress);\n emit PriceFeedAddressChanged(_priceFeedAddress);\n emit SortedTrovesAddressChanged(_sortedTrovesAddress);\n emit ZUSDTokenAddressChanged(_zusdTokenAddress);\n emit ZEROStakingAddressChanged(_zeroStakingAddress);\n }\n\n function setMassetManagerAddress(address _massetManagerAddress) external onlyOwner {\n massetManager = IMassetManager(_massetManagerAddress);\n emit MassetManagerAddressChanged(_massetManagerAddress);\n }\n\n function openTrove(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n _openTrove(_maxFeePercentage, _ZUSDAmount, _upperHint, _lowerHint, msg.sender);\n }\n\n function openNueTrove(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n require(address(massetManager) != address(0), \"Masset address not set\");\n\n _openTrove(_maxFeePercentage, _ZUSDAmount, _upperHint, _lowerHint, address(this));\n require(\n zusdToken.approve(address(massetManager), _ZUSDAmount),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n massetManager.mintTo(address(zusdToken), _ZUSDAmount, msg.sender);\n }\n\n // --- Borrower Trove Operations ---\n function _openTrove(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint,\n address _tokensRecipient\n ) internal {\n ContractsCache memory contractsCache = ContractsCache(troveManager, activePool, zusdToken);\n LocalVariables_openTrove memory vars;\n\n vars.price = priceFeed.fetchPrice();\n bool isRecoveryMode = _checkRecoveryMode(vars.price);\n\n _requireValidMaxFeePercentage(_maxFeePercentage, isRecoveryMode);\n _requireTroveisNotActive(contractsCache.troveManager, msg.sender);\n\n vars.ZUSDFee;\n vars.netDebt = _ZUSDAmount;\n\n if (!isRecoveryMode) {\n vars.ZUSDFee = _triggerBorrowingFee(\n contractsCache.troveManager,\n contractsCache.zusdToken,\n _ZUSDAmount,\n _maxFeePercentage\n );\n vars.netDebt = vars.netDebt.add(vars.ZUSDFee);\n }\n _requireAtLeastMinNetDebt(vars.netDebt);\n\n // ICR is based on the composite debt, i.e. the requested ZUSD amount + ZUSD borrowing fee + ZUSD gas comp.\n vars.compositeDebt = _getCompositeDebt(vars.netDebt);\n assert(vars.compositeDebt > 0);\n\n vars.ICR = LiquityMath._computeCR(msg.value, vars.compositeDebt, vars.price);\n vars.NICR = LiquityMath._computeNominalCR(msg.value, vars.compositeDebt);\n\n if (isRecoveryMode) {\n _requireICRisAboveCCR(vars.ICR);\n } else {\n _requireICRisAboveMCR(vars.ICR);\n uint256 newTCR = _getNewTCRFromTroveChange(\n msg.value,\n true,\n vars.compositeDebt,\n true,\n vars.price\n ); // bools: coll increase, debt increase\n _requireNewTCRisAboveCCR(newTCR);\n }\n\n // Set the trove struct's properties\n contractsCache.troveManager.setTroveStatus(msg.sender, 1);\n contractsCache.troveManager.increaseTroveColl(msg.sender, msg.value);\n contractsCache.troveManager.increaseTroveDebt(msg.sender, vars.compositeDebt);\n\n contractsCache.troveManager.updateTroveRewardSnapshots(msg.sender);\n vars.stake = contractsCache.troveManager.updateStakeAndTotalStakes(msg.sender);\n\n sortedTroves.insert(msg.sender, vars.NICR, _upperHint, _lowerHint);\n vars.arrayIndex = contractsCache.troveManager.addTroveOwnerToArray(msg.sender);\n emit TroveCreated(msg.sender, vars.arrayIndex);\n\n // Move the ether to the Active Pool, and mint the ZUSDAmount to the borrower\n _activePoolAddColl(contractsCache.activePool, msg.value);\n _mintZusdAndIncreaseActivePoolDebt(\n contractsCache.activePool,\n contractsCache.zusdToken,\n _tokensRecipient,\n _ZUSDAmount,\n vars.netDebt\n );\n // Move the ZUSD gas compensation to the Gas Pool\n _mintZusdAndIncreaseActivePoolDebt(\n contractsCache.activePool,\n contractsCache.zusdToken,\n gasPoolAddress,\n ZUSD_GAS_COMPENSATION,\n ZUSD_GAS_COMPENSATION\n );\n\n emit TroveUpdated(\n msg.sender,\n vars.compositeDebt,\n msg.value,\n vars.stake,\n BorrowerOperation.openTrove\n );\n emit ZUSDBorrowingFeePaid(msg.sender, vars.ZUSDFee);\n }\n\n /// Send ETH as collateral to a trove\n function addColl(address _upperHint, address _lowerHint) external payable override {\n _adjustTrove(msg.sender, 0, 0, false, _upperHint, _lowerHint, 0);\n }\n\n /// Send ETH as collateral to a trove. Called by only the Stability Pool.\n function moveETHGainToTrove(\n address _borrower,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n _requireCallerIsStabilityPool();\n _adjustTrove(_borrower, 0, 0, false, _upperHint, _lowerHint, 0);\n }\n\n /// Withdraw ETH collateral from a trove\n function withdrawColl(\n uint256 _collWithdrawal,\n address _upperHint,\n address _lowerHint\n ) external override {\n _adjustTrove(msg.sender, _collWithdrawal, 0, false, _upperHint, _lowerHint, 0);\n }\n\n /// Withdraw ZUSD tokens from a trove: mint new ZUSD tokens to the owner, and increase the trove's debt accordingly\n function withdrawZUSD(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external override {\n _adjustTrove(msg.sender, 0, _ZUSDAmount, true, _upperHint, _lowerHint, _maxFeePercentage);\n }\n\n /// Borrow (withdraw) ZUSD tokens from a trove: mint new ZUSD tokens to the owner and convert it to DLLR in one transaction\n /// Zero Line of Credit owner can borrow a specified amount of ZUSD and convert it to DLLR via Sovryn Mynt\n ///@return DLLR amount minted\n function withdrawZusdAndConvertToDLLR(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external override returns (uint256) {\n address thisAddress = address(this);\n uint256 balanceBefore = zusdToken.balanceOf(thisAddress);\n\n _withdrawZusdTo(\n msg.sender,\n thisAddress,\n _ZUSDAmount,\n _upperHint,\n _lowerHint,\n _maxFeePercentage\n );\n\n require(\n zusdToken.balanceOf(thisAddress) == balanceBefore.add(_ZUSDAmount),\n \"ZUSD is not borrowed correctly\"\n );\n require(\n zusdToken.approve(address(massetManager), _ZUSDAmount),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n return massetManager.mintTo(address(zusdToken), _ZUSDAmount, msg.sender);\n }\n\n /// Repay ZUSD tokens to a Trove: Burn the repaid ZUSD tokens, and reduce the trove's debt accordingly\n function repayZUSD(\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external override {\n _adjustTrove(msg.sender, 0, _ZUSDAmount, false, _upperHint, _lowerHint, 0);\n }\n\n /// Repay ZUSD tokens to a Trove by DLLR: convert DLLR to ZUSD tokens, and then reduce the trove's debt accordingly\n function repayZusdFromDLLR(\n uint256 _dllrAmount,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external override {\n _adjustNueTrove(0, 0, _dllrAmount, false, _upperHint, _lowerHint, _permitParams);\n }\n\n function adjustTrove(\n uint256 _maxFeePercentage,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n _adjustTrove(\n msg.sender,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFeePercentage\n );\n }\n\n // in case of _isDebtIncrease = false MassetManager contract must have an approval of NUE tokens\n function adjustNueTrove(\n uint256 _maxFeePercentage,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external payable override {\n _adjustNueTrove(\n _maxFeePercentage,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _permitParams\n );\n }\n\n // in case of _isDebtIncrease = false Masset Manager contract must have an approval of NUE tokens\n function _adjustNueTrove(\n uint256 _maxFeePercentage,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) internal {\n require(address(massetManager) != address(0), \"Masset address not set\");\n\n if (!_isDebtIncrease && _ZUSDChange > 0) {\n MyntLib.redeemZusdFromDllrWithPermit(\n massetManager,\n _ZUSDChange,\n address(zusdToken),\n _permitParams\n );\n }\n _adjustSenderTrove(\n msg.sender,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFeePercentage,\n address(this)\n );\n if (_isDebtIncrease && _ZUSDChange > 0) {\n require(\n zusdToken.approve(address(massetManager), _ZUSDChange),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n massetManager.mintTo(address(zusdToken), _ZUSDChange, msg.sender);\n }\n }\n\n function _adjustTrove(\n address _borrower,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n uint256 _maxFeePercentage\n ) internal {\n _adjustSenderTrove(\n _borrower,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFeePercentage,\n msg.sender\n );\n }\n\n // _withdrawZusd: _adjustTrove(msg.sender, 0, _ZUSDAmount, true, _upperHint, _lowerHint, _maxFeePercentage);\n function _withdrawZusdTo(\n address _borrower,\n address _receiver,\n uint256 _ZUSDChange,\n address _upperHint,\n address _lowerHint,\n uint256 _maxFeePercentage\n ) internal {\n _adjustSenderTrove(\n _borrower,\n 0,\n _ZUSDChange,\n true,\n _upperHint,\n _lowerHint,\n _maxFeePercentage,\n _receiver\n );\n }\n\n /**\n * _adjustSenderTrove(): Alongside a debt change, this function can perform either a collateral top-up or a collateral withdrawal.\n *\n * It therefore expects either a positive msg.value, or a positive _collWithdrawal argument.\n *\n * If both are positive, it will revert.\n */\n function _adjustSenderTrove(\n address _borrower,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n uint256 _maxFeePercentage,\n address _tokensRecipient\n ) internal {\n ContractsCache memory contractsCache = ContractsCache(troveManager, activePool, zusdToken);\n LocalVariables_adjustTrove memory vars;\n\n vars.price = priceFeed.fetchPrice();\n vars.isRecoveryMode = _checkRecoveryMode(vars.price);\n\n if (_isDebtIncrease) {\n _requireValidMaxFeePercentage(_maxFeePercentage, vars.isRecoveryMode);\n _requireNonZeroDebtChange(_ZUSDChange);\n }\n _requireSingularCollChange(_collWithdrawal);\n _requireNonZeroAdjustment(_collWithdrawal, _ZUSDChange);\n _requireTroveisActive(contractsCache.troveManager, _borrower);\n\n // Confirm the operation is either a borrower adjusting their own trove, or a pure ETH transfer from the Stability Pool to a trove\n assert(\n msg.sender == _borrower ||\n (msg.sender == stabilityPoolAddress && msg.value > 0 && _ZUSDChange == 0)\n );\n\n contractsCache.troveManager.applyPendingRewards(_borrower);\n\n // Get the collChange based on whether or not ETH was sent in the transaction\n (vars.collChange, vars.isCollIncrease) = _getCollChange(msg.value, _collWithdrawal);\n\n vars.netDebtChange = _ZUSDChange;\n\n // If the adjustment incorporates a debt increase and system is in Normal Mode, then trigger a borrowing fee\n if (_isDebtIncrease && !vars.isRecoveryMode) {\n vars.ZUSDFee = _triggerBorrowingFee(\n contractsCache.troveManager,\n contractsCache.zusdToken,\n _ZUSDChange,\n _maxFeePercentage\n );\n vars.netDebtChange = vars.netDebtChange.add(vars.ZUSDFee); // The raw debt change includes the fee\n }\n\n vars.debt = contractsCache.troveManager.getTroveDebt(_borrower);\n vars.coll = contractsCache.troveManager.getTroveColl(_borrower);\n\n // Get the trove's old ICR before the adjustment, and what its new ICR will be after the adjustment\n vars.oldICR = LiquityMath._computeCR(vars.coll, vars.debt, vars.price);\n vars.newICR = _getNewICRFromTroveChange(\n vars.coll,\n vars.debt,\n vars.collChange,\n vars.isCollIncrease,\n vars.netDebtChange,\n _isDebtIncrease,\n vars.price\n );\n assert(_collWithdrawal <= vars.coll);\n\n // Check the adjustment satisfies all conditions for the current system mode\n _requireValidAdjustmentInCurrentMode(\n vars.isRecoveryMode,\n _collWithdrawal,\n _isDebtIncrease,\n vars\n );\n\n // When the adjustment is a debt repayment, check it's a valid amount and that the caller has enough ZUSD\n if (!_isDebtIncrease && _ZUSDChange > 0) {\n _requireAtLeastMinNetDebt(_getNetDebt(vars.debt).sub(vars.netDebtChange));\n _requireValidZUSDRepayment(vars.debt, vars.netDebtChange);\n _requireSufficientZUSDBalance(contractsCache.zusdToken, _borrower, vars.netDebtChange);\n }\n\n (vars.newColl, vars.newDebt) = _updateTroveFromAdjustment(\n contractsCache.troveManager,\n _borrower,\n vars.collChange,\n vars.isCollIncrease,\n vars.netDebtChange,\n _isDebtIncrease\n );\n vars.stake = contractsCache.troveManager.updateStakeAndTotalStakes(_borrower);\n\n // Re-insert trove in to the sorted list\n vars.newNICR = _getNewNominalICRFromTroveChange(\n vars.coll,\n vars.debt,\n vars.collChange,\n vars.isCollIncrease,\n vars.netDebtChange,\n _isDebtIncrease\n );\n sortedTroves.reInsert(_borrower, vars.newNICR, _upperHint, _lowerHint);\n\n emit TroveUpdated(\n _borrower,\n vars.newDebt,\n vars.newColl,\n vars.stake,\n BorrowerOperation.adjustTrove\n );\n emit ZUSDBorrowingFeePaid(msg.sender, vars.ZUSDFee);\n\n // Use the unmodified _ZUSDChange here, as we don't send the fee to the user\n _moveTokensAndETHfromAdjustment(\n contractsCache.activePool,\n contractsCache.zusdToken,\n msg.sender,\n vars.collChange,\n vars.isCollIncrease,\n _ZUSDChange,\n _isDebtIncrease,\n vars.netDebtChange,\n _tokensRecipient\n );\n }\n\n function closeTrove() external override {\n _closeTrove();\n }\n\n function closeNueTrove(IMassetManager.PermitParams calldata _permitParams) external override {\n require(address(massetManager) != address(0), \"Masset address not set\");\n\n uint256 debt = troveManager.getTroveDebt(msg.sender);\n\n MyntLib.redeemZusdFromDllrWithPermit(\n massetManager,\n debt.sub(ZUSD_GAS_COMPENSATION),\n address(zusdToken),\n _permitParams\n );\n _closeTrove();\n }\n\n function _closeTrove() internal {\n ITroveManager troveManagerCached = troveManager;\n IActivePool activePoolCached = activePool;\n IZUSDToken zusdTokenCached = zusdToken;\n\n _requireTroveisActive(troveManagerCached, msg.sender);\n uint256 price = priceFeed.fetchPrice();\n _requireNotInRecoveryMode(price);\n\n troveManagerCached.applyPendingRewards(msg.sender);\n\n uint256 coll = troveManagerCached.getTroveColl(msg.sender);\n uint256 debt = troveManagerCached.getTroveDebt(msg.sender);\n\n _requireSufficientZUSDBalance(\n zusdTokenCached,\n msg.sender,\n debt.sub(ZUSD_GAS_COMPENSATION)\n );\n\n uint256 newTCR = _getNewTCRFromTroveChange(coll, false, debt, false, price);\n _requireNewTCRisAboveCCR(newTCR);\n\n troveManagerCached.removeStake(msg.sender);\n troveManagerCached.closeTrove(msg.sender);\n\n emit TroveUpdated(msg.sender, 0, 0, 0, BorrowerOperation.closeTrove);\n\n // Burn the repaid ZUSD from the user's balance and the gas compensation from the Gas Pool\n _burnZusdAndDecreaseActivePoolDebt(\n activePoolCached,\n zusdTokenCached,\n msg.sender,\n debt.sub(ZUSD_GAS_COMPENSATION)\n );\n _burnZusdAndDecreaseActivePoolDebt(\n activePoolCached,\n zusdTokenCached,\n gasPoolAddress,\n ZUSD_GAS_COMPENSATION\n );\n\n // Send the collateral back to the user\n activePoolCached.sendETH(msg.sender, coll);\n }\n\n /**\n * Claim remaining collateral from a redemption or from a liquidation with ICR > MCR in Recovery Mode\n */\n function claimCollateral() external override {\n // send ETH from CollSurplus Pool to owner\n collSurplusPool.claimColl(msg.sender);\n }\n\n // --- Helper functions ---\n\n function _triggerBorrowingFee(\n ITroveManager _troveManager,\n IZUSDToken _zusdToken,\n uint256 _ZUSDAmount,\n uint256 _maxFeePercentage\n ) internal returns (uint256) {\n _troveManager.decayBaseRateFromBorrowing(); // decay the baseRate state variable\n uint256 ZUSDFee = _troveManager.getBorrowingFee(_ZUSDAmount);\n\n _requireUserAcceptsFee(ZUSDFee, _ZUSDAmount, _maxFeePercentage);\n _zusdToken.mint(address(feeDistributor), ZUSDFee);\n feeDistributor.distributeFees();\n\n return ZUSDFee;\n }\n\n function _getUSDValue(uint256 _coll, uint256 _price) internal pure returns (uint256) {\n uint256 usdValue = _price.mul(_coll).div(DECIMAL_PRECISION);\n\n return usdValue;\n }\n\n function _getCollChange(uint256 _collReceived, uint256 _requestedCollWithdrawal)\n internal\n pure\n returns (uint256 collChange, bool isCollIncrease)\n {\n if (_collReceived != 0) {\n collChange = _collReceived;\n isCollIncrease = true;\n } else {\n collChange = _requestedCollWithdrawal;\n }\n }\n\n /// Update trove's coll and debt based on whether they increase or decrease\n function _updateTroveFromAdjustment(\n ITroveManager _troveManager,\n address _borrower,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease\n ) internal returns (uint256, uint256) {\n uint256 newColl = (_isCollIncrease)\n ? _troveManager.increaseTroveColl(_borrower, _collChange)\n : _troveManager.decreaseTroveColl(_borrower, _collChange);\n uint256 newDebt = (_isDebtIncrease)\n ? _troveManager.increaseTroveDebt(_borrower, _debtChange)\n : _troveManager.decreaseTroveDebt(_borrower, _debtChange);\n\n return (newColl, newDebt);\n }\n\n function _moveTokensAndETHfromAdjustment(\n IActivePool _activePool,\n IZUSDToken _zusdToken,\n address _borrower,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n uint256 _netDebtChange,\n address _tokensRecipient\n ) internal {\n if (_isDebtIncrease) {\n _mintZusdAndIncreaseActivePoolDebt(\n _activePool,\n _zusdToken,\n _tokensRecipient,\n _ZUSDChange,\n _netDebtChange\n );\n } else {\n _burnZusdAndDecreaseActivePoolDebt(_activePool, _zusdToken, _borrower, _ZUSDChange);\n }\n\n if (_isCollIncrease) {\n _activePoolAddColl(_activePool, _collChange);\n } else {\n _activePool.sendETH(_borrower, _collChange);\n }\n }\n\n /// Send ETH to Active Pool and increase its recorded ETH balance\n function _activePoolAddColl(IActivePool _activePool, uint256 _amount) internal {\n (bool success, ) = address(_activePool).call{ value: _amount }(\"\");\n require(success, \"BorrowerOps: Sending ETH to ActivePool failed\");\n }\n\n /// Issue the specified amount of ZUSD to _account and increases the total active debt (_netDebtIncrease potentially includes a ZUSDFee)\n function _mintZusdAndIncreaseActivePoolDebt(\n IActivePool _activePool,\n IZUSDToken _zusdToken,\n address _account,\n uint256 _ZUSDAmount,\n uint256 _netDebtIncrease\n ) internal {\n _activePool.increaseZUSDDebt(_netDebtIncrease);\n _zusdToken.mint(_account, _ZUSDAmount);\n }\n\n /// Burn the specified amount of ZUSD from _account and decreases the total active debt\n function _burnZusdAndDecreaseActivePoolDebt(\n IActivePool _activePool,\n IZUSDToken _zusdToken,\n address _account,\n uint256 _ZUSD\n ) internal {\n _activePool.decreaseZUSDDebt(_ZUSD);\n _zusdToken.burn(_account, _ZUSD);\n }\n\n // --- 'Require' wrapper functions ---\n\n function _requireSingularCollChange(uint256 _collWithdrawal) internal view {\n require(\n msg.value == 0 || _collWithdrawal == 0,\n \"BorrowerOperations: Cannot withdraw and add coll\"\n );\n }\n\n function _requireCallerIsBorrower(address _borrower) internal view {\n require(\n msg.sender == _borrower,\n \"BorrowerOps: Caller must be the borrower for a withdrawal\"\n );\n }\n\n function _requireNonZeroAdjustment(uint256 _collWithdrawal, uint256 _ZUSDChange)\n internal\n view\n {\n require(\n msg.value != 0 || _collWithdrawal != 0 || _ZUSDChange != 0,\n \"BorrowerOps: There must be either a collateral change or a debt change\"\n );\n }\n\n function _requireTroveisActive(ITroveManager _troveManager, address _borrower) internal view {\n uint256 status = _troveManager.getTroveStatus(_borrower);\n require(status == 1, \"BorrowerOps: Trove does not exist or is closed\");\n }\n\n function _requireTroveisNotActive(ITroveManager _troveManager, address _borrower)\n internal\n view\n {\n uint256 status = _troveManager.getTroveStatus(_borrower);\n require(status != 1, \"BorrowerOps: Trove is active\");\n }\n\n function _requireNonZeroDebtChange(uint256 _ZUSDChange) internal pure {\n require(_ZUSDChange > 0, \"BorrowerOps: Debt increase requires non-zero debtChange\");\n }\n\n function _requireNotInRecoveryMode(uint256 _price) internal view {\n require(\n !_checkRecoveryMode(_price),\n \"BorrowerOps: Operation not permitted during Recovery Mode\"\n );\n }\n\n function _requireNoCollWithdrawal(uint256 _collWithdrawal) internal pure {\n require(\n _collWithdrawal == 0,\n \"BorrowerOps: Collateral withdrawal not permitted Recovery Mode\"\n );\n }\n\n function _requireValidAdjustmentInCurrentMode(\n bool _isRecoveryMode,\n uint256 _collWithdrawal,\n bool _isDebtIncrease,\n LocalVariables_adjustTrove memory _vars\n ) internal view {\n /*\n *In Recovery Mode, only allow:\n *\n * - Pure collateral top-up\n * - Pure debt repayment\n * - Collateral top-up with debt repayment\n * - A debt increase combined with a collateral top-up which makes the ICR >= 150% and improves the ICR (and by extension improves the TCR).\n *\n * In Normal Mode, ensure:\n *\n * - The new ICR is above MCR\n * - The adjustment won't pull the TCR below CCR\n */\n if (_isRecoveryMode) {\n _requireNoCollWithdrawal(_collWithdrawal);\n if (_isDebtIncrease) {\n _requireICRisAboveCCR(_vars.newICR);\n _requireNewICRisAboveOldICR(_vars.newICR, _vars.oldICR);\n }\n } else {\n // if Normal Mode\n _requireICRisAboveMCR(_vars.newICR);\n _vars.newTCR = _getNewTCRFromTroveChange(\n _vars.collChange,\n _vars.isCollIncrease,\n _vars.netDebtChange,\n _isDebtIncrease,\n _vars.price\n );\n _requireNewTCRisAboveCCR(_vars.newTCR);\n }\n }\n\n function _requireICRisAboveMCR(uint256 _newICR) internal view {\n require(\n _newICR >= liquityBaseParams.MCR(),\n \"BorrowerOps: An operation that would result in ICR < MCR is not permitted\"\n );\n }\n\n function _requireICRisAboveCCR(uint256 _newICR) internal view {\n require(\n _newICR >= liquityBaseParams.CCR(),\n \"BorrowerOps: Operation must leave trove with ICR >= CCR\"\n );\n }\n\n function _requireNewICRisAboveOldICR(uint256 _newICR, uint256 _oldICR) internal pure {\n require(\n _newICR >= _oldICR,\n \"BorrowerOps: Cannot decrease your Trove's ICR in Recovery Mode\"\n );\n }\n\n function _requireNewTCRisAboveCCR(uint256 _newTCR) internal view {\n require(\n _newTCR >= liquityBaseParams.CCR(),\n \"BorrowerOps: An operation that would result in TCR < CCR is not permitted\"\n );\n }\n\n function _requireAtLeastMinNetDebt(uint256 _netDebt) internal pure {\n require(\n _netDebt >= MIN_NET_DEBT,\n \"BorrowerOps: Trove's net debt must be greater than minimum\"\n );\n }\n\n function _requireValidZUSDRepayment(uint256 _currentDebt, uint256 _debtRepayment)\n internal\n pure\n {\n require(\n _debtRepayment <= _currentDebt.sub(ZUSD_GAS_COMPENSATION),\n \"BorrowerOps: Amount repaid must not be larger than the Trove's debt\"\n );\n }\n\n function _requireCallerIsStabilityPool() internal view {\n require(msg.sender == stabilityPoolAddress, \"BorrowerOps: Caller is not Stability Pool\");\n }\n\n function _requireSufficientZUSDBalance(\n IZUSDToken _zusdToken,\n address _borrower,\n uint256 _debtRepayment\n ) internal view {\n require(\n _zusdToken.balanceOf(_borrower) >= _debtRepayment,\n \"BorrowerOps: Caller doesnt have enough ZUSD to make repayment\"\n );\n }\n\n function _requireValidMaxFeePercentage(uint256 _maxFeePercentage, bool _isRecoveryMode)\n internal\n view\n {\n if (_isRecoveryMode) {\n require(\n _maxFeePercentage <= DECIMAL_PRECISION,\n \"Max fee percentage must less than or equal to 100%\"\n );\n } else {\n require(\n _maxFeePercentage >= liquityBaseParams.BORROWING_FEE_FLOOR() &&\n _maxFeePercentage <= DECIMAL_PRECISION,\n \"Max fee percentage must be between 0.5% and 100%\"\n );\n }\n }\n\n // --- ICR and TCR getters ---\n\n /// Compute the new collateral ratio, considering the change in coll and debt. Assumes 0 pending rewards.\n function _getNewNominalICRFromTroveChange(\n uint256 _coll,\n uint256 _debt,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease\n ) internal pure returns (uint256) {\n (uint256 newColl, uint256 newDebt) = _getNewTroveAmounts(\n _coll,\n _debt,\n _collChange,\n _isCollIncrease,\n _debtChange,\n _isDebtIncrease\n );\n\n uint256 newNICR = LiquityMath._computeNominalCR(newColl, newDebt);\n return newNICR;\n }\n\n /// Compute the new collateral ratio, considering the change in coll and debt. Assumes 0 pending rewards.\n function _getNewICRFromTroveChange(\n uint256 _coll,\n uint256 _debt,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease,\n uint256 _price\n ) internal pure returns (uint256) {\n (uint256 newColl, uint256 newDebt) = _getNewTroveAmounts(\n _coll,\n _debt,\n _collChange,\n _isCollIncrease,\n _debtChange,\n _isDebtIncrease\n );\n\n uint256 newICR = LiquityMath._computeCR(newColl, newDebt, _price);\n return newICR;\n }\n\n function _getNewTroveAmounts(\n uint256 _coll,\n uint256 _debt,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease\n ) internal pure returns (uint256, uint256) {\n uint256 newColl = _coll;\n uint256 newDebt = _debt;\n\n newColl = _isCollIncrease ? _coll.add(_collChange) : _coll.sub(_collChange);\n newDebt = _isDebtIncrease ? _debt.add(_debtChange) : _debt.sub(_debtChange);\n\n return (newColl, newDebt);\n }\n\n function _getNewTCRFromTroveChange(\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease,\n uint256 _price\n ) internal view returns (uint256) {\n uint256 totalColl = getEntireSystemColl();\n uint256 totalDebt = getEntireSystemDebt();\n\n totalColl = _isCollIncrease ? totalColl.add(_collChange) : totalColl.sub(_collChange);\n totalDebt = _isDebtIncrease ? totalDebt.add(_debtChange) : totalDebt.sub(_debtChange);\n\n uint256 newTCR = LiquityMath._computeCR(totalColl, totalDebt, _price);\n return newTCR;\n }\n\n function getCompositeDebt(uint256 _debt) external view override returns (uint256) {\n return _getCompositeDebt(_debt);\n }\n\n function BORROWING_FEE_FLOOR() external view override returns (uint256) {\n return liquityBaseParams.BORROWING_FEE_FLOOR();\n }\n\n function getMassetManager() external view override returns (IMassetManager) {\n return massetManager;\n }\n}\n" + }, + "contracts/BorrowerOperationsStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IActivePool.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/Mynt/IMassetManager.sol\";\n\ncontract BorrowerOperationsStorage is Ownable {\n string public constant NAME = \"BorrowerOperations\";\n\n // --- Connected contract declarations ---\n\n ITroveManager public troveManager;\n\n address stabilityPoolAddress;\n\n address gasPoolAddress;\n\n ICollSurplusPool collSurplusPool;\n\n IZEROStaking public zeroStaking;\n address public zeroStakingAddress;\n\n IZUSDToken public zusdToken;\n\n // A doubly linked list of Troves, sorted by their collateral ratios\n ISortedTroves public sortedTroves;\n\n IMassetManager public massetManager;\n IFeeDistributor public feeDistributor;\n}\n" + }, + "contracts/CollSurplusPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./CollSurplusPoolStorage.sol\";\n\ncontract CollSurplusPool is CollSurplusPoolStorage, CheckContract, ICollSurplusPool {\n using SafeMath for uint256;\n // --- Events ---\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n\n event CollBalanceUpdated(address indexed _account, uint256 _newBalance);\n event EtherSent(address _to, uint256 _amount);\n\n // --- Contract setters ---\n\n function setAddresses(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress\n ) external override onlyOwner {\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n\n borrowerOperationsAddress = _borrowerOperationsAddress;\n troveManagerAddress = _troveManagerAddress;\n activePoolAddress = _activePoolAddress;\n\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n }\n\n /** Returns the ETH state variable at ActivePool address.\n Not necessarily equal to the raw ether balance - ether can be forcibly sent to contracts. */\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n function getCollateral(address _account) external view override returns (uint256) {\n return balances[_account];\n }\n\n // --- Pool functionality ---\n\n function accountSurplus(address _account, uint256 _amount) external override {\n _requireCallerIsTroveManager();\n\n uint256 newAmount = balances[_account].add(_amount);\n balances[_account] = newAmount;\n\n emit CollBalanceUpdated(_account, newAmount);\n }\n\n function claimColl(address _account) external override {\n _requireCallerIsBorrowerOperations();\n uint256 claimableColl = balances[_account];\n require(claimableColl > 0, \"CollSurplusPool: No collateral available to claim\");\n\n balances[_account] = 0;\n emit CollBalanceUpdated(_account, 0);\n\n ETH = ETH.sub(claimableColl);\n emit EtherSent(_account, claimableColl);\n\n (bool success, ) = _account.call{ value: claimableColl }(\"\");\n require(success, \"CollSurplusPool: sending ETH failed\");\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsBorrowerOperations() internal view {\n require(\n msg.sender == borrowerOperationsAddress,\n \"CollSurplusPool: Caller is not Borrower Operations\"\n );\n }\n\n function _requireCallerIsTroveManager() internal view {\n require(msg.sender == troveManagerAddress, \"CollSurplusPool: Caller is not TroveManager\");\n }\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"CollSurplusPool: Caller is not Active Pool\");\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsActivePool();\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/CollSurplusPoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Dependencies/Ownable.sol\";\n\ncontract CollSurplusPoolStorage is Ownable {\n string public constant NAME = \"CollSurplusPool\";\n\n address public borrowerOperationsAddress;\n address public troveManagerAddress;\n address public activePoolAddress;\n\n // deposited ether tracker\n uint256 internal ETH;\n // Collateral surplus claimable by trove owners\n mapping(address => uint256) internal balances;\n}\n" + }, + "contracts/DefaultPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IDefaultPool.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./DefaultPoolStorage.sol\";\n\n/**\n * The Default Pool holds the ETH and ZUSD debt (but not ZUSD tokens) from liquidations that have been redistributed\n * to active troves but not yet \"applied\", i.e. not yet recorded on a recipient active trove's struct.\n *\n * When a trove makes an operation that applies its pending ETH and ZUSD debt, its pending ETH and ZUSD debt is moved\n * from the Default Pool to the Active Pool.\n */\ncontract DefaultPool is DefaultPoolStorage, CheckContract, IDefaultPool {\n using SafeMath for uint256;\n\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event DefaultPoolZUSDDebtUpdated(uint256 _ZUSDDebt);\n event DefaultPoolETHBalanceUpdated(uint256 _ETH);\n\n // --- Dependency setters ---\n\n function setAddresses(address _troveManagerAddress, address _activePoolAddress)\n external\n onlyOwner\n {\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n\n troveManagerAddress = _troveManagerAddress;\n activePoolAddress = _activePoolAddress;\n\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n }\n\n // --- Getters for public variables. Required by IPool interface ---\n\n /**\n * @return the ETH state variable.\n *\n * Not necessarily equal to the the contract's raw ETH balance - ether can be forcibly sent to contracts.\n */\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n function getZUSDDebt() external view override returns (uint256) {\n return ZUSDDebt;\n }\n\n // --- Pool functionality ---\n\n function sendETHToActivePool(uint256 _amount) external override {\n _requireCallerIsTroveManager();\n address activePool = activePoolAddress; // cache to save an SLOAD\n ETH = ETH.sub(_amount);\n emit DefaultPoolETHBalanceUpdated(ETH);\n emit EtherSent(activePool, _amount);\n\n (bool success, ) = activePool.call{ value: _amount }(\"\");\n require(success, \"DefaultPool: sending ETH failed\");\n }\n\n function increaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsTroveManager();\n ZUSDDebt = ZUSDDebt.add(_amount);\n emit DefaultPoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n function decreaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsTroveManager();\n ZUSDDebt = ZUSDDebt.sub(_amount);\n emit DefaultPoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"DefaultPool: Caller is not the ActivePool\");\n }\n\n function _requireCallerIsTroveManager() internal view {\n require(msg.sender == troveManagerAddress, \"DefaultPool: Caller is not the TroveManager\");\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsActivePool();\n ETH = ETH.add(msg.value);\n emit DefaultPoolETHBalanceUpdated(ETH);\n }\n}\n" + }, + "contracts/DefaultPoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract DefaultPoolStorage is Ownable {\n string public constant NAME = \"DefaultPool\";\n\n address public troveManagerAddress;\n address public activePoolAddress;\n uint256 internal ETH; // deposited ETH tracker\n uint256 internal ZUSDDebt; // debt\n}\n" + }, + "contracts/Dependencies/BaseMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\n\ncontract BaseMath {\n uint constant public DECIMAL_PRECISION = 1e18;\n}\n" + }, + "contracts/Dependencies/CheckContract.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n\ncontract CheckContract {\n /**\n * @dev Check that the account is an already deployed non-destroyed contract.\n * See: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L12\n */\n function checkContract(address _account) internal view {\n require(_account != address(0), \"Account cannot be zero address\");\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(_account) }\n require(size > 0, \"Account code size cannot be zero\");\n }\n}\n" + }, + "contracts/Dependencies/console.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// Buidler's helper contract for console logging\nlibrary console {\n\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n\tfunction log() internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log()\"));\n\t\tignored;\n\t}\tfunction logInt(int p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(int)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logUint(uint p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logString(string memory p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBool(bool p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logAddress(address p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes(bytes memory p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logByte(byte p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(byte)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes1(bytes1 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes1)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes2(bytes2 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes2)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes3(bytes3 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes3)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes4(bytes4 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes4)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes5(bytes5 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes5)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes6(bytes6 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes6)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes7(bytes7 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes7)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes8(bytes8 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes8)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes9(bytes9 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes9)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes10(bytes10 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes10)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes11(bytes11 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes11)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes12(bytes12 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes12)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes13(bytes13 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes13)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes14(bytes14 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes14)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes15(bytes15 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes15)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes16(bytes16 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes16)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes17(bytes17 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes17)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes18(bytes18 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes18)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes19(bytes19 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes19)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes20(bytes20 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes20)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes21(bytes21 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes21)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes22(bytes22 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes22)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes23(bytes23 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes23)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes24(bytes24 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes24)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes25(bytes25 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes25)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes26(bytes26 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes26)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes27(bytes27 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes27)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes28(bytes28 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes28)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes29(bytes29 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes29)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes30(bytes30 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes30)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes31(bytes31 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes31)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes32(bytes32 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes32)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(address p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n}\n" + }, + "contracts/Dependencies/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * Based on the OpenZeppelin IER20 interface:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol\n *\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n function increaseAllowance(address spender, uint256 addedValue) external returns (bool);\n function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n function name() external view returns (string memory);\n function symbol() external view returns (string memory);\n function decimals() external view returns (uint8);\n \n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}" + }, + "contracts/Dependencies/IERC2612.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * @dev Interface of the ERC2612 standard as defined in the EIP.\n *\n * Adds the {permit} method, which can be used to change one's\n * {IERC20-allowance} without having to send a transaction, by signing a\n * message. This allows users to spend tokens without having to hold Ether.\n *\n * See https://eips.ethereum.org/EIPS/eip-2612.\n * \n * Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\n */\ninterface IERC2612 {\n /**\n * @dev Sets `amount` as the allowance of `spender` over `owner`'s tokens,\n * given `owner`'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(address owner, address spender, uint256 amount, \n uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n \n /**\n * @dev Returns the current ERC2612 nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases `owner`'s nonce by one. This\n * prevents a signature from being used multiple times.\n *\n * `owner` can limit the time a Permit is valid for by setting `deadline` to \n * a value in the near future. The deadline argument can be set to uint(-1) to \n * create Permits that effectively never expire.\n */\n function nonces(address owner) external view returns (uint256);\n \n function version() external view returns (string memory);\n function permitTypeHash() external view returns (bytes32);\n function domainSeparator() external view returns (bytes32);\n}\n" + }, + "contracts/Dependencies/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * @title Initializable\n *\n * Based on OpenZeppelin's Initializable contract:\n * https://github.com/OpenZeppelin/openzeppelin-upgrades/blob/master/packages/core/contracts/Initializable.sol\n * \n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(\n initializing || isConstructor() || !initialized,\n \"Contract instance has already been initialized\"\n );\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n /// @dev Returns true if and only if the function is running in the constructor\n function isConstructor() private view returns (bool) {\n // extcodesize checks the size of the code stored in an address, and\n // address returns the current address. Since the code is still not\n // deployed when running a constructor, any checks on its code size will\n // yield zero, making it an effective way to detect if a contract is\n // under construction or not.\n address self = address(this);\n uint256 cs;\n assembly {\n cs := extcodesize(self)\n }\n return cs == 0;\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}\n" + }, + "contracts/Dependencies/LiquityBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./BaseMath.sol\";\nimport \"./LiquityMath.sol\";\nimport \"../Interfaces/IActivePool.sol\";\nimport \"../Interfaces/IDefaultPool.sol\";\nimport \"../Interfaces/IPriceFeed.sol\";\nimport \"../Interfaces/ILiquityBase.sol\";\nimport \"../Interfaces/ILiquityBaseParams.sol\";\n\n/**\n * Base contract for TroveManager, BorrowerOperations and StabilityPool. Contains global system constants and\n * common functions.\n */\ncontract LiquityBase is BaseMath, ILiquityBase {\n using SafeMath for uint256;\n\n uint256 public constant _100pct = 1000000000000000000; // 1e18 == 100%\n\n /// Amount of ZUSD to be locked in gas pool on opening troves\n uint256 public constant ZUSD_GAS_COMPENSATION = 20e18;\n\n /// Minimum amount of net ZUSD debt a trove must have\n uint256 public constant MIN_NET_DEBT = 180e18;\n\n IActivePool public activePool;\n\n IDefaultPool public defaultPool;\n\n IPriceFeed public override priceFeed;\n\n ILiquityBaseParams public override liquityBaseParams;\n\n // --- Gas compensation functions ---\n\n // Returns the composite debt (drawn debt + gas compensation) of a trove, for the purpose of ICR calculation\n function _getCompositeDebt(uint256 _debt) internal pure returns (uint256) {\n return _debt.add(ZUSD_GAS_COMPENSATION);\n }\n\n function _getNetDebt(uint256 _debt) internal pure returns (uint256) {\n return _debt.sub(ZUSD_GAS_COMPENSATION);\n }\n\n /// Return the amount of ETH to be drawn from a trove's collateral and sent as gas compensation.\n function _getCollGasCompensation(uint256 _entireColl) internal view returns (uint256) {\n return _entireColl / liquityBaseParams.PERCENT_DIVISOR();\n }\n\n function getEntireSystemColl() public view returns (uint256 entireSystemColl) {\n uint256 activeColl = activePool.getETH();\n uint256 liquidatedColl = defaultPool.getETH();\n\n return activeColl.add(liquidatedColl);\n }\n\n function getEntireSystemDebt() public view returns (uint256 entireSystemDebt) {\n uint256 activeDebt = activePool.getZUSDDebt();\n uint256 closedDebt = defaultPool.getZUSDDebt();\n\n return activeDebt.add(closedDebt);\n }\n\n function _getTCR(uint256 _price) internal view returns (uint256 TCR) {\n uint256 entireSystemColl = getEntireSystemColl();\n uint256 entireSystemDebt = getEntireSystemDebt();\n\n TCR = LiquityMath._computeCR(entireSystemColl, entireSystemDebt, _price);\n\n return TCR;\n }\n\n function _checkRecoveryMode(uint256 _price) internal view returns (bool) {\n uint256 TCR = _getTCR(_price);\n\n return TCR < liquityBaseParams.CCR();\n }\n\n function _requireUserAcceptsFee(\n uint256 _fee,\n uint256 _amount,\n uint256 _maxFeePercentage\n ) internal pure {\n uint256 feePercentage = _fee.mul(DECIMAL_PRECISION).div(_amount);\n require(feePercentage <= _maxFeePercentage, \"Fee exceeded provided maximum\");\n }\n}\n" + }, + "contracts/Dependencies/LiquityMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./SafeMath.sol\";\nimport \"./console.sol\";\n\nlibrary LiquityMath {\n using SafeMath for uint;\n\n uint internal constant DECIMAL_PRECISION = 1e18;\n\n /* Precision for Nominal ICR (independent of price). Rationale for the value:\n *\n * - Making it “too high” could lead to overflows.\n * - Making it “too low” could lead to an ICR equal to zero, due to truncation from Solidity floor division. \n *\n * This value of 1e20 is chosen for safety: the NICR will only overflow for numerator > ~1e39 ETH,\n * and will only truncate to 0 if the denominator is at least 1e20 times greater than the numerator.\n *\n */\n uint internal constant NICR_PRECISION = 1e20;\n\n function _min(uint _a, uint _b) internal pure returns (uint) {\n return (_a < _b) ? _a : _b;\n }\n\n function _max(uint _a, uint _b) internal pure returns (uint) {\n return (_a >= _b) ? _a : _b;\n }\n\n /* \n * Multiply two decimal numbers and use normal rounding rules:\n * -round product up if 19'th mantissa digit >= 5\n * -round product down if 19'th mantissa digit < 5\n *\n * Used only inside the exponentiation, _decPow().\n */\n function decMul(uint x, uint y) internal pure returns (uint decProd) {\n uint prod_xy = x.mul(y);\n\n decProd = prod_xy.add(DECIMAL_PRECISION / 2).div(DECIMAL_PRECISION);\n }\n\n /* \n * _decPow: Exponentiation function for 18-digit decimal base, and integer exponent n.\n * \n * Uses the efficient \"exponentiation by squaring\" algorithm. O(log(n)) complexity. \n * \n * Called by two functions that represent time in units of minutes:\n * 1) TroveManager._calcDecayedBaseRate\n * 2) CommunityIssuance._getCumulativeIssuanceFraction \n * \n * The exponent is capped to avoid reverting due to overflow. The cap 525600000 equals\n * \"minutes in 1000 years\": 60 * 24 * 365 * 1000\n * \n * If a period of > 1000 years is ever used as an exponent in either of the above functions, the result will be\n * negligibly different from just passing the cap, since: \n *\n * In function 1), the decayed base rate will be 0 for 1000 years or > 1000 years\n * In function 2), the difference in tokens issued at 1000 years and any time > 1000 years, will be negligible\n */\n function _decPow(uint _base, uint _minutes) internal pure returns (uint) {\n \n if (_minutes > 525600000) {_minutes = 525600000;} // cap to avoid overflow\n \n if (_minutes == 0) {return DECIMAL_PRECISION;}\n\n uint y = DECIMAL_PRECISION;\n uint x = _base;\n uint n = _minutes;\n\n // Exponentiation-by-squaring\n while (n > 1) {\n if (n % 2 == 0) {\n x = decMul(x, x);\n n = n.div(2);\n } else { // if (n % 2 != 0)\n y = decMul(x, y);\n x = decMul(x, x);\n n = (n.sub(1)).div(2);\n }\n }\n\n return decMul(x, y);\n }\n\n function _getAbsoluteDifference(uint _a, uint _b) internal pure returns (uint) {\n return (_a >= _b) ? _a.sub(_b) : _b.sub(_a);\n }\n\n function _computeNominalCR(uint _coll, uint _debt) internal pure returns (uint) {\n if (_debt > 0) {\n return _coll.mul(NICR_PRECISION).div(_debt);\n }\n // Return the maximal value for uint256 if the Trove has a debt of 0. Represents \"infinite\" CR.\n else { // if (_debt == 0)\n return 2**256 - 1;\n }\n }\n\n function _computeCR(uint _coll, uint _debt, uint _price) internal pure returns (uint) {\n if (_debt > 0) {\n uint newCollRatio = _coll.mul(_price).div(_debt);\n\n return newCollRatio;\n }\n // Return the maximal value for uint256 if the Trove has a debt of 0. Represents \"infinite\" CR.\n else { // if (_debt == 0)\n return 2**256 - 1; \n }\n }\n}\n" + }, + "contracts/Dependencies/LiquitySafeMath128.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// uint128 addition and subtraction, with overflow protection.\n\nlibrary LiquitySafeMath128 {\n function add(uint128 a, uint128 b) internal pure returns (uint128) {\n uint128 c = a + b;\n require(c >= a, \"LiquitySafeMath128: addition overflow\");\n\n return c;\n }\n \n function sub(uint128 a, uint128 b) internal pure returns (uint128) {\n require(b <= a, \"LiquitySafeMath128: subtraction overflow\");\n uint128 c = a - b;\n\n return c;\n }\n}" + }, + "contracts/Dependencies/Mynt/IDLLR.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\nimport \"../IERC20.sol\";\n\n/// Public interface for Sovryn Dollar DLLR (Meta Asset Token of Sovryn Mynt) exposing specific functions\ninterface IDLLR is IERC20 {\n /**\n * @notice Only owner can transfer the token.\n * @notice destination cannot be:\n * - zero (0x0) address.\n *\n * @param _recipient Recipient of the token.\n * @param _amount The amount of token that will be transferred.\n *\n * @return true / false.\n */\n function transfer(address _recipient, uint256 _amount) external override returns (bool);\n\n /**\n * @notice Only owner who can transfer the token.\n * @notice destination cannot be:\n * - zero (0x0) address.\n *\n * @param _from Sender of the token.\n * @param _to Recipient of the token.\n * @param _amount The amount of token that will be transferred.\n *\n * @return true / false.\n */\n function transferFrom(\n address _from,\n address _to,\n uint256 _amount\n ) external override returns (bool);\n\n /**\n * @notice transfer utilizing EIP-2612, to reduce the additional sending transaction for doing the approval to the spender.\n *\n * @notice destination cannot be:\n * - zero (0x0) address.\n *\n * @dev By calling this function, the allowance will be overwritten by the total amount.\n *\n * @param _from Sender of the token.\n * @param _to Recipient of the token.\n * @param _amount The amount of the token that will be transferred.\n * @param _deadline Expiration time of the signature.\n * @param _v Last 1 byte of ECDSA signature.\n * @param _r First 32 bytes of ECDSA signature.\n * @param _s 32 bytes after _r in ECDSA signature.\n */\n function transferWithPermit(\n address _from,\n address _to,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external;\n\n /**\n * @notice Approves and then calls the receiving contract.\n * Useful to encapsulate sending tokens to a contract in one call.\n * Solidity has no native way to send tokens to contracts.\n * ERC-20 tokens require approval to be spent by third parties, such as a contract in this case.\n * @param _spender The contract address to spend the tokens.\n * @param _amount The amount of tokens to be sent.\n * @param _data Parameters for the contract call, such as endpoint signature.\n */\n function approveAndCall(address _spender, uint256 _amount, bytes calldata _data) external;\n}\n" + }, + "contracts/Dependencies/Mynt/IMassetManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IMassetManager {\n struct PermitParams {\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n function mintTo(\n address _bAsset,\n uint256 _bAssetQuantity,\n address _recipient\n ) external returns (uint256);\n\n function getToken() external view returns (address);\n\n /**\n * @dev Credits a recipient with a certain quantity of selected bAsset, in exchange for burning the\n * relative mAsset quantity from the sender. Sender also incurs a small fee, if any.\n * @param _bAsset Address of the bAsset to redeem.\n * @param _massetQuantity Units of the masset to redeem.\n * @param _recipient Address to credit with withdrawn bAssets.\n * @return massetRedeemed Relative number of mAsset units burned to pay for the bAssets.\n */\n function redeemTo(\n address _bAsset,\n uint256 _massetQuantity,\n address _recipient\n ) external returns (uint256 massetRedeemed);\n}\n" + }, + "contracts/Dependencies/Mynt/MyntLib.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IMassetManager.sol\";\nimport \"./IDLLR.sol\";\nimport \"../SafeMath.sol\";\n\nlibrary MyntLib {\n using SafeMath for uint256;\n\n /**\n * @notice Convert DLLR _dllrAmount to _toToken utilizing EIP-2612 permit\n * to reduce the additional sending transaction for doing the approval to the spender.\n *\n * @param _myntMassetManager Mynt protocol MassetManager contract address - needed for integration\n * @param _dllrAmount The amount of the DLLR (mAsset) token that will be burned in exchange for _toToken\n * @param _toToken bAsset token address to wothdraw from DLLR\n * @param _permitParams EIP-2612 permit params:\n * _deadline Expiration time of the signature.\n * _v Last 1 byte of ECDSA signature.\n * _r First 32 bytes of ECDSA signature.\n * _s 32 bytes after _r in ECDSA signature.\n * @return redeemed ZUSD amount\n */\n function redeemZusdFromDllrWithPermit(\n IMassetManager _myntMassetManager,\n uint256 _dllrAmount,\n address _toToken,\n IMassetManager.PermitParams calldata _permitParams\n ) internal returns (uint256) {\n IDLLR dllr = IDLLR(_myntMassetManager.getToken());\n uint256 thisBalanceBefore = dllr.balanceOf(address(this));\n address thisAddress = address(this);\n dllr.transferWithPermit(\n msg.sender,\n thisAddress,\n _dllrAmount,\n _permitParams.deadline,\n _permitParams.v,\n _permitParams.r,\n _permitParams.s\n );\n require(\n dllr.balanceOf(thisAddress).sub(thisBalanceBefore) == _dllrAmount,\n \"DLLR transferred amount validation failed\"\n );\n return _myntMassetManager.redeemTo(_toToken, _dllrAmount, msg.sender);\n }\n}\n" + }, + "contracts/Dependencies/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * Based on OpenZeppelin's Ownable contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n *\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\ncontract Ownable {\n bytes32 private constant KEY_OWNER = keccak256(\"key.ownable.owner\");\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () internal {\n _setOwner(msg.sender);\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(msg.sender == getOwner(), \"Ownable:: access denied\");\n _;\n }\n\n /**\n * @notice Set address of the owner.\n * @param _owner Address of the owner.\n * */\n function _setOwner(address _owner) internal {\n require(_owner != address(0), \"Ownable::setOwner: invalid address\");\n emit OwnershipTransferred(getOwner(), _owner);\n\n bytes32 key = KEY_OWNER;\n assembly {\n sstore(key, _owner)\n }\n }\n\n /**\n * @notice Set address of the owner (only owner can call this function)\n * @param _owner Address of the owner.\n * */\n function setOwner(address _owner) public onlyOwner {\n _setOwner(_owner);\n }\n\n /**\n * @notice Return address of the owner.\n * @return _owner Address of the owner.\n * */\n function getOwner() public view returns (address _owner) {\n bytes32 key = KEY_OWNER;\n assembly {\n _owner := sload(key)\n }\n }\n}\n" + }, + "contracts/Dependencies/PriceFeed/IExternalPriceFeed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/// @title A generic interface for external price providers \ninterface IExternalPriceFeed {\n /// @dev The returned price should be 18-decimal value\n /// @return the prive value and a boolean stating if the query was successful\n function latestAnswer() external view returns (uint256, bool);\n}\n" + }, + "contracts/Dependencies/PriceFeed/MocMedianizer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./IExternalPriceFeed.sol\";\n\ninterface IMoCBaseOracle {\n function peek() external view returns (bytes32, bool);\n}\n\ncontract MoCMedianizer is IExternalPriceFeed {\n IMoCBaseOracle medianizer;\n\n constructor(address _medianizer) public {\n medianizer = IMoCBaseOracle(_medianizer);\n }\n\n function latestAnswer() external view override returns (uint256, bool) {\n (bytes32 price, bool success) = medianizer.peek();\n return (uint256(price), success);\n }\n}\n" + }, + "contracts/Dependencies/PriceFeed/RskOracle.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./IExternalPriceFeed.sol\";\n\ninterface IRSKOracle {\n function getPricing() external view returns (uint256, uint256);\n}\n\ncontract RskOracle is IExternalPriceFeed {\n \n IRSKOracle rskOracle;\n\n constructor(address _address) public {\n rskOracle = IRSKOracle(_address);\n }\n\n function latestAnswer() external view override returns (uint256, bool) {\n (uint256 price, ) = rskOracle.getPricing();\n return (price, true);\n }\n}\n" + }, + "contracts/Dependencies/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * Based on OpenZeppelin's SafeMath:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol\n *\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "contracts/Dependencies/TroveManagerBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IActivePool.sol\";\nimport \"../Interfaces/IDefaultPool.sol\";\nimport \"../Interfaces/IZUSDToken.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\nimport \"../Interfaces/ISortedTroves.sol\";\nimport \"../Interfaces/ICollSurplusPool.sol\";\nimport \"../TroveManagerStorage.sol\";\nimport \"./LiquityBase.sol\";\n\ncontract TroveManagerBase is LiquityBase, TroveManagerStorage {\n uint256 public constant SECONDS_IN_ONE_MINUTE = 60;\n\n uint256 public constant MINUTE_DECAY_FACTOR = 999037758833783000;\n\n /// During bootsrap period redemptions are not allowed\n uint256 public immutable BOOTSTRAP_PERIOD;\n\n /**\n BETA: 18 digit decimal. Parameter by which to divide the redeemed fraction, in order to calc the new base rate from a redemption.\n Corresponds to (1 / ALPHA) in the white paper.\n */\n uint256 public constant BETA = 2;\n\n /**\n --- Variable container structs for liquidations ---\n \n These structs are used to hold, return and assign variables inside the liquidation functions,\n in order to avoid the error: \"CompilerError: Stack too deep\".\n */\n\n struct LocalVariables_OuterLiquidationFunction {\n uint256 price;\n uint256 ZUSDInStabPool;\n bool recoveryModeAtStart;\n uint256 liquidatedDebt;\n uint256 liquidatedColl;\n }\n\n struct LocalVariables_InnerSingleLiquidateFunction {\n uint256 collToLiquidate;\n uint256 pendingDebtReward;\n uint256 pendingCollReward;\n }\n\n struct LocalVariables_LiquidationSequence {\n uint256 remainingZUSDInStabPool;\n uint256 i;\n uint256 ICR;\n address user;\n bool backToNormalMode;\n uint256 entireSystemDebt;\n uint256 entireSystemColl;\n }\n\n struct LiquidationValues {\n uint256 entireTroveDebt;\n uint256 entireTroveColl;\n uint256 collGasCompensation;\n uint256 ZUSDGasCompensation;\n uint256 debtToOffset;\n uint256 collToSendToSP;\n uint256 debtToRedistribute;\n uint256 collToRedistribute;\n uint256 collSurplus;\n }\n\n struct LiquidationTotals {\n uint256 totalCollInSequence;\n uint256 totalDebtInSequence;\n uint256 totalCollGasCompensation;\n uint256 totalZUSDGasCompensation;\n uint256 totalDebtToOffset;\n uint256 totalCollToSendToSP;\n uint256 totalDebtToRedistribute;\n uint256 totalCollToRedistribute;\n uint256 totalCollSurplus;\n }\n\n struct ContractsCache {\n IActivePool activePool;\n IDefaultPool defaultPool;\n IZUSDToken zusdToken;\n IZEROStaking zeroStaking;\n ISortedTroves sortedTroves;\n ICollSurplusPool collSurplusPool;\n address gasPoolAddress;\n }\n // --- Variable container structs for redemptions ---\n\n struct RedemptionTotals {\n uint256 remainingZUSD;\n uint256 totalZUSDToRedeem;\n uint256 totalETHDrawn;\n uint256 ETHFee;\n uint256 ETHToSendToRedeemer;\n uint256 decayedBaseRate;\n uint256 price;\n uint256 totalZUSDSupplyAtStart;\n }\n\n struct SingleRedemptionValues {\n uint256 ZUSDLot;\n uint256 ETHLot;\n bool cancelledPartial;\n }\n\n // --- Events ---\n\n event Liquidation(\n uint256 _liquidatedDebt,\n uint256 _liquidatedColl,\n uint256 _collGasCompensation,\n uint256 _ZUSDGasCompensation\n );\n event Redemption(\n uint256 _attemptedZUSDAmount,\n uint256 _actualZUSDAmount,\n uint256 _ETHSent,\n uint256 _ETHFee\n );\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 _stake,\n TroveManagerOperation _operation\n );\n event TroveLiquidated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n TroveManagerOperation _operation\n );\n event BaseRateUpdated(uint256 _baseRate);\n event LastFeeOpTimeUpdated(uint256 _lastFeeOpTime);\n event TotalStakesUpdated(uint256 _newTotalStakes);\n event SystemSnapshotsUpdated(uint256 _totalStakesSnapshot, uint256 _totalCollateralSnapshot);\n event LTermsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveSnapshotsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveIndexUpdated(address _borrower, uint256 _newIndex);\n\n enum TroveManagerOperation {\n applyPendingRewards,\n liquidateInNormalMode,\n liquidateInRecoveryMode,\n redeemCollateral\n }\n\n constructor(uint256 _bootstrapPeriod) public {\n BOOTSTRAP_PERIOD = _bootstrapPeriod;\n }\n\n /// Return the current collateral ratio (ICR) of a given Trove. Takes a trove's pending coll and debt rewards from redistributions into account.\n function _getCurrentICR(address _borrower, uint256 _price) public view returns (uint256) {\n (uint256 currentETH, uint256 currentZUSDDebt) = _getCurrentTroveAmounts(_borrower);\n\n uint256 ICR = LiquityMath._computeCR(currentETH, currentZUSDDebt, _price);\n return ICR;\n }\n\n function _getCurrentTroveAmounts(address _borrower) internal view returns (uint256, uint256) {\n uint256 pendingETHReward = _getPendingETHReward(_borrower);\n uint256 pendingZUSDDebtReward = _getPendingZUSDDebtReward(_borrower);\n\n uint256 currentETH = Troves[_borrower].coll.add(pendingETHReward);\n uint256 currentZUSDDebt = Troves[_borrower].debt.add(pendingZUSDDebtReward);\n\n return (currentETH, currentZUSDDebt);\n }\n\n /// Get the borrower's pending accumulated ETH reward, earned by their stake\n function _getPendingETHReward(address _borrower) public view returns (uint256) {\n uint256 snapshotETH = rewardSnapshots[_borrower].ETH;\n uint256 rewardPerUnitStaked = L_ETH.sub(snapshotETH);\n\n if (rewardPerUnitStaked == 0 || Troves[_borrower].status != Status.active) {\n return 0;\n }\n\n uint256 stake = Troves[_borrower].stake;\n\n uint256 pendingETHReward = stake.mul(rewardPerUnitStaked).div(DECIMAL_PRECISION);\n\n return pendingETHReward;\n }\n\n /// Get the borrower's pending accumulated ZUSD reward, earned by their stake\n function _getPendingZUSDDebtReward(address _borrower) public view returns (uint256) {\n uint256 snapshotZUSDDebt = rewardSnapshots[_borrower].ZUSDDebt;\n uint256 rewardPerUnitStaked = L_ZUSDDebt.sub(snapshotZUSDDebt);\n\n if (rewardPerUnitStaked == 0 || Troves[_borrower].status != Status.active) {\n return 0;\n }\n\n uint256 stake = Troves[_borrower].stake;\n\n uint256 pendingZUSDDebtReward = stake.mul(rewardPerUnitStaked).div(DECIMAL_PRECISION);\n\n return pendingZUSDDebtReward;\n }\n\n /// Add the borrowers's coll and debt rewards earned from redistributions, to their Trove\n function _applyPendingRewards(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n address _borrower\n ) internal {\n if (_hasPendingRewards(_borrower)) {\n _requireTroveIsActive(_borrower);\n\n // Compute pending rewards\n uint256 pendingETHReward = _getPendingETHReward(_borrower);\n uint256 pendingZUSDDebtReward = _getPendingZUSDDebtReward(_borrower);\n\n // Apply pending rewards to trove's state\n Troves[_borrower].coll = Troves[_borrower].coll.add(pendingETHReward);\n Troves[_borrower].debt = Troves[_borrower].debt.add(pendingZUSDDebtReward);\n\n _updateTroveRewardSnapshots(_borrower);\n\n // Transfer from DefaultPool to ActivePool\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n pendingZUSDDebtReward,\n pendingETHReward\n );\n\n emit TroveUpdated(\n _borrower,\n Troves[_borrower].debt,\n Troves[_borrower].coll,\n Troves[_borrower].stake,\n TroveManagerOperation.applyPendingRewards\n );\n }\n }\n\n function _hasPendingRewards(address _borrower) public view returns (bool) {\n /*\n * A Trove has pending rewards if its snapshot is less than the current rewards per-unit-staked sum:\n * this indicates that rewards have occured since the snapshot was made, and the user therefore has\n * pending rewards\n */\n if (Troves[_borrower].status != Status.active) {\n return false;\n }\n\n return (rewardSnapshots[_borrower].ETH < L_ETH);\n }\n\n function _updateTroveRewardSnapshots(address _borrower) internal {\n rewardSnapshots[_borrower].ETH = L_ETH;\n rewardSnapshots[_borrower].ZUSDDebt = L_ZUSDDebt;\n emit TroveSnapshotsUpdated(L_ETH, L_ZUSDDebt);\n }\n\n /// Move a Trove's pending debt and collateral rewards from distributions, from the Default Pool to the Active Pool\n function _movePendingTroveRewardsToActivePool(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _ZUSD,\n uint256 _ETH\n ) internal {\n _defaultPool.decreaseZUSDDebt(_ZUSD);\n _activePool.increaseZUSDDebt(_ZUSD);\n _defaultPool.sendETHToActivePool(_ETH);\n }\n\n /// Remove borrower's stake from the totalStakes sum, and set their stake to 0\n function _removeStake(address _borrower) internal {\n uint256 stake = Troves[_borrower].stake;\n totalStakes = totalStakes.sub(stake);\n Troves[_borrower].stake = 0;\n }\n\n function _closeTrove(address _borrower, Status closedStatus) internal {\n assert(closedStatus != Status.nonExistent && closedStatus != Status.active);\n\n uint256 TroveOwnersArrayLength = TroveOwners.length;\n _requireMoreThanOneTroveInSystem(TroveOwnersArrayLength);\n\n Troves[_borrower].status = closedStatus;\n Troves[_borrower].coll = 0;\n Troves[_borrower].debt = 0;\n\n rewardSnapshots[_borrower].ETH = 0;\n rewardSnapshots[_borrower].ZUSDDebt = 0;\n\n _removeTroveOwner(_borrower, TroveOwnersArrayLength);\n sortedTroves.remove(_borrower);\n }\n\n /// Update borrower's stake based on their latest collateral value\n function _updateStakeAndTotalStakes(address _borrower) internal returns (uint256) {\n uint256 newStake = _computeNewStake(Troves[_borrower].coll);\n uint256 oldStake = Troves[_borrower].stake;\n Troves[_borrower].stake = newStake;\n\n totalStakes = totalStakes.sub(oldStake).add(newStake);\n emit TotalStakesUpdated(totalStakes);\n\n return newStake;\n }\n\n // Calculate a new stake based on the snapshots of the totalStakes and totalCollateral taken at the last liquidation\n function _computeNewStake(uint256 _coll) internal view returns (uint256) {\n uint256 stake;\n if (totalCollateralSnapshot == 0) {\n stake = _coll;\n } else {\n /*\n * The following assert() holds true because:\n * - The system always contains >= 1 trove\n * - When we close or liquidate a trove, we redistribute the pending rewards, so if all troves were closed/liquidated,\n * rewards would’ve been emptied and totalCollateralSnapshot would be zero too.\n */\n assert(totalStakesSnapshot > 0);\n stake = _coll.mul(totalStakesSnapshot).div(totalCollateralSnapshot);\n }\n return stake;\n }\n\n function _calcDecayedBaseRate() internal view returns (uint256) {\n uint256 minutesPassed = _minutesPassedSinceLastFeeOp();\n uint256 decayFactor = LiquityMath._decPow(MINUTE_DECAY_FACTOR, minutesPassed);\n\n return baseRate.mul(decayFactor).div(DECIMAL_PRECISION);\n }\n\n function _minutesPassedSinceLastFeeOp() internal view returns (uint256) {\n return (block.timestamp.sub(lastFeeOperationTime)).div(SECONDS_IN_ONE_MINUTE);\n }\n\n // Update the last fee operation time only if time passed >= decay interval. This prevents base rate griefing.\n function _updateLastFeeOpTime() internal {\n uint256 timePassed = block.timestamp.sub(lastFeeOperationTime);\n\n if (timePassed >= SECONDS_IN_ONE_MINUTE) {\n lastFeeOperationTime = block.timestamp;\n emit LastFeeOpTimeUpdated(block.timestamp);\n }\n }\n\n function _calcRedemptionFee(\n uint256 _redemptionRate,\n uint256 _ETHDrawn\n ) internal pure returns (uint256) {\n uint256 redemptionFee = _redemptionRate.mul(_ETHDrawn).div(DECIMAL_PRECISION);\n require(\n redemptionFee < _ETHDrawn,\n \"TroveManager: Fee would eat up all returned collateral\"\n );\n return redemptionFee;\n }\n\n function _getRedemptionRate() public view returns (uint256) {\n return _calcRedemptionRate(baseRate);\n }\n\n function _getRedemptionFee(uint256 _ETHDrawn) internal view returns (uint256) {\n return _calcRedemptionFee(_getRedemptionRate(), _ETHDrawn);\n }\n\n function _calcRedemptionRate(uint256 _baseRate) internal view returns (uint256) {\n return\n LiquityMath._min(\n liquityBaseParams.REDEMPTION_FEE_FLOOR().add(_baseRate),\n DECIMAL_PRECISION // cap at a maximum of 100%\n );\n }\n\n /**\n Remove a Trove owner from the TroveOwners array, not preserving array order. Removing owner 'B' does the following:\n [A B C D E] => [A E C D], and updates E's Trove struct to point to its new array index.\n */\n function _removeTroveOwner(address _borrower, uint256 TroveOwnersArrayLength) internal {\n Status troveStatus = Troves[_borrower].status;\n // It’s set in caller function `_closeTrove`\n assert(troveStatus != Status.nonExistent && troveStatus != Status.active);\n\n uint128 index = Troves[_borrower].arrayIndex;\n uint256 length = TroveOwnersArrayLength;\n uint256 idxLast = length.sub(1);\n\n assert(index <= idxLast);\n\n address addressToMove = TroveOwners[idxLast];\n\n TroveOwners[index] = addressToMove;\n Troves[addressToMove].arrayIndex = index;\n emit TroveIndexUpdated(addressToMove, index);\n\n TroveOwners.pop();\n }\n\n // --- 'require' wrapper functions ---\n\n function _requireCallerIsBorrowerOperations() internal view {\n require(\n msg.sender == borrowerOperationsAddress,\n \"TroveManager: Caller is not the BorrowerOperations contract\"\n );\n }\n\n function _requireTroveIsActive(address _borrower) internal view {\n require(\n Troves[_borrower].status == Status.active,\n \"TroveManager: Trove does not exist or is closed\"\n );\n }\n\n function _requireZUSDBalanceCoversRedemption(\n IZUSDToken _zusdToken,\n address _redeemer,\n uint256 _amount\n ) internal view {\n require(\n _zusdToken.balanceOf(_redeemer) >= _amount,\n \"TroveManager: Requested redemption amount must be <= user's ZUSD token balance\"\n );\n }\n\n function _requireMoreThanOneTroveInSystem(uint256 TroveOwnersArrayLength) internal view {\n require(\n TroveOwnersArrayLength > 1 && sortedTroves.getSize() > 1,\n \"TroveManager: Only one trove in the system\"\n );\n }\n\n function _requireAmountGreaterThanZero(uint256 _amount) internal pure {\n require(_amount > 0, \"TroveManager: Amount must be greater than zero\");\n }\n\n function _requireTCRoverMCR(uint256 _price) internal view {\n require(\n _getTCR(_price) >= liquityBaseParams.MCR(),\n \"TroveManager: Cannot redeem when TCR < MCR\"\n );\n }\n\n function _requireAfterBootstrapPeriod() internal view {\n uint256 systemDeploymentTime = _zeroToken.getDeploymentStartTime();\n require(\n block.timestamp >= systemDeploymentTime.add(BOOTSTRAP_PERIOD),\n \"TroveManager: Redemptions are not allowed during bootstrap phase\"\n );\n }\n\n function _requireValidMaxFeePercentage(uint256 _maxFeePercentage) internal view {\n require(\n _maxFeePercentage >= liquityBaseParams.REDEMPTION_FEE_FLOOR() &&\n _maxFeePercentage <= DECIMAL_PRECISION,\n \"Max fee percentage must be between 0.5% and 100%\"\n );\n }\n}\n" + }, + "contracts/Dependencies/TroveManagerRedeemOps.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../Dependencies/Mynt/MyntLib.sol\";\nimport \"../Interfaces/IBorrowerOperations.sol\";\nimport \"./TroveManagerBase.sol\";\n\n/// This contract is designed to be used via delegatecall from the TroveManager contract\n/// TroveManagerBase constructor param is bootsrap period when redemptions are not allowed\ncontract TroveManagerRedeemOps is TroveManagerBase {\n /** Send _ZUSDamount ZUSD to the system and redeem the corresponding amount of collateral from as many Troves as are needed to fill the redemption\n request. Applies pending rewards to a Trove before reducing its debt and coll.\n \n Note that if _amount is very large, this function can run out of gas, specially if traversed troves are small. This can be easily avoided by\n splitting the total _amount in appropriate chunks and calling the function multiple times.\n \n Param `_maxIterations` can also be provided, so the loop through Troves is capped (if it’s zero, it will be ignored).This makes it easier to\n avoid OOG for the frontend, as only knowing approximately the average cost of an iteration is enough, without needing to know the “topology”\n of the trove list. It also avoids the need to set the cap in stone in the contract, nor doing gas calculations, as both gas price and opcode\n costs can vary.\n \n All Troves that are redeemed from -- with the likely exception of the last one -- will end up with no debt left, therefore they will be closed.\n If the last Trove does have some remaining debt, it has a finite ICR, and the reinsertion could be anywhere in the list, therefore it requires a hint.\n A frontend should use getRedemptionHints() to calculate what the ICR of this Trove will be after redemption, and pass a hint for its position\n in the sortedTroves list along with the ICR value that the hint was found for.\n \n If another transaction modifies the list between calling getRedemptionHints() and passing the hints to redeemCollateral(), it\n is very likely that the last (partially) redeemed Trove would end up with a different ICR than what the hint is for. In this case the\n redemption will stop after the last completely redeemed Trove and the sender will keep the remaining ZUSD amount, which they can attempt\n to redeem later.\n */\n\n constructor(uint256 _bootstrapPeriod) public TroveManagerBase(_bootstrapPeriod) {}\n\n function redeemCollateral(\n uint256 _ZUSDamount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage\n ) external {\n _redeemCollateral(\n _ZUSDamount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n _maxIterations,\n _maxFeePercentage\n );\n }\n\n function _redeemCollateral(\n uint256 _ZUSDamount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage\n ) internal {\n ContractsCache memory contractsCache = ContractsCache(\n activePool,\n defaultPool,\n _zusdToken,\n _zeroStaking,\n sortedTroves,\n collSurplusPool,\n gasPoolAddress\n );\n RedemptionTotals memory totals;\n\n _requireValidMaxFeePercentage(_maxFeePercentage);\n _requireAfterBootstrapPeriod();\n totals.price = priceFeed.fetchPrice();\n _requireTCRoverMCR(totals.price);\n _requireAmountGreaterThanZero(_ZUSDamount);\n _requireZUSDBalanceCoversRedemption(contractsCache.zusdToken, msg.sender, _ZUSDamount);\n\n totals.totalZUSDSupplyAtStart = getEntireSystemDebt();\n // Confirm redeemer's balance is less than total ZUSD supply\n assert(contractsCache.zusdToken.balanceOf(msg.sender) <= totals.totalZUSDSupplyAtStart);\n\n totals.remainingZUSD = _ZUSDamount;\n address currentBorrower;\n\n if (\n _isValidFirstRedemptionHint(\n contractsCache.sortedTroves,\n _firstRedemptionHint,\n totals.price\n )\n ) {\n currentBorrower = _firstRedemptionHint;\n } else {\n currentBorrower = contractsCache.sortedTroves.getLast();\n // Find the first trove with ICR >= MCR\n while (\n currentBorrower != address(0) &&\n _getCurrentICR(currentBorrower, totals.price) < liquityBaseParams.MCR()\n ) {\n currentBorrower = contractsCache.sortedTroves.getPrev(currentBorrower);\n }\n }\n\n // Loop through the Troves starting from the one with lowest collateral ratio until _amount of ZUSD is exchanged for collateral\n if (_maxIterations == 0) {\n _maxIterations = uint256(-1);\n }\n while (currentBorrower != address(0) && totals.remainingZUSD > 0 && _maxIterations > 0) {\n _maxIterations--;\n // Save the address of the Trove preceding the current one, before potentially modifying the list\n address nextUserToCheck = contractsCache.sortedTroves.getPrev(currentBorrower);\n\n _applyPendingRewards(\n contractsCache.activePool,\n contractsCache.defaultPool,\n currentBorrower\n );\n\n SingleRedemptionValues memory singleRedemption = _redeemCollateralFromTrove(\n contractsCache,\n currentBorrower,\n totals.remainingZUSD,\n totals.price,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR\n );\n\n if (singleRedemption.cancelledPartial) break; // Partial redemption was cancelled (out-of-date hint, or new net debt < minimum), therefore we could not redeem from the last Trove\n\n totals.totalZUSDToRedeem = totals.totalZUSDToRedeem.add(singleRedemption.ZUSDLot);\n totals.totalETHDrawn = totals.totalETHDrawn.add(singleRedemption.ETHLot);\n\n totals.remainingZUSD = totals.remainingZUSD.sub(singleRedemption.ZUSDLot);\n currentBorrower = nextUserToCheck;\n }\n require(totals.totalETHDrawn > 0, \"TroveManager: Unable to redeem any amount\");\n\n // Decay the baseRate due to time passed, and then increase it according to the size of this redemption.\n // Use the saved total ZUSD supply value, from before it was reduced by the redemption.\n _updateBaseRateFromRedemption(\n totals.totalETHDrawn,\n totals.price,\n totals.totalZUSDSupplyAtStart\n );\n\n // Calculate the ETH fee\n totals.ETHFee = _getRedemptionFee(totals.totalETHDrawn);\n\n _requireUserAcceptsFee(totals.ETHFee, totals.totalETHDrawn, _maxFeePercentage);\n\n // Send the ETH fee to the feeDistributorContract address\n contractsCache.activePool.sendETH(address(feeDistributor), totals.ETHFee);\n feeDistributor.distributeFees();\n\n totals.ETHToSendToRedeemer = totals.totalETHDrawn.sub(totals.ETHFee);\n\n emit Redemption(\n _ZUSDamount,\n totals.totalZUSDToRedeem,\n totals.totalETHDrawn,\n totals.ETHFee\n );\n\n // Burn the total ZUSD that is cancelled with debt, and send the redeemed ETH to msg.sender\n contractsCache.zusdToken.burn(msg.sender, totals.totalZUSDToRedeem);\n // Update Active Pool ZUSD, and send ETH to account\n contractsCache.activePool.decreaseZUSDDebt(totals.totalZUSDToRedeem);\n contractsCache.activePool.sendETH(msg.sender, totals.ETHToSendToRedeemer);\n }\n\n ///DLLR _owner can use Sovryn Mynt to convert DLLR to ZUSD, then use the Zero redemption mechanism to redeem ZUSD for RBTC, all in a single transaction\n function redeemCollateralViaDLLR(\n uint256 _dllrAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage,\n IMassetManager.PermitParams calldata _permitParams\n ) external {\n uint256 _zusdAmount = MyntLib.redeemZusdFromDllrWithPermit(\n IBorrowerOperations(borrowerOperationsAddress).getMassetManager(),\n _dllrAmount,\n address(_zusdToken),\n _permitParams\n );\n _redeemCollateral(\n _zusdAmount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n _maxIterations,\n _maxFeePercentage\n );\n }\n\n function _isValidFirstRedemptionHint(\n ISortedTroves _sortedTroves,\n address _firstRedemptionHint,\n uint256 _price\n ) internal view returns (bool) {\n if (\n _firstRedemptionHint == address(0) ||\n !_sortedTroves.contains(_firstRedemptionHint) ||\n _getCurrentICR(_firstRedemptionHint, _price) < liquityBaseParams.MCR()\n ) {\n return false;\n }\n\n address nextTrove = _sortedTroves.getNext(_firstRedemptionHint);\n return\n nextTrove == address(0) || _getCurrentICR(nextTrove, _price) < liquityBaseParams.MCR();\n }\n\n /// Redeem as much collateral as possible from _borrower's Trove in exchange for ZUSD up to _maxZUSDamount\n function _redeemCollateralFromTrove(\n ContractsCache memory _contractsCache,\n address _borrower,\n uint256 _maxZUSDamount,\n uint256 _price,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR\n ) internal returns (SingleRedemptionValues memory singleRedemption) {\n // Determine the remaining amount (lot) to be redeemed, capped by the entire debt of the Trove minus the liquidation reserve\n singleRedemption.ZUSDLot = LiquityMath._min(\n _maxZUSDamount,\n Troves[_borrower].debt.sub(ZUSD_GAS_COMPENSATION)\n );\n\n // Get the ETHLot of equivalent value in USD\n singleRedemption.ETHLot = singleRedemption.ZUSDLot.mul(DECIMAL_PRECISION).div(_price);\n\n // Decrease the debt and collateral of the current Trove according to the ZUSD lot and corresponding ETH to send\n uint256 newDebt = (Troves[_borrower].debt).sub(singleRedemption.ZUSDLot);\n uint256 newColl = (Troves[_borrower].coll).sub(singleRedemption.ETHLot);\n\n if (newDebt == ZUSD_GAS_COMPENSATION) {\n // No debt left in the Trove (except for the liquidation reserve), therefore the trove gets closed\n _removeStake(_borrower);\n _closeTrove(_borrower, Status.closedByRedemption);\n _redeemCloseTrove(_contractsCache, _borrower, ZUSD_GAS_COMPENSATION, newColl);\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.redeemCollateral);\n } else {\n uint256 newNICR = LiquityMath._computeNominalCR(newColl, newDebt);\n\n /*\n * If the provided hint is out of date, we bail since trying to reinsert without a good hint will almost\n * certainly result in running out of gas.\n *\n * If the resultant net debt of the partial is less than the minimum, net debt we bail.\n */\n if (newNICR != _partialRedemptionHintNICR || _getNetDebt(newDebt) < MIN_NET_DEBT) {\n singleRedemption.cancelledPartial = true;\n return singleRedemption;\n }\n\n _contractsCache.sortedTroves.reInsert(\n _borrower,\n newNICR,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint\n );\n\n Troves[_borrower].debt = newDebt;\n Troves[_borrower].coll = newColl;\n _updateStakeAndTotalStakes(_borrower);\n\n emit TroveUpdated(\n _borrower,\n newDebt,\n newColl,\n Troves[_borrower].stake,\n TroveManagerOperation.redeemCollateral\n );\n }\n\n return singleRedemption;\n }\n\n /**\n This function has two impacts on the baseRate state variable:\n 1) decays the baseRate based on time passed since last redemption or ZUSD borrowing operation.\n then,\n 2) increases the baseRate based on the amount redeemed, as a proportion of total supply\n */\n function _updateBaseRateFromRedemption(\n uint256 _ETHDrawn,\n uint256 _price,\n uint256 _totalZUSDSupply\n ) internal returns (uint256) {\n uint256 decayedBaseRate = _calcDecayedBaseRate();\n\n /* Convert the drawn ETH back to ZUSD at face value rate (1 ZUSD:1 USD), in order to get\n * the fraction of total supply that was redeemed at face value. */\n uint256 redeemedZUSDFraction = _ETHDrawn.mul(_price).div(_totalZUSDSupply);\n\n uint256 newBaseRate = decayedBaseRate.add(redeemedZUSDFraction.div(BETA));\n newBaseRate = LiquityMath._min(newBaseRate, DECIMAL_PRECISION); // cap baseRate at a maximum of 100%\n //assert(newBaseRate <= DECIMAL_PRECISION); // This is already enforced in the line above\n assert(newBaseRate > 0); // Base rate is always non-zero after redemption\n\n // Update the baseRate state variable\n baseRate = newBaseRate;\n emit BaseRateUpdated(newBaseRate);\n\n _updateLastFeeOpTime();\n\n return newBaseRate;\n }\n\n /**\n Called when a full redemption occurs, and closes the trove.\n The redeemer swaps (debt - liquidation reserve) ZUSD for (debt - liquidation reserve) worth of ETH, so the ZUSD liquidation reserve left corresponds to the remaining debt.\n In order to close the trove, the ZUSD liquidation reserve is burned, and the corresponding debt is removed from the active pool.\n The debt recorded on the trove's struct is zero'd elswhere, in _closeTrove.\n Any surplus ETH left in the trove, is sent to the Coll surplus pool, and can be later claimed by the borrower.\n */\n function _redeemCloseTrove(\n ContractsCache memory _contractsCache,\n address _borrower,\n uint256 _ZUSD,\n uint256 _ETH\n ) internal {\n _contractsCache.zusdToken.burn(gasPoolAddress, _ZUSD);\n // Update Active Pool ZUSD, and send ETH to account\n _contractsCache.activePool.decreaseZUSDDebt(_ZUSD);\n\n // send ETH from Active Pool to CollSurplus Pool\n _contractsCache.collSurplusPool.accountSurplus(_borrower, _ETH);\n _contractsCache.activePool.sendETH(address(_contractsCache.collSurplusPool), _ETH);\n }\n}\n" + }, + "contracts/FeeDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/LiquityMath.sol\";\nimport \"./FeeDistributorStorage.sol\";\nimport \"./Dependencies/SafeMath.sol\";\n\ncontract FeeDistributor is CheckContract, FeeDistributorStorage, IFeeDistributor {\n using SafeMath for uint256;\n // --- Events ---\n\n event FeeSharingCollectorAddressChanged(address _feeSharingCollectorAddress);\n event ZeroStakingAddressChanged(address _zeroStakingAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event WrbtcAddressChanged(address _wrbtcAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event ZUSDDistributed(uint256 _zusdDistributedAmount);\n event RBTCistributed(uint256 _rbtcDistributedAmount);\n\n // --- Dependency setters ---\n\n function setAddresses(\n address _feeSharingCollectorAddress,\n address _zeroStakingAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _wrbtcAddress,\n address _zusdTokenAddress,\n address _activePoolAddress\n ) external override onlyOwner {\n checkContract(_feeSharingCollectorAddress);\n checkContract(_zeroStakingAddress);\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_wrbtcAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_activePoolAddress);\n\n feeSharingCollector = IFeeSharingCollector(_feeSharingCollectorAddress);\n zeroStaking = IZEROStaking(_zeroStakingAddress);\n borrowerOperations = IBorrowerOperations(_borrowerOperationsAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n wrbtc = IWrbtc(_wrbtcAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n activePoolAddress = _activePoolAddress;\n\n // Not entirely removing this as per request from @light\n FEE_TO_FEE_SHARING_COLLECTOR = LiquityMath.DECIMAL_PRECISION; // 100%\n\n emit FeeSharingCollectorAddressChanged(_feeSharingCollectorAddress);\n emit ZeroStakingAddressChanged(_zeroStakingAddress);\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit WrbtcAddressChanged(_wrbtcAddress);\n emit ZUSDTokenAddressChanged(_zusdTokenAddress);\n emit ActivePoolAddressSet(_activePoolAddress);\n }\n\n function setFeeToFeeSharingCollector(uint256 FEE_TO_FEE_SHARING_COLLECTOR_) public onlyOwner {\n FEE_TO_FEE_SHARING_COLLECTOR = FEE_TO_FEE_SHARING_COLLECTOR_;\n }\n\n function distributeFees() public override {\n require(\n msg.sender == address(borrowerOperations) || msg.sender == address(troveManager),\n \"FeeDistributor: invalid caller\"\n );\n uint256 zusdtoDistribute = zusdToken.balanceOf(address(this));\n uint256 rbtcToDistribute = address(this).balance;\n if (zusdtoDistribute != 0) {\n _distributeZUSD(zusdtoDistribute);\n }\n if (rbtcToDistribute != 0) {\n _distributeRBTC(rbtcToDistribute);\n }\n }\n\n function _distributeZUSD(uint256 toDistribute) internal {\n // Send fee to the FeeSharingCollector address\n uint256 feeToFeeSharingCollector = toDistribute.mul(FEE_TO_FEE_SHARING_COLLECTOR).div(\n LiquityMath.DECIMAL_PRECISION\n );\n zusdToken.approve(address(feeSharingCollector), feeToFeeSharingCollector);\n\n feeSharingCollector.transferTokens(address(zusdToken), uint96(feeToFeeSharingCollector));\n // Send fee to ZERO staking contract\n uint256 feeToZeroStaking = toDistribute.sub(feeToFeeSharingCollector);\n if (feeToZeroStaking != 0) {\n require(\n zusdToken.transfer(address(zeroStaking), feeToZeroStaking),\n \"Coudn't execute ZUSD transfer\"\n );\n zeroStaking.increaseF_ZUSD(feeToZeroStaking);\n }\n emit ZUSDDistributed(toDistribute);\n }\n\n function _distributeRBTC(uint256 toDistribute) internal {\n // Send fee to the feeSharingCollector address\n uint256 feeToFeeSharingCollector = toDistribute.mul(FEE_TO_FEE_SHARING_COLLECTOR).div(\n LiquityMath.DECIMAL_PRECISION\n );\n\n feeSharingCollector.transferRBTC{ value: feeToFeeSharingCollector }();\n\n // Send the ETH fee to the ZERO staking contract\n uint256 feeToZeroStaking = toDistribute.sub(feeToFeeSharingCollector);\n if (feeToZeroStaking != 0) {\n (bool success, ) = address(zeroStaking).call{ value: feeToZeroStaking }(\"\");\n require(success, \"FeeDistributor: sending ETH failed\");\n zeroStaking.increaseF_ETH(feeToZeroStaking);\n }\n emit RBTCistributed(toDistribute);\n }\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"FeeDistributor: caller is not ActivePool\");\n }\n\n receive() external payable {\n _requireCallerIsActivePool();\n }\n}\n" + }, + "contracts/FeeDistributorStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IFeeSharingCollector.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IWrbtc.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract FeeDistributorStorage is Ownable {\n string public constant NAME = \"FeeDistributor\";\n\n // --- Connected contract declarations ---\n\n IFeeSharingCollector public feeSharingCollector;\n\n IZEROStaking public zeroStaking;\n\n IBorrowerOperations public borrowerOperations;\n\n ITroveManager public troveManager;\n\n IWrbtc public wrbtc;\n\n IZUSDToken public zusdToken;\n\n address public activePoolAddress;\n\n //pct of fees sent to feeSharingCollector address\n uint256 public FEE_TO_FEE_SHARING_COLLECTOR;\n}\n" + }, + "contracts/GasPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * The purpose of this contract is to hold ZUSD tokens for gas compensation:\n * https://github.com/DistributedCollective/zero#gas-compensation\n * When a borrower opens a trove, an additional 50 ZUSD debt is issued,\n * and 50 ZUSD is minted and sent to this contract.\n * When a borrower closes their active trove, this gas compensation is refunded:\n * 50 ZUSD is burned from the this contract's balance, and the corresponding\n * 50 ZUSD debt on the trove is cancelled.\n * See this issue for more context: https://github.com/liquity/dev/issues/186\n */\ncontract GasPool {\n // do nothing, as the core contracts have permission to send to and burn from this address\n}\n" + }, + "contracts/HintHelpers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./HintHelpersStorage.sol\";\n\ncontract HintHelpers is LiquityBase, HintHelpersStorage, CheckContract {\n // --- Events ---\n\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event TroveManagerAddressChanged(address _troveManagerAddress);\n\n // --- Dependency setters ---\n\n function setAddresses(\n address _liquityBaseParamsAddress,\n address _sortedTrovesAddress,\n address _troveManagerAddress\n ) external onlyOwner {\n checkContract(_liquityBaseParamsAddress);\n checkContract(_sortedTrovesAddress);\n checkContract(_troveManagerAddress);\n\n liquityBaseParams = ILiquityBaseParams(_liquityBaseParamsAddress);\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n\n emit SortedTrovesAddressChanged(_sortedTrovesAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n }\n\n // --- Functions ---\n\n /** getRedemptionHints() - Helper function for finding the right hints to pass to redeemCollateral().\n *\n * It simulates a redemption of `_ZUSDamount` to figure out where the redemption sequence will start and what state the final Trove\n * of the sequence will end up in.\n *\n * Returns three hints:\n * - `firstRedemptionHint` is the address of the first Trove with ICR >= MCR (i.e. the first Trove that will be redeemed).\n * - `partialRedemptionHintNICR` is the final nominal ICR of the last Trove of the sequence after being hit by partial redemption,\n * or zero in case of no partial redemption.\n * - `truncatedZUSDamount` is the maximum amount that can be redeemed out of the the provided `_ZUSDamount`. This can be lower than\n * `_ZUSDamount` when redeeming the full amount would leave the last Trove of the redemption sequence with less net debt than the\n * minimum allowed value (i.e. MIN_NET_DEBT).\n *\n * The number of Troves to consider for redemption can be capped by passing a non-zero value as `_maxIterations`, while passing zero\n * will leave it uncapped.\n */\n\n function getRedemptionHints(\n uint256 _ZUSDamount,\n uint256 _price,\n uint256 _maxIterations\n )\n external\n view\n returns (\n address firstRedemptionHint,\n uint256 partialRedemptionHintNICR,\n uint256 truncatedZUSDamount\n )\n {\n ISortedTroves sortedTrovesCached = sortedTroves;\n\n uint256 remainingZUSD = _ZUSDamount;\n address currentTroveuser = sortedTrovesCached.getLast();\n\n while (\n currentTroveuser != address(0) &&\n troveManager.getCurrentICR(currentTroveuser, _price) < liquityBaseParams.MCR()\n ) {\n currentTroveuser = sortedTrovesCached.getPrev(currentTroveuser);\n }\n\n firstRedemptionHint = currentTroveuser;\n\n if (_maxIterations == 0) {\n _maxIterations = uint256(-1);\n }\n\n while (currentTroveuser != address(0) && remainingZUSD > 0 && _maxIterations-- > 0) {\n uint256 netZUSDDebt = _getNetDebt(troveManager.getTroveDebt(currentTroveuser)).add(\n troveManager.getPendingZUSDDebtReward(currentTroveuser)\n );\n\n if (netZUSDDebt > remainingZUSD) {\n if (netZUSDDebt > MIN_NET_DEBT) {\n uint256 maxRedeemableZUSD = LiquityMath._min(\n remainingZUSD,\n netZUSDDebt.sub(MIN_NET_DEBT)\n );\n\n uint256 ETH = troveManager.getTroveColl(currentTroveuser).add(\n troveManager.getPendingETHReward(currentTroveuser)\n );\n\n uint256 newColl = ETH.sub(\n maxRedeemableZUSD.mul(DECIMAL_PRECISION).div(_price)\n );\n uint256 newDebt = netZUSDDebt.sub(maxRedeemableZUSD);\n\n uint256 compositeDebt = _getCompositeDebt(newDebt);\n partialRedemptionHintNICR = LiquityMath._computeNominalCR(\n newColl,\n compositeDebt\n );\n\n remainingZUSD = remainingZUSD.sub(maxRedeemableZUSD);\n }\n break;\n } else {\n remainingZUSD = remainingZUSD.sub(netZUSDDebt);\n }\n\n currentTroveuser = sortedTrovesCached.getPrev(currentTroveuser);\n }\n\n truncatedZUSDamount = _ZUSDamount.sub(remainingZUSD);\n }\n\n /** getApproxHint() - return address of a Trove that is, on average, (length / numTrials) positions away in the \n sortedTroves list from the correct insert position of the Trove to be inserted. \n \n Note: The output address is worst-case O(n) positions away from the correct insert position, however, the function \n is probabilistic. Input can be tuned to guarantee results to a high degree of confidence, e.g:\n\n Submitting numTrials = k * sqrt(length), with k = 15 makes it very, very likely that the ouput address will \n be <= sqrt(length) positions away from the correct insert position.\n */\n function getApproxHint(\n uint256 _CR,\n uint256 _numTrials,\n uint256 _inputRandomSeed\n )\n external\n view\n returns (\n address hintAddress,\n uint256 diff,\n uint256 latestRandomSeed\n )\n {\n uint256 arrayLength = troveManager.getTroveOwnersCount();\n\n if (arrayLength == 0) {\n return (address(0), 0, _inputRandomSeed);\n }\n\n hintAddress = sortedTroves.getLast();\n diff = LiquityMath._getAbsoluteDifference(_CR, troveManager.getNominalICR(hintAddress));\n latestRandomSeed = _inputRandomSeed;\n\n uint256 i = 1;\n\n while (i < _numTrials) {\n latestRandomSeed = uint256(keccak256(abi.encodePacked(latestRandomSeed)));\n\n uint256 arrayIndex = latestRandomSeed % arrayLength;\n address currentAddress = troveManager.getTroveFromTroveOwnersArray(arrayIndex);\n uint256 currentNICR = troveManager.getNominalICR(currentAddress);\n\n // check if abs(current - CR) > abs(closest - CR), and update closest if current is closer\n uint256 currentDiff = LiquityMath._getAbsoluteDifference(currentNICR, _CR);\n\n if (currentDiff < diff) {\n diff = currentDiff;\n hintAddress = currentAddress;\n }\n i++;\n }\n }\n\n function computeNominalCR(uint256 _coll, uint256 _debt) external pure returns (uint256) {\n return LiquityMath._computeNominalCR(_coll, _debt);\n }\n\n function computeCR(\n uint256 _coll,\n uint256 _debt,\n uint256 _price\n ) external pure returns (uint256) {\n return LiquityMath._computeCR(_coll, _debt, _price);\n }\n}\n" + }, + "contracts/HintHelpersStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract HintHelpersStorage is Ownable {\n string public constant NAME = \"HintHelpers\";\n\n ISortedTroves public sortedTroves;\n ITroveManager public troveManager;\n}\n" + }, + "contracts/Interfaces/IActivePool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IPool.sol\";\n\n/**\n * The Active Pool holds the ETH collateral and ZUSD debt (but not ZUSD tokens) for all active troves.\n *\n * When a trove is liquidated, it's ETH and ZUSD debt are transferred from the Active Pool, to either the\n * Stability Pool, the Default Pool, or both, depending on the liquidation conditions.\n *\n */\ninterface IActivePool is IPool {\n // --- Events ---\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolZUSDDebtUpdated(uint _ZUSDDebt);\n event ActivePoolETHBalanceUpdated(uint _ETH);\n\n // --- Functions ---\n\n /// @notice Send ETH amount to given account. Updates ActivePool balance. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _account account to receive the ETH amount\n /// @param _amount ETH amount to send\n function sendETH(address _account, uint _amount) external;\n}\n" + }, + "contracts/Interfaces/IBalanceRedirectPresale.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IBalanceRedirectPresale {\n\n function isClosed() external view returns (bool);\n}" + }, + "contracts/Interfaces/IBorrowerOperations.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../Dependencies/Mynt/IMassetManager.sol\";\n\n/// Common interface for the Trove Manager.\ninterface IBorrowerOperations {\n // --- Events ---\n\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n\n event TroveCreated(address indexed _borrower, uint256 arrayIndex);\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 stake,\n uint8 operation\n );\n event ZUSDBorrowingFeePaid(address indexed _borrower, uint256 _ZUSDFee);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _feeDistributorAddress feeDistributor contract address\n * @param _liquityBaseParamsAddress LiquidityBaseParams contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _activePoolAddress ActivePool contract address\n * @param _defaultPoolAddress DefaultPool contract address\n * @param _stabilityPoolAddress StabilityPool contract address\n * @param _gasPoolAddress GasPool contract address\n * @param _collSurplusPoolAddress CollSurplusPool contract address\n * @param _priceFeedAddress PrideFeed contract address\n * @param _sortedTrovesAddress SortedTroves contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _zeroStakingAddress ZEROStaking contract address\n */\n function setAddresses(\n address _feeDistributorAddress,\n address _liquityBaseParamsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _defaultPoolAddress,\n address _stabilityPoolAddress,\n address _gasPoolAddress,\n address _collSurplusPoolAddress,\n address _priceFeedAddress,\n address _sortedTrovesAddress,\n address _zusdTokenAddress,\n address _zeroStakingAddress\n ) external;\n\n /**\n * @notice payable function that creates a Trove for the caller with the requested debt, and the Ether received as collateral.\n * Successful execution is conditional mainly on the resulting collateralization ratio which must exceed the minimum (110% in Normal Mode, 150% in Recovery Mode).\n * In addition to the requested debt, extra debt is issued to pay the issuance fee, and cover the gas compensation.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _ZUSDAmount ZUSD requested debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function openTrove(\n uint256 _maxFee,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /**\n * @notice payable function that creates a Trove for the caller with the requested debt, and the Ether received as collateral.\n * Successful execution is conditional mainly on the resulting collateralization ratio which must exceed the minimum (110% in Normal Mode, 150% in Recovery Mode).\n * In addition to the requested debt, extra debt is issued to pay the issuance fee, and cover the gas compensation.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * This method is identical to `openTrove()`, but operates on NUE tokens instead of ZUSD.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _ZUSDAmount ZUSD requested debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function openNueTrove(\n uint256 _maxFee,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /// @notice payable function that adds the received Ether to the caller's active Trove.\n /// @param _upperHint upper trove id hint\n /// @param _lowerHint lower trove id hint\n function addColl(address _upperHint, address _lowerHint) external payable;\n\n /// @notice send ETH as collateral to a trove. Called by only the Stability Pool.\n /// @param _user user trove address\n /// @param _upperHint upper trove id hint\n /// @param _lowerHint lower trove id hint\n function moveETHGainToTrove(\n address _user,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /**\n * @notice withdraws `_amount` of collateral from the caller’s Trove.\n * Executes only if the user has an active Trove, the withdrawal would not pull the user’s Trove below the minimum collateralization ratio,\n * and the resulting total collateralization ratio of the system is above 150%.\n * @param _amount collateral amount to withdraw\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function withdrawColl(uint256 _amount, address _upperHint, address _lowerHint) external;\n\n /**\n * @notice issues `_amount` of ZUSD from the caller’s Trove to the caller.\n * Executes only if the Trove's collateralization ratio would remain above the minimum, and the resulting total collateralization ratio is above 150%.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _amount ZUSD amount to withdraw\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function withdrawZUSD(\n uint256 _maxFee,\n uint256 _amount,\n address _upperHint,\n address _lowerHint\n ) external;\n\n /// Borrow (withdraw) ZUSD tokens from a trove: mint new ZUSD tokens to the owner and convert it to DLLR in one transaction\n function withdrawZusdAndConvertToDLLR(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external returns (uint256);\n\n /// @notice repay `_amount` of ZUSD to the caller’s Trove, subject to leaving 50 debt in the Trove (which corresponds to the 50 ZUSD gas compensation).\n /// @param _amount ZUSD amount to repay\n /// @param _upperHint upper trove id hint\n /// @param _lowerHint lower trove id hint\n function repayZUSD(uint256 _amount, address _upperHint, address _lowerHint) external;\n\n /// Repay ZUSD tokens to a Trove: Burn the repaid ZUSD tokens, and reduce the trove's debt accordingly\n function repayZusdFromDLLR(\n uint256 _dllrAmount,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external;\n\n /**\n * @notice allows a borrower to repay all debt, withdraw all their collateral, and close their Trove.\n * Requires the borrower have a ZUSD balance sufficient to repay their trove's debt, excluding gas compensation - i.e. `(debt - 50)` ZUSD.\n */\n function closeTrove() external;\n\n /**\n * @notice allows a borrower to repay all debt, withdraw all their collateral, and close their Trove.\n * Requires the borrower have a NUE balance sufficient to repay their trove's debt, excluding gas compensation - i.e. `(debt - 50)` NUE.\n * This method is identical to `closeTrove()`, but operates on NUE tokens instead of ZUSD.\n */\n function closeNueTrove(IMassetManager.PermitParams calldata _permitParams) external;\n\n /**\n * @notice enables a borrower to simultaneously change both their collateral and debt, subject to all the restrictions that apply to individual increases/decreases of each quantity with the following particularity:\n * if the adjustment reduces the collateralization ratio of the Trove, the function only executes if the resulting total collateralization ratio is above 150%.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * The parameter is ignored if the debt is not increased with the transaction.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _collWithdrawal collateral amount to withdraw\n * @param _debtChange ZUSD amount to change\n * @param isDebtIncrease indicates if increases debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function adjustTrove(\n uint256 _maxFee,\n uint256 _collWithdrawal,\n uint256 _debtChange,\n bool isDebtIncrease,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /**\n * @notice enables a borrower to simultaneously change both their collateral and debt, subject to all the restrictions that apply to individual increases/decreases of each quantity with the following particularity:\n * if the adjustment reduces the collateralization ratio of the Trove, the function only executes if the resulting total collateralization ratio is above 150%.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * The parameter is ignored if the debt is not increased with the transaction.\n * This method is identical to `adjustTrove()`, but operates on NUE tokens instead of ZUSD.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _collWithdrawal collateral amount to withdraw\n * @param _debtChange ZUSD amount to change\n * @param isDebtIncrease indicates if increases debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function adjustNueTrove(\n uint256 _maxFee,\n uint256 _collWithdrawal,\n uint256 _debtChange,\n bool isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external payable;\n\n /**\n * @notice when a borrower’s Trove has been fully redeemed from and closed, or liquidated in Recovery Mode with a collateralization ratio above 110%,\n * this function allows the borrower to claim their ETH collateral surplus that remains in the system (collateral - debt upon redemption; collateral - 110% of the debt upon liquidation).\n */\n function claimCollateral() external;\n\n function getCompositeDebt(uint256 _debt) external view returns (uint256);\n\n function BORROWING_FEE_FLOOR() external view returns (uint256);\n\n function getMassetManager() external view returns (IMassetManager);\n}\n" + }, + "contracts/Interfaces/ICollSurplusPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface ICollSurplusPool {\n // --- Events ---\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n\n event CollBalanceUpdated(address indexed _account, uint256 _newBalance);\n event EtherSent(address _to, uint256 _amount);\n\n // --- Contract setters ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _borrowerOperationsAddress BorrowerOperations contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _activePoolAddress ActivePool contract address\n */\n function setAddresses(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress\n ) external;\n\n /// @notice Not necessarily equal to the raw ether balance - ether can be forcibly sent to contracts.\n /// @return ETH state variable\n function getETH() external view returns (uint256);\n\n /// @param _account account to retrieve collateral\n /// @return collateral\n function getCollateral(address _account) external view returns (uint256);\n\n /// @notice adds amount to current account balance. Only callable by TroveManager.\n /// @param _account account to add amount\n /// @param _amount amount to add\n function accountSurplus(address _account, uint256 _amount) external;\n\n /// @notice claims collateral for given account. Only callable by BorrowerOperations.\n /// @param _account account to send claimable collateral\n function claimColl(address _account) external;\n}\n" + }, + "contracts/Interfaces/ICommunityIssuance.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface ICommunityIssuance { \n \n // --- Events ---\n \n event SOVTokenAddressSet(address _zeroTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event StabilityPoolAddressSet(address _stabilityPoolAddress);\n event PriceFeedAddressSet(address _priceFeed);\n event RewardManagerAddressSet(address _rewardManagerAddress);\n event APRSet(uint256 _APR);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other contracts. Callable only by owner.\n * @dev initializer function, checks addresses are contracts\n * @param _zeroTokenAddress ZEROToken contract address\n * @param _communityPotAddress CommunityPot contract address\n */\n function initialize\n (\n address _zeroTokenAddress, \n address _communityPotAddress,\n address _fundingWalletAddress\n ) external;\n\n /**\n * @dev setter function to set the APR value in basis points.\n * can only be called by reward manager.\n * @param _APR apr value in basis points.\n */\n function setAPR(uint256 _APR) external;\n\n /**\n * @dev setter function to set the price feed.\n * can only be called by the owner.\n * @param _priceFeedAddress price feed address.\n */\n function setPriceFeed(address _priceFeedAddress) external;\n\n /**\n * @dev setter function to set reward manager.\n * can only be called by the owner.\n * @param _rewardManagerAddress reward manager address.\n */\n function setRewardManager(address _rewardManagerAddress) external;\n\n /// @notice issues SOV tokens based on total zusd is deposited.\n /// @return SOV tokens issuance \n function issueSOV(uint256 _totalZUSDDeposits) external returns (uint256);\n\n /// @notice sends ZERO tokens to given account\n /// @param _account account to receive the tokens\n /// @param _ZEROamount amount of tokens to transfer\n function sendSOV(address _account, uint _ZEROamount) external;\n}\n" + }, + "contracts/Interfaces/IDefaultPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IPool.sol\";\n\ninterface IDefaultPool is IPool {\n // --- Events ---\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event DefaultPoolZUSDDebtUpdated(uint256 _ZUSDDebt);\n event DefaultPoolETHBalanceUpdated(uint256 _ETH);\n\n // --- Functions ---\n\n /// @notice Send ETH to Active Pool\n /// @param _amount ETH to send\n function sendETHToActivePool(uint256 _amount) external;\n}\n" + }, + "contracts/Interfaces/IFeeDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/// Common interface for Fee Distributor.\ninterface IFeeDistributor {\n // --- Events ---\n\n event FeeSharingCollectorAddressChanged(address _feeSharingCollectorAddress);\n event ZeroStakingAddressChanged(address _zeroStakingAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event WrbtcAddressChanged(address _wrbtcAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event ZUSDDistributed(uint256 _zusdDistributedAmount);\n event RBTCistributed(uint256 _rbtcDistributedAmount);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _feeSharingCollectorAddress FeeSharingCollector address\n * @param _zeroStakingAddress ZEROStaking contract address\n * @param _borrowerOperationsAddress borrowerOperations contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _wrbtcAddress wrbtc ERC20 contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _activePoolAddress ActivePool contract address\n */\n function setAddresses(\n address _feeSharingCollectorAddress,\n address _zeroStakingAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _wrbtcAddress,\n address _zusdTokenAddress,\n address _activePoolAddress\n ) external;\n\n function distributeFees() external;\n}\n" + }, + "contracts/Interfaces/IFeeSharingCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\n/**\n * @title Interface for Sovryn protocol fee sharing collector.\n * @dev Interfaces are used to cast a contract address into a callable instance.\n * */\ninterface IFeeSharingCollector {\n\tfunction withdrawFees(address _token) external;\n\n\tfunction transferTokens(address _token, uint96 _amount) external;\n\n\tfunction withdraw(\n\t\taddress _loanPoolToken,\n\t\tuint32 _maxCheckpoints,\n\t\taddress _receiver\n\t) external;\n\n\tfunction transferRBTC() external payable;\n}\n" + }, + "contracts/Interfaces/ILiquityBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IPriceFeed.sol\";\nimport \"./ILiquityBaseParams.sol\";\n\ninterface ILiquityBase {\n /// @return PriceFeed contract\n function priceFeed() external view returns (IPriceFeed);\n\n /// @return LiquityBaseParams contract\n function liquityBaseParams() external view returns (ILiquityBaseParams);\n}\n" + }, + "contracts/Interfaces/ILiquityBaseParams.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface ILiquityBaseParams {\n\n /// Minimum collateral ratio for individual troves\n function MCR() external view returns (uint);\n\n /// Critical system collateral ratio. If the system's total collateral ratio (TCR) falls below the CCR, Recovery Mode is triggered.\n function CCR() external view returns (uint);\n\n function PERCENT_DIVISOR() external view returns (uint);\n\n function BORROWING_FEE_FLOOR() external view returns (uint);\n\n /**\n * Half-life of 12h. 12h = 720 min\n * (1/2) = d^720 => d = (1/2)^(1/720)\n */\n function REDEMPTION_FEE_FLOOR() external view returns (uint);\n\n function MAX_BORROWING_FEE() external view returns (uint);\n\n}" + }, + "contracts/Interfaces/IPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// Common interface for the Pools.\ninterface IPool {\n // --- Events ---\n\n event ETHBalanceUpdated(uint _newBalance);\n event ZUSDBalanceUpdated(uint _newBalance);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n event DefaultPoolAddressChanged(address _newDefaultPoolAddress);\n event StabilityPoolAddressChanged(address _newStabilityPoolAddress);\n event EtherSent(address _to, uint _amount);\n\n // --- Functions ---\n\n /// @notice Not necessarily equal to the raw ether balance - ether can be forcibly sent to contracts.\n /// @return ETH pool balance\n function getETH() external view returns (uint);\n\n /// @return ZUSD debt pool balance\n function getZUSDDebt() external view returns (uint);\n\n /// @notice Increases ZUSD debt of the pool.\n /// @param _amount ZUSD amount to add to the pool debt\n function increaseZUSDDebt(uint _amount) external;\n\n /// @notice Decreases ZUSD debt of the pool.\n /// @param _amount ZUSD amount to subtract to the pool debt\n function decreaseZUSDDebt(uint _amount) external;\n}\n" + }, + "contracts/Interfaces/IPriceFeed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IPriceFeed {\n // --- Events ---\n event LastGoodPriceUpdated(uint256 _lastGoodPrice);\n\n // --- Function ---\n\n /// @notice Returns the latest price obtained from the Oracle. Called by Zero functions that require a current price.\n /// It uses the main price feed and fallback to the backup one in case of an error. If both fail return the last\n /// good price seen.\n /// @dev It's also callable by anyone externally\n /// @return The price\n function fetchPrice() external returns (uint256);\n}\n" + }, + "contracts/Interfaces/IPriceFeedSovryn.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IPriceFeedSovryn {\n function queryRate(address sourceToken, address destToken)\n external\n view\n returns (uint256 rate, uint256 precision);\n\n function queryPrecision(address sourceToken, address destToken)\n external\n view\n returns (uint256 precision);\n\n function queryReturn(\n address sourceToken,\n address destToken,\n uint256 sourceAmount\n ) external view returns (uint256 destAmount);\n\n function checkPriceDisagreement(\n address sourceToken,\n address destToken,\n uint256 sourceAmount,\n uint256 destAmount,\n uint256 maxSlippage\n ) external view returns (uint256 sourceToDestSwapRate);\n\n function amountInEth(address Token, uint256 amount) external view returns (uint256 ethAmount);\n\n function getMaxDrawdown(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount,\n uint256 maintenanceMargin\n ) external view returns (uint256);\n\n function getCurrentMarginAndCollateralSize(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount\n ) external view returns (uint256 currentMargin, uint256 collateralInEthAmount);\n\n function getCurrentMargin(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount\n ) external view returns (uint256 currentMargin, uint256 collateralToLoanRate);\n\n function shouldLiquidate(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount,\n uint256 maintenanceMargin\n ) external view returns (bool);\n\n function getFastGasPrice(address payToken) external view returns (uint256);\n}\n" + }, + "contracts/Interfaces/ISortedTroves.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// Common interface for the SortedTroves Doubly Linked List.\ninterface ISortedTroves {\n // --- Events ---\n\n event SortedTrovesAddressChanged(address _sortedDoublyLLAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event NodeAdded(address _id, uint256 _NICR);\n event NodeRemoved(address _id);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts and size. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _size max size of troves list\n * @param _TroveManagerAddress TroveManager contract address\n * @param _borrowerOperationsAddress BorrowerOperations contract address\n */\n function setParams(\n uint256 _size,\n address _TroveManagerAddress,\n address _borrowerOperationsAddress\n ) external;\n\n /**\n * @dev Add a node to the list\n * @param _id Node's id\n * @param _ICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function insert(\n address _id,\n uint256 _ICR,\n address _prevId,\n address _nextId\n ) external;\n\n /**\n * @dev Remove a node from the list\n * @param _id Node's id\n */\n function remove(address _id) external;\n\n /**\n * @dev Re-insert the node at a new position, based on its new NICR\n * @param _id Node's id\n * @param _newICR Node's new NICR\n * @param _prevId Id of previous node for the new insert position\n * @param _nextId Id of next node for the new insert position\n */\n function reInsert(\n address _id,\n uint256 _newICR,\n address _prevId,\n address _nextId\n ) external;\n\n /**\n * @dev Checks if the list contains a node\n * @param _id Node's id\n * @return true if list contains a node with given id\n */\n function contains(address _id) external view returns (bool);\n\n /**\n * @dev Checks if the list is full\n * @return true if list is full\n */\n function isFull() external view returns (bool);\n\n /**\n * @dev Checks if the list is empty\n * @return true if list is empty\n */\n function isEmpty() external view returns (bool);\n\n /**\n * @return list current size\n */\n function getSize() external view returns (uint256);\n\n /**\n * @return list max size\n */\n function getMaxSize() external view returns (uint256);\n\n /**\n * @return the first node in the list (node with the largest NICR)\n */\n function getFirst() external view returns (address);\n\n /**\n * @return the last node in the list (node with the smallest NICR)\n */\n function getLast() external view returns (address);\n\n /**\n * @param _id Node's id\n * @return the next node (with a smaller NICR) in the list for a given node\n */\n function getNext(address _id) external view returns (address);\n\n /**\n * @param _id Node's id\n * @return the previous node (with a larger NICR) in the list for a given node\n */\n function getPrev(address _id) external view returns (address);\n\n /**\n * @notice Check if a pair of nodes is a valid insertion point for a new node with the given NICR\n * @param _ICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function validInsertPosition(\n uint256 _ICR,\n address _prevId,\n address _nextId\n ) external view returns (bool);\n\n /**\n * @notice Find the insert position for a new node with the given NICR\n * @param _ICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function findInsertPosition(\n uint256 _ICR,\n address _prevId,\n address _nextId\n ) external view returns (address, address);\n}\n" + }, + "contracts/Interfaces/IStabilityPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../Dependencies/Mynt/IMassetManager.sol\";\n\n/*\n * The Stability Pool holds ZUSD tokens deposited by Stability Pool depositors.\n *\n * When a trove is liquidated, then depending on system conditions, some of its ZUSD debt gets offset with\n * ZUSD in the Stability Pool: that is, the offset debt evaporates, and an equal amount of ZUSD tokens in the Stability Pool is burned.\n *\n * Thus, a liquidation causes each depositor to receive a ZUSD loss, in proportion to their deposit as a share of total deposits.\n * They also receive an ETH gain, as the ETH collateral of the liquidated trove is distributed among Stability depositors,\n * in the same proportion.\n *\n * When a liquidation occurs, it depletes every deposit by the same fraction: for example, a liquidation that depletes 40%\n * of the total ZUSD in the Stability Pool, depletes 40% of each deposit.\n *\n * A deposit that has experienced a series of liquidations is termed a \"compounded deposit\": each liquidation depletes the deposit,\n * multiplying it by some factor in range ]0,1[\n *\n * Please see the implementation spec in the proof document, which closely follows on from the compounded deposit / ETH gain derivations:\n * https://github.com/liquity/liquity/blob/master/papers/Scalable_Reward_Distribution_with_Compounding_Stakes.pdf\n *\n * --- SOV ISSUANCE TO STABILITY POOL DEPOSITORS ---\n *\n * An SOV issuance event occurs at every deposit operation, and every liquidation.\n *\n * Each deposit is tagged with the address of the front end through which it was made.\n *\n * All deposits earn a share of the issued SOV in proportion to the deposit as a share of total deposits. The SOV earned\n * by a given deposit, is split between the depositor and the front end through which the deposit was made, based on the front end's kickbackRate.\n *\n * Please see the system Readme for an overview:\n * https://github.com/liquity/dev/blob/main/README.md#zero-issuance-to-stability-providers\n */\ninterface IStabilityPool {\n // --- Events ---\n\n event StabilityPoolETHBalanceUpdated(uint _newBalance);\n event StabilityPoolZUSDBalanceUpdated(uint _newBalance);\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n event DefaultPoolAddressChanged(address _newDefaultPoolAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event SortedTrovesAddressChanged(address _newSortedTrovesAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event CommunityIssuanceAddressChanged(address _newCommunityIssuanceAddress);\n\n event P_Updated(uint _P);\n event S_Updated(uint _S, uint128 _epoch, uint128 _scale);\n event G_Updated(uint _G, uint128 _epoch, uint128 _scale);\n event EpochUpdated(uint128 _currentEpoch);\n event ScaleUpdated(uint128 _currentScale);\n\n event FrontEndRegistered(address indexed _frontEnd, uint _kickbackRate);\n event FrontEndTagSet(address indexed _depositor, address indexed _frontEnd);\n\n event DepositSnapshotUpdated(address indexed _depositor, uint _P, uint _S, uint _G);\n event FrontEndSnapshotUpdated(address indexed _frontEnd, uint _P, uint _G);\n event UserDepositChanged(address indexed _depositor, uint _newDeposit);\n event FrontEndStakeChanged(\n address indexed _frontEnd,\n uint _newFrontEndStake,\n address _depositor\n );\n\n event ETHGainWithdrawn(address indexed _depositor, uint _ETH, uint _ZUSDLoss);\n event SOVPaidToDepositor(address indexed _depositor, uint _SOV);\n event SOVPaidToFrontEnd(address indexed _frontEnd, uint _SOV);\n event EtherSent(address _to, uint _amount);\n\n event WithdrawFromSpAndConvertToDLLR(\n address _depositor,\n uint256 _zusdAmountRequested,\n uint256 _dllrAmountReceived\n );\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Liquity contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _liquityBaseParamsAddress LiquidityBaseParams contract address\n * @param _borrowerOperationsAddress BorrowerOperations contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _activePoolAddress ActivePool contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _sortedTrovesAddress SortedTroves contract address\n * @param _priceFeedAddress PriceFeed contract address\n * @param _communityIssuanceAddress CommunityIssuanceAddress\n */\n function setAddresses(\n address _liquityBaseParamsAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _zusdTokenAddress,\n address _sortedTrovesAddress,\n address _priceFeedAddress,\n address _communityIssuanceAddress\n ) external;\n\n /**\n * @notice Initial checks:\n * - Frontend is registered or zero address\n * - Sender is not a registered frontend\n * - _amount is not zero\n * ---\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Tags the deposit with the provided front end tag param, if it's a new deposit\n * - Sends depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Increases deposit and tagged front end's stake, and takes new snapshots for each.\n * @param _amount amount to provide\n * @param _frontEndTag frontend address to receive accumulated SOV gains\n */\n function provideToSP(uint _amount, address _frontEndTag) external;\n\n /**\n * @notice Initial checks:\n * - _amount is zero or there are no under collateralized troves left in the system\n * - User has a non zero deposit\n * ---\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Removes the deposit's front end tag if it is a full withdrawal\n * - Sends all depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Decreases deposit and tagged front end's stake, and takes new snapshots for each.\n *\n * If _amount > userDeposit, the user withdraws all of their compounded deposit.\n * @param _amount amount to withdraw\n */\n function withdrawFromSP(uint _amount) external;\n\n /**\n * @notice Initial checks:\n * - User has a non zero deposit\n * - User has an open trove\n * - User has some ETH gain\n * ---\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Sends all depositor's SOV gain to depositor\n * - Sends all tagged front end's SOV gain to the tagged front end\n * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove\n * - Leaves their compounded deposit in the Stability Pool\n * - Updates snapshots for deposit and tagged front end stake\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external;\n\n /**\n * @notice Initial checks:\n * - Frontend (sender) not already registered\n * - User (sender) has no deposit\n * - _kickbackRate is in the range [0, 100%]\n * ---\n * Front end makes a one-time selection of kickback rate upon registering\n * @param _kickbackRate kickback rate selected by frontend\n */\n function registerFrontEnd(uint _kickbackRate) external;\n\n /**\n * @notice Initial checks:\n * - Caller is TroveManager\n * ---\n * Cancels out the specified debt against the ZUSD contained in the Stability Pool (as far as possible)\n * and transfers the Trove's ETH collateral from ActivePool to StabilityPool.\n * Only called by liquidation functions in the TroveManager.\n * @param _debt debt to cancel\n * @param _coll collateral to transfer\n */\n function offset(uint _debt, uint _coll) external;\n\n /**\n * @return the total amount of ETH held by the pool, accounted in an internal variable instead of `balance`,\n * to exclude edge cases like ETH received from a self-destruct.\n */\n function getETH() external view returns (uint);\n\n /**\n * @return ZUSD held in the pool. Changes when users deposit/withdraw, and when Trove debt is offset.\n */\n function getTotalZUSDDeposits() external view returns (uint);\n\n /**\n * @notice Calculates the ETH gain earned by the deposit since its last snapshots were taken.\n * @param _depositor address to calculate ETH gain\n * @return ETH gain from given depositor\n */\n function getDepositorETHGain(address _depositor) external view returns (uint);\n\n /**\n * @notice Calculate the SOV gain earned by a deposit since its last snapshots were taken.\n * If not tagged with a front end, the depositor gets a 100% cut of what their deposit earned.\n * Otherwise, their cut of the deposit's earnings is equal to the kickbackRate, set by the front end through\n * which they made their deposit.\n * @param _depositor address to calculate ETH gain\n * @return SOV gain from given depositor\n */\n function getDepositorSOVGain(address _depositor) external view returns (uint);\n\n /**\n * @param _frontEnd front end address\n * @return the SOV gain earned by the front end.\n */\n function getFrontEndSOVGain(address _frontEnd) external view returns (uint);\n\n /**\n * @param _depositor depositor address\n * @return the user's compounded deposit.\n */\n function getCompoundedZUSDDeposit(address _depositor) external view returns (uint);\n\n /**\n * @notice The front end's compounded stake is equal to the sum of its depositors' compounded deposits.\n * @param _frontEnd front end address\n * @return the front end's compounded stake.\n */\n function getCompoundedFrontEndStake(address _frontEnd) external view returns (uint);\n\n //DLLR _owner or _spender can convert a specified amount of DLLR into ZUSD via Sovryn Mynt and deposit the ZUSD into the SOV Stability Pool, all in a single transaction\n function provideToSpFromDLLR(\n uint _dllrAmount,\n IMassetManager.PermitParams calldata _permitParams\n ) external;\n\n /// Stability Pool depositor can withdraw a specified amount of ZUSD from the SOV Stability Pool and optionally convert the ZUSD to DLLR via Sovryn Mynt, all in a single transaction\n function withdrawFromSpAndConvertToDLLR(uint256 _zusdAmount) external;\n\n /**\n * Fallback function\n * Only callable by Active Pool, it just accounts for ETH received\n * receive() external payable;\n */\n}\n" + }, + "contracts/Interfaces/ITroveManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./ILiquityBase.sol\";\nimport \"./IStabilityPool.sol\";\nimport \"./IZUSDToken.sol\";\nimport \"./IZEROToken.sol\";\nimport \"./IZEROStaking.sol\";\nimport \"../Dependencies/Mynt/IMassetManager.sol\";\n\n/// Common interface for the Trove Manager.\ninterface ITroveManager is ILiquityBase {\n // --- Events ---\n\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerRedeemOpsAddressChanged(address _troveManagerRedeemOps);\n event LiquityBaseParamsAddressChanges(address _borrowerOperationsAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZEROTokenAddressChanged(address _zeroTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n\n event Liquidation(\n uint256 _liquidatedDebt,\n uint256 _liquidatedColl,\n uint256 _collGasCompensation,\n uint256 _ZUSDGasCompensation\n );\n event Redemption(\n uint256 _attemptedZUSDAmount,\n uint256 _actualZUSDAmount,\n uint256 _ETHSent,\n uint256 _ETHFee\n );\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 stake,\n uint8 operation\n );\n event TroveLiquidated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint8 operation\n );\n event BaseRateUpdated(uint256 _baseRate);\n event LastFeeOpTimeUpdated(uint256 _lastFeeOpTime);\n event TotalStakesUpdated(uint256 _newTotalStakes);\n event SystemSnapshotsUpdated(uint256 _totalStakesSnapshot, uint256 _totalCollateralSnapshot);\n event LTermsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveSnapshotsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveIndexUpdated(address _borrower, uint256 _newIndex);\n\n struct TroveManagerInitAddressesParams {\n address _feeDistributorAddress;\n address _troveManagerRedeemOps;\n address _liquityBaseParamsAddress;\n address _borrowerOperationsAddress;\n address _activePoolAddress;\n address _defaultPoolAddress;\n address _stabilityPoolAddress;\n address _gasPoolAddress;\n address _collSurplusPoolAddress;\n address _priceFeedAddress;\n address _zusdTokenAddress;\n address _sortedTrovesAddress;\n address _zeroTokenAddress;\n address _zeroStakingAddress;\n }\n\n // --- Functions ---\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _troveManagerInitAddresses addresses list to intialize TroveManager with _\n * _feeDistributorAddress feeDistributor contract address\n * _troveManagerRedeemOps TroveManagerRedeemOps contract address\n * _liquityBaseParamsAddress LiquityBaseParams contract address\n * _borrowerOperationsAddress BorrowerOperations contract address\n * _activePoolAddress ActivePool contract address\n * _defaultPoolAddress DefaultPool contract address\n * _stabilityPoolAddress StabilityPool contract address\n * _gasPoolAddress GasPool contract address\n * _collSurplusPoolAddress CollSurplusPool contract address\n * _priceFeedAddress PriceFeed contract address\n * _zusdTokenAddress ZUSDToken contract address\n * _sortedTrovesAddress SortedTroves contract address\n * _zeroTokenAddress ZEROToken contract address\n * _zeroStakingAddress ZEROStaking contract address\n */\n function setAddresses(\n TroveManagerInitAddressesParams memory _troveManagerInitAddresses\n ) external;\n\n function setTroveManagerRedeemOps(address _troveManagerRedeemOps) external;\n\n /// @return Trove owners count\n function getTroveOwnersCount() external view returns (uint256);\n\n /// @param _index Trove owner index\n /// @return Trove from TroveOwners array in given index\n function getTroveFromTroveOwnersArray(uint256 _index) external view returns (address);\n\n /// @param _borrower borrower address\n /// @return the nominal collateral ratio (ICR) of a given Trove, without the price. Takes a trove's pending coll and debt rewards from redistributions into account.\n function getNominalICR(address _borrower) external view returns (uint256);\n\n /// @notice computes the user’s individual collateralization ratio (ICR) based on their total collateral and total ZUSD debt. Returns 2^256 -1 if they have 0 debt.\n /// @param _borrower borrower address\n /// @param _price ETH price\n /// @return the current collateral ratio (ICR) of a given Trove. Takes a trove's pending coll and debt rewards from redistributions into account.\n function getCurrentICR(address _borrower, uint256 _price) external view returns (uint256);\n\n /// @notice Closes the trove if its ICR is lower than the minimum collateral ratio.\n /// @param _borrower borrower address\n function liquidate(address _borrower) external;\n\n /**\n * @notice Liquidate a sequence of troves. Closes a maximum number of n under-collateralized Troves,\n * starting from the one with the lowest collateral ratio in the system, and moving upwards\n * @param _n max number of under-collateralized Troves to liquidate\n */\n function liquidateTroves(uint256 _n) external;\n\n /**\n * @notice Attempt to liquidate a custom list of troves provided by the caller.\n * @param _troveArray list of trove addresses\n */\n function batchLiquidateTroves(address[] calldata _troveArray) external;\n\n /**\n * @notice Send _ZUSDamount ZUSD to the system and redeem the corresponding amount of collateral from as many Troves as are needed to fill the redemption\n * request. Applies pending rewards to a Trove before reducing its debt and coll.\n *\n * Note that if _amount is very large, this function can run out of gas, specially if traversed troves are small. This can be easily avoided by\n * splitting the total _amount in appropriate chunks and calling the function multiple times.\n *\n * Param `_maxIterations` can also be provided, so the loop through Troves is capped (if it’s zero, it will be ignored).This makes it easier to\n * avoid OOG for the frontend, as only knowing approximately the average cost of an iteration is enough, without needing to know the “topology”\n * of the trove list. It also avoids the need to set the cap in stone in the contract, nor doing gas calculations, as both gas price and opcode\n * costs can vary.\n *\n * All Troves that are redeemed from -- with the likely exception of the last one -- will end up with no debt left, therefore they will be closed.\n * If the last Trove does have some remaining debt, it has a finite ICR, and the reinsertion could be anywhere in the list, therefore it requires a hint.\n * A frontend should use getRedemptionHints() to calculate what the ICR of this Trove will be after redemption, and pass a hint for its position\n * in the sortedTroves list along with the ICR value that the hint was found for.\n *\n * If another transaction modifies the list between calling getRedemptionHints() and passing the hints to redeemCollateral(), it\n * is very likely that the last (partially) redeemed Trove would end up with a different ICR than what the hint is for. In this case the\n * redemption will stop after the last completely redeemed Trove and the sender will keep the remaining ZUSD amount, which they can attempt\n * to redeem later.\n *\n * @param _ZUSDAmount ZUSD amount to send to the system\n * @param _firstRedemptionHint calculated ICR hint of first trove after redemption\n * @param _maxIterations max Troves iterations (can be 0)\n * @param _maxFee max fee percentage to accept\n */\n function redeemCollateral(\n uint256 _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFee\n ) external;\n\n function redeemCollateralViaDLLR(\n uint256 _dllrAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage,\n IMassetManager.PermitParams calldata _permitParams\n ) external;\n\n /// @notice Update borrower's stake based on their latest collateral value\n /// @param _borrower borrower address\n function updateStakeAndTotalStakes(address _borrower) external returns (uint256);\n\n /// @notice Update borrower's snapshots of L_ETH and L_ZUSDDebt to reflect the current values\n /// @param _borrower borrower address\n function updateTroveRewardSnapshots(address _borrower) external;\n\n /// @notice Push the owner's address to the Trove owners list, and record the corresponding array index on the Trove struct\n /// @param _borrower borrower address\n /// @return index where Trove was inserted\n function addTroveOwnerToArray(address _borrower) external returns (uint256 index);\n\n /// @notice Add the borrowers's coll and debt rewards earned from redistributions, to their Trove\n /// @param _borrower borrower address\n function applyPendingRewards(address _borrower) external;\n\n /// @param _borrower borrower address\n /// @return the borrower's pending accumulated ETH reward, earned by their stake\n function getPendingETHReward(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return the borrower's pending accumulated ZUSD reward, earned by their stake\n function getPendingZUSDDebtReward(address _borrower) external view returns (uint256);\n\n /*\n * @notice A Trove has pending rewards if its snapshot is less than the current rewards per-unit-staked sum:\n * this indicates that rewards have occured since the snapshot was made, and the user therefore has\n * pending rewards\n *\n * @param _borrower borrower address\n * @return true if has pending rewards\n */\n function hasPendingRewards(address _borrower) external view returns (bool);\n\n /// @notice returns the Troves entire debt and coll, including pending rewards from redistributions.\n /// @param _borrower borrower address\n function getEntireDebtAndColl(\n address _borrower\n )\n external\n view\n returns (\n uint256 debt,\n uint256 coll,\n uint256 pendingZUSDDebtReward,\n uint256 pendingETHReward\n );\n\n /// @notice Close given trove. Called by BorrowerOperations.\n /// @param _borrower borrower address\n function closeTrove(address _borrower) external;\n\n /// @notice Remove borrower's stake from the totalStakes sum, and set their stake to 0\n /// @param _borrower borrower address\n function removeStake(address _borrower) external;\n\n /// @return calculated redemption rate using baseRate\n function getRedemptionRate() external view returns (uint256);\n\n /// @return calculated redemption rate using calculated decayed as base rate\n function getRedemptionRateWithDecay() external view returns (uint256);\n\n /// @notice The redemption fee is taken as a cut of the total ETH drawn from the system in a redemption. It is based on the current redemption rate.\n /// @param _ETHDrawn ETH drawn\n function getRedemptionFeeWithDecay(uint256 _ETHDrawn) external view returns (uint256);\n\n /// @return borrowing rate\n function getBorrowingRate() external view returns (uint256);\n\n /// @return borrowing rate calculated using decayed as base rate\n function getBorrowingRateWithDecay() external view returns (uint256);\n\n /// @param ZUSDDebt ZUSD debt amount to calculate fee\n /// @return borrowing fee using borrowing rate\n function getBorrowingFee(uint256 ZUSDDebt) external view returns (uint256);\n\n /// @param _ZUSDDebt ZUSD debt amount to calculate fee\n /// @return borrowing fee using borrowing rate with decay\n function getBorrowingFeeWithDecay(uint256 _ZUSDDebt) external view returns (uint256);\n\n /// @notice Updates the baseRate state variable based on time elapsed since the last redemption or ZUSD borrowing operation.\n function decayBaseRateFromBorrowing() external;\n\n /// @param _borrower borrower address\n /// @return Trove status from given trove\n function getTroveStatus(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return Trove stake from given trove\n function getTroveStake(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return Trove debt from given trove\n function getTroveDebt(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return Trove collateral from given trove\n function getTroveColl(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @param num status to set\n function setTroveStatus(address _borrower, uint256 num) external;\n\n /// @param _borrower borrower address\n /// @param _collIncrease amount of collateral to increase\n /// @return new trove collateral\n function increaseTroveColl(\n address _borrower,\n uint256 _collIncrease\n ) external returns (uint256);\n\n /// @param _borrower borrower address\n /// @param _collDecrease amount of collateral to decrease\n /// @return new trove collateral\n function decreaseTroveColl(\n address _borrower,\n uint256 _collDecrease\n ) external returns (uint256);\n\n /// @param _borrower borrower address\n /// @param _debtIncrease amount of debt to increase\n /// @return new trove debt\n function increaseTroveDebt(\n address _borrower,\n uint256 _debtIncrease\n ) external returns (uint256);\n\n /// @param _borrower borrower address\n /// @param _debtDecrease amount of debt to decrease\n /// @return new trove debt\n function decreaseTroveDebt(\n address _borrower,\n uint256 _debtDecrease\n ) external returns (uint256);\n\n /**\n * @param _price ETH price\n * @return the total collateralization ratio (TCR) of the system.\n * The TCR is based on the the entire system debt and collateral (including pending rewards).\n */\n function getTCR(uint256 _price) external view returns (uint256);\n\n function MCR() external view returns (uint256);\n\n function CCR() external view returns (uint256);\n\n /// @notice reveals whether or not the system is in Recovery Mode (i.e. whether the Total Collateralization Ratio (TCR) is below the Critical Collateralization Ratio (CCR)).\n function checkRecoveryMode(uint256 _price) external view returns (bool);\n}\n" + }, + "contracts/Interfaces/IWrbtc.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Dependencies/IERC20.sol\";\n\ninterface IWrbtc is IERC20 {\n\t\n\tfunction deposit() external payable;\n\n\tfunction withdraw(uint256 wad) external;\n\n}\n" + }, + "contracts/Interfaces/IZEROStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IZEROStaking {\n // --- Events --\n\n event ZEROTokenAddressSet(address _zeroTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event FeeDistributorAddressAddressSet(address _feeDistributorAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event StakeChanged(address indexed staker, uint256 newStake);\n event StakingGainsWithdrawn(address indexed staker, uint256 ZUSDGain, uint256 ETHGain);\n event F_ETHUpdated(uint256 _F_ETH);\n event F_ZUSDUpdated(uint256 _F_ZUSD);\n event TotalZEROStakedUpdated(uint256 _totalZEROStaked);\n event EtherSent(address _account, uint256 _amount);\n event StakerSnapshotsUpdated(address _staker, uint256 _F_ETH, uint256 _F_ZUSD);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _zeroTokenAddress ZEROToken contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _feeDistributorAddress FeeDistributorAddress contract address\n * @param _activePoolAddress ActivePool contract address\n */\n function setAddresses(\n address _zeroTokenAddress,\n address _zusdTokenAddress,\n address _feeDistributorAddress,\n address _activePoolAddress\n ) external;\n\n /// @notice If caller has a pre-existing stake, send any accumulated ETH and ZUSD gains to them.\n /// @param _ZEROamount ZERO tokens to stake\n function stake(uint256 _ZEROamount) external;\n\n /**\n * @notice Unstake the ZERO and send the it back to the caller, along with their accumulated ZUSD & ETH gains.\n * If requested amount > stake, send their entire stake.\n * @param _ZEROamount ZERO tokens to unstake\n */\n function unstake(uint256 _ZEROamount) external;\n\n /// @param _ETHFee ETH fee\n /// @notice increase ETH fee\n function increaseF_ETH(uint256 _ETHFee) external;\n\n /// @param _ZEROFee ZUSD fee\n /// @notice increase ZUSD fee\n function increaseF_ZUSD(uint256 _ZEROFee) external;\n\n /// @param _user user address\n /// @return pending ETH gain of given user\n function getPendingETHGain(address _user) external view returns (uint256);\n\n /// @param _user user address\n /// @return pending ZUSD gain of given user\n function getPendingZUSDGain(address _user) external view returns (uint256);\n}\n" + }, + "contracts/Interfaces/IZEROToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Dependencies/IERC2612.sol\";\n\ninterface IZEROToken is IERC20, IERC2612 { \n\n // --- Functions ---\n\n /// @notice send zero tokens to ZEROStaking contract\n /// @param _sender sender address\n /// @param _amount amount to send\n function sendToZEROStaking(address _sender, uint256 _amount) external;\n\n /// @return deployment start time\n function getDeploymentStartTime() external view returns (uint256);\n\n}\n" + }, + "contracts/Interfaces/IZUSDToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Dependencies/IERC2612.sol\";\n\ninterface IZUSDToken is IERC20, IERC2612 { \n \n // --- Events ---\n\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event StabilityPoolAddressChanged(address _newStabilityPoolAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n\n event ZUSDTokenBalanceUpdated(address _user, uint _amount);\n\n // --- Functions ---\n\n function mint(address _account, uint256 _amount) external;\n\n function burn(address _account, uint256 _amount) external;\n\n function sendToPool(address _sender, address poolAddress, uint256 _amount) external;\n\n function returnFromPool(address poolAddress, address user, uint256 _amount ) external;\n}\n" + }, + "contracts/LiquityBaseParams.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ILiquityBaseParams.sol\";\nimport \"./Dependencies/BaseMath.sol\";\nimport \"./Dependencies/LiquityMath.sol\";\n\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/Initializable.sol\";\n\ncontract LiquityBaseParams is ILiquityBaseParams, Ownable, Initializable, BaseMath {\n using SafeMath for uint256;\n\n /// Minimum collateral ratio for individual troves\n uint256 public override MCR;\n\n /// Critical system collateral ratio. If the system's total collateral ratio (TCR) falls below the CCR, Recovery Mode is triggered.\n uint256 public override CCR;\n\n uint256 public override PERCENT_DIVISOR;\n\n uint256 public override BORROWING_FEE_FLOOR;\n\n /**\n * Half-life of 12h. 12h = 720 min\n * (1/2) = d^720 => d = (1/2)^(1/720)\n */\n uint256 public override REDEMPTION_FEE_FLOOR;\n\n uint256 public override MAX_BORROWING_FEE;\n\n function initialize() public initializer onlyOwner {\n MCR = 1100000000000000000; // 110%\n CCR = 1500000000000000000; // 150%\n PERCENT_DIVISOR = 200; // dividing by 200 yields 0.5%\n BORROWING_FEE_FLOOR = (DECIMAL_PRECISION / 1000) * 5; // 0.5%\n REDEMPTION_FEE_FLOOR = (DECIMAL_PRECISION / 1000) * 5; // 0.5%\n MAX_BORROWING_FEE = (DECIMAL_PRECISION / 100) * 5; // 5%\n }\n\n function setMCR(uint256 MCR_) public onlyOwner {\n MCR = MCR_;\n }\n\n function setCCR(uint256 CCR_) public onlyOwner {\n CCR = CCR_;\n }\n\n function setPercentDivisor(uint256 PERCENT_DIVISOR_) public onlyOwner {\n PERCENT_DIVISOR = PERCENT_DIVISOR_;\n }\n\n function setBorrowingFeeFloor(uint256 BORROWING_FEE_FLOOR_) public onlyOwner {\n BORROWING_FEE_FLOOR = BORROWING_FEE_FLOOR_;\n }\n\n function setRedemptionFeeFloor(uint256 REDEMPTION_FEE_FLOOR_) public onlyOwner {\n REDEMPTION_FEE_FLOOR = REDEMPTION_FEE_FLOOR_;\n }\n\n function setMaxBorrowingFee(uint256 MAX_BORROWING_FEE_) public onlyOwner {\n MAX_BORROWING_FEE = MAX_BORROWING_FEE_;\n }\n}\n" + }, + "contracts/MultiTroveGetter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./TroveManager.sol\";\nimport \"./SortedTroves.sol\";\nimport \"./MultiTroveGetterStorage.sol\";\n\n/** Helper contract for grabbing Trove data for the front end. Not part of the core Zero system. */\ncontract MultiTroveGetter is MultiTroveGetterStorage {\n struct CombinedTroveData {\n address owner;\n uint256 debt;\n uint256 coll;\n uint256 stake;\n uint256 snapshotETH;\n uint256 snapshotZUSDDebt;\n }\n\n function setAddresses(TroveManager _troveManager, ISortedTroves _sortedTroves)\n public\n onlyOwner\n {\n troveManager = _troveManager;\n sortedTroves = _sortedTroves;\n }\n\n function getMultipleSortedTroves(int256 _startIdx, uint256 _count)\n external\n view\n returns (CombinedTroveData[] memory _troves)\n {\n uint256 startIdx;\n bool descend;\n\n if (_startIdx >= 0) {\n startIdx = uint256(_startIdx);\n descend = true;\n } else {\n startIdx = uint256(-(_startIdx + 1));\n descend = false;\n }\n\n uint256 sortedTrovesSize = sortedTroves.getSize();\n\n if (startIdx >= sortedTrovesSize) {\n _troves = new CombinedTroveData[](0);\n } else {\n uint256 maxCount = sortedTrovesSize - startIdx;\n\n if (_count > maxCount) {\n _count = maxCount;\n }\n\n if (descend) {\n _troves = _getMultipleSortedTrovesFromHead(startIdx, _count);\n } else {\n _troves = _getMultipleSortedTrovesFromTail(startIdx, _count);\n }\n }\n }\n\n function _getMultipleSortedTrovesFromHead(uint256 _startIdx, uint256 _count)\n internal\n view\n returns (CombinedTroveData[] memory _troves)\n {\n address currentTroveowner = sortedTroves.getFirst();\n\n for (uint256 idx = 0; idx < _startIdx; ++idx) {\n currentTroveowner = sortedTroves.getNext(currentTroveowner);\n }\n\n _troves = new CombinedTroveData[](_count);\n\n for (uint256 idx = 0; idx < _count; ++idx) {\n _troves[idx].owner = currentTroveowner;\n (\n _troves[idx].debt,\n _troves[idx].coll,\n _troves[idx].stake,\n /* status */\n /* arrayIndex */\n ,\n\n ) = troveManager.Troves(currentTroveowner);\n (_troves[idx].snapshotETH, _troves[idx].snapshotZUSDDebt) = troveManager\n .rewardSnapshots(currentTroveowner);\n\n currentTroveowner = sortedTroves.getNext(currentTroveowner);\n }\n }\n\n function _getMultipleSortedTrovesFromTail(uint256 _startIdx, uint256 _count)\n internal\n view\n returns (CombinedTroveData[] memory _troves)\n {\n address currentTroveowner = sortedTroves.getLast();\n\n for (uint256 idx = 0; idx < _startIdx; ++idx) {\n currentTroveowner = sortedTroves.getPrev(currentTroveowner);\n }\n\n _troves = new CombinedTroveData[](_count);\n\n for (uint256 idx = 0; idx < _count; ++idx) {\n _troves[idx].owner = currentTroveowner;\n (\n _troves[idx].debt,\n _troves[idx].coll,\n _troves[idx].stake,\n /* status */\n /* arrayIndex */\n ,\n\n ) = troveManager.Troves(currentTroveowner);\n (_troves[idx].snapshotETH, _troves[idx].snapshotZUSDDebt) = troveManager\n .rewardSnapshots(currentTroveowner);\n\n currentTroveowner = sortedTroves.getPrev(currentTroveowner);\n }\n }\n}\n" + }, + "contracts/MultiTroveGetterStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\nimport \"./TroveManager.sol\";\nimport \"./SortedTroves.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract MultiTroveGetterStorage is Ownable {\n TroveManager public troveManager; // XXX Troves missing from ITroveManager?\n ISortedTroves public sortedTroves;\n}\n" + }, + "contracts/PriceFeed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IPriceFeed.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./PriceFeedStorage.sol\";\n\n/// @title The system price feed adapter\n/// @notice The PriceFeed relies upon a main oracle and a secondary as a fallback in case of error\ncontract PriceFeed is PriceFeedStorage, IPriceFeed {\n event LastGoodPriceUpdated(uint256 _lastGoodPrice);\n event PriceFeedBroken(uint8 index, address priceFeedAddress);\n event PriceFeedUpdated(uint8 index, address newPriceFeedAddress);\n\n // --- Dependency setters ---\n\n function setAddresses(address _mainPriceFeed, address _backupPriceFeed) external onlyOwner {\n uint256 latestPrice = setAddress(0, _mainPriceFeed);\n setAddress(1, _backupPriceFeed);\n\n _storePrice(latestPrice);\n }\n\n // --- Functions ---\n\n /// @notice Returns the latest price obtained from the Oracle. Called by Zero functions that require a current price.\n /// It uses the main price feed and fallback to the backup one in case of an error. If both fail return the last\n /// good price seen.\n /// @dev It's also callable by anyone externally\n /// @return The price\n function fetchPrice() external override returns (uint256) {\n for (uint8 index = 0; index < 2; index++) {\n (uint256 price, bool success) = priceFeeds[index].latestAnswer();\n if (success) {\n _storePrice(price);\n return price;\n } else {\n emit PriceFeedBroken(index, address(priceFeeds[index]));\n }\n }\n return lastGoodPrice;\n }\n\n /// @notice Allows users to setup the main and the backup price feeds\n /// @param _index the oracle to be configured\n /// @param _newPriceFeed address where an IExternalPriceFeed implementation is located\n /// @return price the latest price of the inserted price feed\n function setAddress(uint8 _index, address _newPriceFeed) public onlyOwner returns (uint256) {\n require(_index < priceFeeds.length, \"Out of bounds when setting the price feed\");\n checkContract(_newPriceFeed);\n priceFeeds[_index] = IExternalPriceFeed(_newPriceFeed);\n (uint256 price, bool success) = priceFeeds[_index].latestAnswer();\n require(success, \"PriceFeed: Price feed must be working\");\n emit PriceFeedUpdated(_index, _newPriceFeed);\n return price;\n }\n\n // --- Helper functions ---\n function _storePrice(uint256 _currentPrice) internal {\n lastGoodPrice = _currentPrice;\n emit LastGoodPriceUpdated(_currentPrice);\n }\n}\n" + }, + "contracts/PriceFeedStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IPriceFeed.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/PriceFeed/IExternalPriceFeed.sol\";\nimport \"./Dependencies/CheckContract.sol\";\n\ncontract PriceFeedStorage is Ownable, CheckContract {\n string public constant NAME = \"PriceFeed\";\n\n IExternalPriceFeed[2] priceFeeds;\n\n // The last good price seen from an oracle by Zero\n uint256 public lastGoodPrice;\n}\n" + }, + "contracts/Proxy/BorrowerOperationsScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/IBorrowerOperations.sol\";\n\n\ncontract BorrowerOperationsScript is CheckContract {\n IBorrowerOperations immutable borrowerOperations;\n\n constructor(IBorrowerOperations _borrowerOperations) public {\n checkContract(address(_borrowerOperations));\n borrowerOperations = _borrowerOperations;\n }\n\n function openTrove(uint _maxFee, uint _ZUSDAmount, address _upperHint, address _lowerHint) external payable {\n borrowerOperations.openTrove{ value: msg.value }(_maxFee, _ZUSDAmount, _upperHint, _lowerHint);\n }\n\n function addColl(address _upperHint, address _lowerHint) external payable {\n borrowerOperations.addColl{ value: msg.value }(_upperHint, _lowerHint);\n }\n\n function withdrawColl(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.withdrawColl(_amount, _upperHint, _lowerHint);\n }\n\n function withdrawZUSD(uint _maxFee, uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.withdrawZUSD(_maxFee, _amount, _upperHint, _lowerHint);\n }\n\n function repayZUSD(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.repayZUSD(_amount, _upperHint, _lowerHint);\n }\n\n function closeTrove() external {\n borrowerOperations.closeTrove();\n }\n\n function adjustTrove(uint _maxFee, uint _collWithdrawal, uint _debtChange, bool isDebtIncrease, address _upperHint, address _lowerHint) external payable {\n borrowerOperations.adjustTrove{ value: msg.value }(_maxFee, _collWithdrawal, _debtChange, isDebtIncrease, _upperHint, _lowerHint);\n }\n\n function claimCollateral() external {\n borrowerOperations.claimCollateral();\n }\n}\n" + }, + "contracts/Proxy/BorrowerWrappersScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Interfaces/IBorrowerOperations.sol\";\nimport \"../Interfaces/ITroveManager.sol\";\nimport \"../Interfaces/IStabilityPool.sol\";\nimport \"../Interfaces/IPriceFeed.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\nimport \"./BorrowerOperationsScript.sol\";\nimport \"./ETHTransferScript.sol\";\nimport \"./ZEROStakingScript.sol\";\nimport \"../Dependencies/console.sol\";\n\n\ncontract BorrowerWrappersScript is BorrowerOperationsScript, ETHTransferScript, ZEROStakingScript {\n using SafeMath for uint;\n\n string constant public NAME = \"BorrowerWrappersScript\";\n\n ITroveManager immutable troveManager;\n IStabilityPool immutable stabilityPool;\n IPriceFeed immutable priceFeed;\n IERC20 immutable zusdToken;\n IERC20 immutable zeroToken;\n IZEROStaking immutable zeroStaking;\n\n constructor(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _zeroStakingAddress,\n address _stabilityPoolAddress,\n address _priceFeedAddress,\n address _zusdTokenAddress,\n address _zeroTokenAddress\n )\n BorrowerOperationsScript(IBorrowerOperations(_borrowerOperationsAddress))\n ZEROStakingScript(_zeroStakingAddress)\n public\n {\n checkContract(_troveManagerAddress);\n ITroveManager troveManagerCached = ITroveManager(_troveManagerAddress);\n troveManager = troveManagerCached;\n\n IStabilityPool stabilityPoolCached = IStabilityPool(_stabilityPoolAddress);\n checkContract(_stabilityPoolAddress);\n stabilityPool = stabilityPoolCached;\n\n IPriceFeed priceFeedCached = IPriceFeed(_priceFeedAddress); \n checkContract(_priceFeedAddress);\n priceFeed = priceFeedCached;\n\n checkContract(_zusdTokenAddress);\n zusdToken = IERC20(_zusdTokenAddress);\n\n checkContract(_zeroTokenAddress);\n zeroToken = IERC20(_zeroTokenAddress);\n\n IZEROStaking zeroStakingCached = IZEROStaking(_zeroStakingAddress);\n checkContract(_zeroStakingAddress);\n zeroStaking = zeroStakingCached;\n }\n\n function claimCollateralAndOpenTrove(uint _maxFee, uint _ZUSDAmount, address _upperHint, address _lowerHint) external payable {\n uint balanceBefore = address(this).balance;\n\n // Claim collateral\n borrowerOperations.claimCollateral();\n\n uint balanceAfter = address(this).balance;\n\n // already checked in CollSurplusPool\n assert(balanceAfter > balanceBefore);\n\n uint totalCollateral = balanceAfter.sub(balanceBefore).add(msg.value);\n\n // Open trove with obtained collateral, plus collateral sent by user\n borrowerOperations.openTrove{ value: totalCollateral }(_maxFee, _ZUSDAmount, _upperHint, _lowerHint);\n }\n\n function claimSPRewardsAndRecycle(uint _maxFee, address _upperHint, address _lowerHint) external {\n uint collBalanceBefore = address(this).balance;\n uint zeroBalanceBefore = zeroToken.balanceOf(address(this));\n\n // Claim rewards\n stabilityPool.withdrawFromSP(0);\n\n uint collBalanceAfter = address(this).balance;\n uint zeroBalanceAfter = zeroToken.balanceOf(address(this));\n uint claimedCollateral = collBalanceAfter.sub(collBalanceBefore);\n\n // Add claimed ETH to trove, get more ZUSD and stake it into the Stability Pool\n if (claimedCollateral > 0) {\n _requireUserHasTrove(address(this));\n uint ZUSDAmount = _getNetZUSDAmount(claimedCollateral);\n borrowerOperations.adjustTrove{ value: claimedCollateral }(_maxFee, 0, ZUSDAmount, true, _upperHint, _lowerHint);\n // Provide withdrawn ZUSD to Stability Pool\n if (ZUSDAmount > 0) {\n stabilityPool.provideToSP(ZUSDAmount, address(0));\n }\n }\n\n // Stake claimed ZERO\n uint claimedZERO = zeroBalanceAfter.sub(zeroBalanceBefore);\n if (claimedZERO > 0) {\n zeroStaking.stake(claimedZERO);\n }\n }\n\n function claimStakingGainsAndRecycle(uint _maxFee, address _upperHint, address _lowerHint) external {\n uint collBalanceBefore = address(this).balance;\n uint zusdBalanceBefore = zusdToken.balanceOf(address(this));\n uint zeroBalanceBefore = zeroToken.balanceOf(address(this));\n\n // Claim gains\n zeroStaking.unstake(0);\n\n uint gainedCollateral = address(this).balance.sub(collBalanceBefore); // stack too deep issues :'(\n uint gainedZUSD = zusdToken.balanceOf(address(this)).sub(zusdBalanceBefore);\n\n uint netZUSDAmount;\n // Top up trove and get more ZUSD, keeping ICR constant\n if (gainedCollateral > 0) {\n _requireUserHasTrove(address(this));\n netZUSDAmount = _getNetZUSDAmount(gainedCollateral);\n borrowerOperations.adjustTrove{ value: gainedCollateral }(_maxFee, 0, netZUSDAmount, true, _upperHint, _lowerHint);\n }\n\n uint totalZUSD = gainedZUSD.add(netZUSDAmount);\n if (totalZUSD > 0) {\n stabilityPool.provideToSP(totalZUSD, address(0));\n\n // Providing to Stability Pool also triggers ZERO claim, so stake it if any\n uint zeroBalanceAfter = zeroToken.balanceOf(address(this));\n uint claimedZERO = zeroBalanceAfter.sub(zeroBalanceBefore);\n if (claimedZERO > 0) {\n zeroStaking.stake(claimedZERO);\n }\n }\n\n }\n\n function _getNetZUSDAmount(uint _collateral) internal returns (uint) {\n uint price = priceFeed.fetchPrice();\n uint ICR = troveManager.getCurrentICR(address(this), price);\n\n uint ZUSDAmount = _collateral.mul(price).div(ICR);\n uint borrowingRate = troveManager.getBorrowingRateWithDecay();\n uint netDebt = ZUSDAmount.mul(LiquityMath.DECIMAL_PRECISION).div(LiquityMath.DECIMAL_PRECISION.add(borrowingRate));\n\n return netDebt;\n }\n\n function _requireUserHasTrove(address _depositor) internal view {\n require(troveManager.getTroveStatus(_depositor) == 1, \"BorrowerWrappersScript: caller must have an active trove\");\n }\n}\n" + }, + "contracts/Proxy/ETHTransferScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n\ncontract ETHTransferScript {\n function transferETH(address _recipient, uint256 _amount) external returns (bool) {\n (bool success, ) = _recipient.call{value: _amount}(\"\");\n return success;\n }\n}\n" + }, + "contracts/Proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Dependencies/Ownable.sol\";\n/**\n * @title Base Proxy contract.\n * \n * Adapted version of https://github.com/DistributedCollective/Sovryn-smart-contracts/blob/development/contracts/proxy/Proxy.sol \n *\n * @notice The proxy performs delegated calls to the contract implementation\n * it is pointing to. This way upgradable contracts are possible on blockchain.\n *\n * Delegating proxy contracts are widely used for both upgradeability and gas\n * savings. These proxies rely on a logic contract (also known as implementation\n * contract or master copy) that is called using delegatecall. This allows\n * proxies to keep a persistent state (storage and balance) while the code is\n * delegated to the logic contract.\n *\n * Proxy contract is meant to be inherited and its internal functions\n * _setImplementation and _setOwner to be called when upgrades become\n * neccessary.\n *\n * The loan token (iToken) contract as well as the protocol contract act as\n * proxies, delegating all calls to underlying contracts. Therefore, if you\n * want to interact with them using web3, you need to use the ABIs from the\n * contracts containing the actual logic or the interface contract.\n * ABI for LoanToken contracts: LoanTokenLogicStandard\n * ABI for Protocol contract: ISovryn\n *\n * @dev UpgradableProxy is the contract that inherits Proxy and wraps these\n * functions.\n * */\ncontract Proxy is Ownable {\n bytes32 private constant KEY_IMPLEMENTATION = keccak256(\"key.implementation\");\n\n event ImplementationChanged(\n address indexed _oldImplementation,\n address indexed _newImplementation\n );\n\n /**\n * @notice Set address of the implementation.\n * @param _implementation Address of the implementation.\n * */\n function _setImplementation(address _implementation) internal {\n require(_implementation != address(0), \"Proxy::setImplementation: invalid address\");\n emit ImplementationChanged(getImplementation(), _implementation);\n\n bytes32 key = KEY_IMPLEMENTATION;\n assembly {\n sstore(key, _implementation)\n }\n }\n\n /**\n * @notice Return address of the implementation.\n * @return _implementation Address of the implementation.\n * */\n function getImplementation() public view returns (address _implementation) {\n bytes32 key = KEY_IMPLEMENTATION;\n assembly {\n _implementation := sload(key)\n }\n }\n\n /**\n * @notice Fallback function performs a delegate call\n * to the actual implementation address is pointing this proxy.\n * Returns whatever the implementation call returns.\n * */\n fallback() external payable {\n delegate();\n }\n\n /**\n * @notice Fallback function performs a delegate call\n * to the actual implementation address is pointing this proxy.\n * Returns whatever the implementation call returns.\n * */\n receive() external payable {\n delegate();\n }\n\n function delegate() internal {\n address implementation = getImplementation();\n require(implementation != address(0), \"Proxy::(): implementation not found\");\n\n assembly {\n let pointer := mload(0x40)\n calldatacopy(pointer, 0, calldatasize())\n let result := delegatecall(gas(), implementation, pointer, calldatasize(), 0, 0)\n let size := returndatasize()\n returndatacopy(pointer, 0, size)\n\n switch result\n case 0 {\n revert(pointer, size)\n }\n default {\n return(pointer, size)\n }\n }\n }\n}\n" + }, + "contracts/Proxy/StabilityPoolScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/IStabilityPool.sol\";\n\n\ncontract StabilityPoolScript is CheckContract {\n string constant public NAME = \"StabilityPoolScript\";\n\n IStabilityPool immutable stabilityPool;\n\n constructor(IStabilityPool _stabilityPool) public {\n checkContract(address(_stabilityPool));\n stabilityPool = _stabilityPool;\n }\n\n function provideToSP(uint _amount, address _frontEndTag) external {\n stabilityPool.provideToSP(_amount, _frontEndTag);\n }\n\n function withdrawFromSP(uint _amount) external {\n stabilityPool.withdrawFromSP(_amount);\n }\n\n function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external {\n stabilityPool.withdrawETHGainToTrove(_upperHint, _lowerHint);\n }\n}\n" + }, + "contracts/Proxy/TokenScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/IERC20.sol\";\n\n\ncontract TokenScript is CheckContract {\n string constant public NAME = \"TokenScript\";\n\n IERC20 immutable token;\n\n constructor(address _tokenAddress) public {\n checkContract(_tokenAddress);\n token = IERC20(_tokenAddress);\n }\n\n function transfer(address recipient, uint256 amount) external returns (bool) {\n token.transfer(recipient, amount);\n }\n\n function allowance(address owner, address spender) external view returns (uint256) {\n token.allowance(owner, spender);\n }\n\n function approve(address spender, uint256 amount) external returns (bool) {\n token.approve(spender, amount);\n }\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {\n token.transferFrom(sender, recipient, amount);\n }\n\n function increaseAllowance(address spender, uint256 addedValue) external returns (bool) {\n token.increaseAllowance(spender, addedValue);\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool) {\n token.decreaseAllowance(spender, subtractedValue);\n }\n}\n" + }, + "contracts/Proxy/TroveManagerScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/ITroveManager.sol\";\n\n\ncontract TroveManagerScript is CheckContract {\n string constant public NAME = \"TroveManagerScript\";\n\n ITroveManager immutable troveManager;\n\n constructor(ITroveManager _troveManager) public {\n checkContract(address(_troveManager));\n troveManager = _troveManager;\n }\n\n function redeemCollateral(\n uint _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint _partialRedemptionHintNICR,\n uint _maxIterations,\n uint _maxFee\n ) external returns (uint) {\n troveManager.redeemCollateral(\n _ZUSDAmount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n _maxIterations,\n _maxFee\n );\n }\n}\n" + }, + "contracts/Proxy/UpgradableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Proxy.sol\";\n\n/**\n * @title Upgradable Proxy contract.\n *\n * Adapted version of https://github.com/DistributedCollective/Sovryn-smart-contracts/blob/development/contracts/proxy/UpgradableProxy.sol\n * \n * @notice A disadvantage of the immutable ledger is that nobody can change the\n * source code of a smart contract after it’s been deployed. In order to fix\n * bugs or introduce new features, smart contracts need to be upgradable somehow.\n *\n * Although it is not possible to upgrade the code of an already deployed smart\n * contract, it is possible to set-up a proxy contract architecture that will\n * allow to use new deployed contracts as if the main logic had been upgraded.\n *\n * A proxy architecture pattern is such that all message calls go through a\n * Proxy contract that will redirect them to the latest deployed contract logic.\n * To upgrade, a new version of the contract is deployed, and the Proxy is\n * updated to reference the new contract address.\n * */\ncontract UpgradableProxy is Proxy {\n /**\n * @notice Set address of the implementation.\n * @dev Wrapper for _setImplementation that exposes the function\n * as public for owner to be able to set a new version of the\n * contract as current pointing implementation.\n * @param _implementation Address of the implementation.\n * */\n function setImplementation(address _implementation) public onlyOwner {\n _setImplementation(_implementation);\n }\n\n}\n" + }, + "contracts/Proxy/ZEROStakingScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\n\n\ncontract ZEROStakingScript is CheckContract {\n IZEROStaking immutable ZEROStaking;\n\n constructor(address _zeroStakingAddress) public {\n checkContract(_zeroStakingAddress);\n ZEROStaking = IZEROStaking(_zeroStakingAddress);\n }\n\n function stake(uint _ZEROamount) external {\n ZEROStaking.stake(_ZEROamount);\n }\n}\n" + }, + "contracts/SortedTroves.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./SortedTrovesStorage.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\n\n/**\n * A sorted doubly linked list with nodes sorted in descending order.\n *\n * Nodes map to active Troves in the system - the ID property is the address of a Trove owner.\n * Nodes are ordered according to their current nominal individual collateral ratio (NICR),\n * which is like the ICR but without the price, i.e., just collateral / debt.\n *\n * The list optionally accepts insert position hints.\n *\n * NICRs are computed dynamically at runtime, and not stored on the Node. This is because NICRs of active Troves\n * change dynamically as liquidation events occur.\n *\n * The list relies on the fact that liquidation events preserve ordering: a liquidation decreases the NICRs of all active Troves,\n * but maintains their order. A node inserted based on current NICR will maintain the correct position,\n * relative to it's peers, as rewards accumulate, as long as it's raw collateral and debt have not changed.\n * Thus, Nodes remain sorted by current NICR.\n *\n * Nodes need only be re-inserted upon a Trove operation - when the owner adds or removes collateral or debt\n * to their position.\n *\n * The list is a modification of the following audited SortedDoublyLinkedList:\n * https://github.com/livepeer/protocol/blob/master/contracts/libraries/SortedDoublyLL.sol\n *\n *\n * Changes made in the Zero implementation:\n *\n * - Keys have been removed from nodes\n *\n * - Ordering checks for insertion are performed by comparing an NICR argument to the current NICR, calculated at runtime.\n * The list relies on the property that ordering by ICR is maintained as the ETH:USD price varies.\n *\n * - Public functions with parameters have been made internal to save gas, and given an external wrapper function for external access\n */\ncontract SortedTroves is SortedTrovesStorage, CheckContract, ISortedTroves {\n using SafeMath for uint256;\n\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event NodeAdded(address _id, uint256 _NICR);\n event NodeRemoved(address _id);\n\n // --- Dependency setters ---\n\n function setParams(\n uint256 _size,\n address _troveManagerAddress,\n address _borrowerOperationsAddress\n ) external override onlyOwner {\n require(_size > 0, \"SortedTroves: Size can’t be zero\");\n checkContract(_troveManagerAddress);\n checkContract(_borrowerOperationsAddress);\n\n data.maxSize = _size;\n\n troveManager = ITroveManager(_troveManagerAddress);\n borrowerOperationsAddress = _borrowerOperationsAddress;\n\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n }\n\n /**\n * @dev Add a node to the list\n * @param _id Node's id\n * @param _NICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n\n function insert(\n address _id,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external override {\n ITroveManager troveManagerCached = troveManager;\n\n _requireCallerIsBOorTroveM(troveManagerCached);\n _insert(troveManagerCached, _id, _NICR, _prevId, _nextId);\n }\n\n function _insert(\n ITroveManager _troveManager,\n address _id,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) internal {\n // List must not be full\n require(!isFull(), \"SortedTroves: List is full\");\n // List must not already contain node\n require(!contains(_id), \"SortedTroves: List already contains the node\");\n // Node id must not be null\n require(_id != address(0), \"SortedTroves: Id cannot be zero\");\n // NICR must be non-zero\n require(_NICR > 0, \"SortedTroves: NICR must be positive\");\n\n address prevId = _prevId;\n address nextId = _nextId;\n\n if (!_validInsertPosition(_troveManager, _NICR, prevId, nextId)) {\n // Sender's hint was not a valid insert position\n // Use sender's hint to find a valid insert position\n (prevId, nextId) = _findInsertPosition(_troveManager, _NICR, prevId, nextId);\n }\n\n data.nodes[_id].exists = true;\n\n if (prevId == address(0) && nextId == address(0)) {\n // Insert as head and tail\n data.head = _id;\n data.tail = _id;\n } else if (prevId == address(0)) {\n // Insert before `prevId` as the head\n data.nodes[_id].nextId = data.head;\n data.nodes[data.head].prevId = _id;\n data.head = _id;\n } else if (nextId == address(0)) {\n // Insert after `nextId` as the tail\n data.nodes[_id].prevId = data.tail;\n data.nodes[data.tail].nextId = _id;\n data.tail = _id;\n } else {\n // Insert at insert position between `prevId` and `nextId`\n data.nodes[_id].nextId = nextId;\n data.nodes[_id].prevId = prevId;\n data.nodes[prevId].nextId = _id;\n data.nodes[nextId].prevId = _id;\n }\n\n data.size = data.size.add(1);\n emit NodeAdded(_id, _NICR);\n }\n\n function remove(address _id) external override {\n _requireCallerIsTroveManager();\n _remove(_id);\n }\n\n /**\n * @dev Remove a node from the list\n * @param _id Node's id\n */\n function _remove(address _id) internal {\n // List must contain the node\n require(contains(_id), \"SortedTroves: List does not contain the id\");\n\n if (data.size > 1) {\n // List contains more than a single node\n if (_id == data.head) {\n // The removed node is the head\n // Set head to next node\n data.head = data.nodes[_id].nextId;\n // Set prev pointer of new head to null\n data.nodes[data.head].prevId = address(0);\n } else if (_id == data.tail) {\n // The removed node is the tail\n // Set tail to previous node\n data.tail = data.nodes[_id].prevId;\n // Set next pointer of new tail to null\n data.nodes[data.tail].nextId = address(0);\n } else {\n // The removed node is neither the head nor the tail\n // Set next pointer of previous node to the next node\n data.nodes[data.nodes[_id].prevId].nextId = data.nodes[_id].nextId;\n // Set prev pointer of next node to the previous node\n data.nodes[data.nodes[_id].nextId].prevId = data.nodes[_id].prevId;\n }\n } else {\n // List contains a single node\n // Set the head and tail to null\n data.head = address(0);\n data.tail = address(0);\n }\n\n delete data.nodes[_id];\n data.size = data.size.sub(1);\n NodeRemoved(_id);\n }\n\n /**\n * @dev Re-insert the node at a new position, based on its new NICR\n * @param _id Node's id\n * @param _newNICR Node's new NICR\n * @param _prevId Id of previous node for the new insert position\n * @param _nextId Id of next node for the new insert position\n */\n function reInsert(\n address _id,\n uint256 _newNICR,\n address _prevId,\n address _nextId\n ) external override {\n ITroveManager troveManagerCached = troveManager;\n\n _requireCallerIsBOorTroveM(troveManagerCached);\n // List must contain the node\n require(contains(_id), \"SortedTroves: List does not contain the id\");\n // NICR must be non-zero\n require(_newNICR > 0, \"SortedTroves: NICR must be positive\");\n\n // Remove node from the list\n _remove(_id);\n\n _insert(troveManagerCached, _id, _newNICR, _prevId, _nextId);\n }\n\n /**\n * @dev Checks if the list contains a node\n */\n function contains(address _id) public view override returns (bool) {\n return data.nodes[_id].exists;\n }\n\n /**\n * @dev Checks if the list is full\n */\n function isFull() public view override returns (bool) {\n return data.size == data.maxSize;\n }\n\n /**\n * @dev Checks if the list is empty\n */\n function isEmpty() public view override returns (bool) {\n return data.size == 0;\n }\n\n /**\n * @dev Returns the current size of the list\n */\n function getSize() external view override returns (uint256) {\n return data.size;\n }\n\n /**\n * @dev Returns the maximum size of the list\n */\n function getMaxSize() external view override returns (uint256) {\n return data.maxSize;\n }\n\n /**\n * @dev Returns the first node in the list (node with the largest NICR)\n */\n function getFirst() external view override returns (address) {\n return data.head;\n }\n\n /**\n * @dev Returns the last node in the list (node with the smallest NICR)\n */\n function getLast() external view override returns (address) {\n return data.tail;\n }\n\n /**\n * @dev Returns the next node (with a smaller NICR) in the list for a given node\n * @param _id Node's id\n */\n function getNext(address _id) external view override returns (address) {\n return data.nodes[_id].nextId;\n }\n\n /**\n * @dev Returns the previous node (with a larger NICR) in the list for a given node\n * @param _id Node's id\n */\n function getPrev(address _id) external view override returns (address) {\n return data.nodes[_id].prevId;\n }\n\n /**\n * @dev Check if a pair of nodes is a valid insertion point for a new node with the given NICR\n * @param _NICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function validInsertPosition(\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external view override returns (bool) {\n return _validInsertPosition(troveManager, _NICR, _prevId, _nextId);\n }\n\n function _validInsertPosition(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) internal view returns (bool) {\n if (_prevId == address(0) && _nextId == address(0)) {\n // `(null, null)` is a valid insert position if the list is empty\n return isEmpty();\n } else if (_prevId == address(0)) {\n // `(null, _nextId)` is a valid insert position if `_nextId` is the head of the list\n return data.head == _nextId && _NICR >= _troveManager.getNominalICR(_nextId);\n } else if (_nextId == address(0)) {\n // `(_prevId, null)` is a valid insert position if `_prevId` is the tail of the list\n return data.tail == _prevId && _NICR <= _troveManager.getNominalICR(_prevId);\n } else {\n // `(_prevId, _nextId)` is a valid insert position if they are adjacent nodes and `_NICR` falls between the two nodes' NICRs\n return\n data.nodes[_prevId].nextId == _nextId &&\n _troveManager.getNominalICR(_prevId) >= _NICR &&\n _NICR >= _troveManager.getNominalICR(_nextId);\n }\n }\n\n /**\n * @dev Descend the list (larger NICRs to smaller NICRs) to find a valid insert position\n * @param _troveManager TroveManager contract, passed in as param to save SLOAD’s\n * @param _NICR Node's NICR\n * @param _startId Id of node to start descending the list from\n */\n function _descendList(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _startId\n ) internal view returns (address, address) {\n // If `_startId` is the head, check if the insert position is before the head\n if (data.head == _startId && _NICR >= _troveManager.getNominalICR(_startId)) {\n return (address(0), _startId);\n }\n\n address prevId = _startId;\n address nextId = data.nodes[prevId].nextId;\n\n // Descend the list until we reach the end or until we find a valid insert position\n while (\n prevId != address(0) && !_validInsertPosition(_troveManager, _NICR, prevId, nextId)\n ) {\n prevId = data.nodes[prevId].nextId;\n nextId = data.nodes[prevId].nextId;\n }\n\n return (prevId, nextId);\n }\n\n /**\n * @dev Ascend the list (smaller NICRs to larger NICRs) to find a valid insert position\n * @param _troveManager TroveManager contract, passed in as param to save SLOAD’s\n * @param _NICR Node's NICR\n * @param _startId Id of node to start ascending the list from\n */\n function _ascendList(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _startId\n ) internal view returns (address, address) {\n // If `_startId` is the tail, check if the insert position is after the tail\n if (data.tail == _startId && _NICR <= _troveManager.getNominalICR(_startId)) {\n return (_startId, address(0));\n }\n\n address nextId = _startId;\n address prevId = data.nodes[nextId].prevId;\n\n // Ascend the list until we reach the end or until we find a valid insertion point\n while (\n nextId != address(0) && !_validInsertPosition(_troveManager, _NICR, prevId, nextId)\n ) {\n nextId = data.nodes[nextId].prevId;\n prevId = data.nodes[nextId].prevId;\n }\n\n return (prevId, nextId);\n }\n\n /**\n * @dev Find the insert position for a new node with the given NICR\n * @param _NICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function findInsertPosition(\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external view override returns (address, address) {\n return _findInsertPosition(troveManager, _NICR, _prevId, _nextId);\n }\n\n function _findInsertPosition(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) internal view returns (address, address) {\n address prevId = _prevId;\n address nextId = _nextId;\n\n if (prevId != address(0)) {\n if (!contains(prevId) || _NICR > _troveManager.getNominalICR(prevId)) {\n // `prevId` does not exist anymore or now has a smaller NICR than the given NICR\n prevId = address(0);\n }\n }\n\n if (nextId != address(0)) {\n if (!contains(nextId) || _NICR < _troveManager.getNominalICR(nextId)) {\n // `nextId` does not exist anymore or now has a larger NICR than the given NICR\n nextId = address(0);\n }\n }\n\n if (prevId == address(0) && nextId == address(0)) {\n // No hint - descend list starting from head\n return _descendList(_troveManager, _NICR, data.head);\n } else if (prevId == address(0)) {\n // No `prevId` for hint - ascend list starting from `nextId`\n return _ascendList(_troveManager, _NICR, nextId);\n } else if (nextId == address(0)) {\n // No `nextId` for hint - descend list starting from `prevId`\n return _descendList(_troveManager, _NICR, prevId);\n } else {\n // Descend list starting from `prevId`\n return _descendList(_troveManager, _NICR, prevId);\n }\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsTroveManager() internal view {\n require(\n msg.sender == address(troveManager),\n \"SortedTroves: Caller is not the TroveManager\"\n );\n }\n\n function _requireCallerIsBOorTroveM(ITroveManager _troveManager) internal view {\n require(\n msg.sender == borrowerOperationsAddress || msg.sender == address(_troveManager),\n \"SortedTroves: Caller is neither BO nor TroveM\"\n );\n }\n}\n" + }, + "contracts/SortedTrovesStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\n\ncontract SortedTrovesStorage is Ownable {\n string public constant NAME = \"SortedTroves\";\n\n address public borrowerOperationsAddress;\n\n ITroveManager public troveManager;\n\n // Information for a node in the list\n struct Node {\n bool exists;\n address nextId; // Id of next node (smaller NICR) in the list\n address prevId; // Id of previous node (larger NICR) in the list\n }\n\n // Information for the list\n struct Data {\n address head; // Head of the list. Also the node in the list with the largest NICR\n address tail; // Tail of the list. Also the node in the list with the smallest NICR\n uint256 maxSize; // Maximum size of the list\n uint256 size; // Current size of the list\n mapping(address => Node) nodes; // Track the corresponding ids for each node in the list\n }\n\n Data public data;\n}\n" + }, + "contracts/StabilityPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ICommunityIssuance.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/LiquitySafeMath128.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/Mynt/MyntLib.sol\";\nimport \"./StabilityPoolStorage.sol\";\n\n/**\n * The Stability Pool holds ZUSD tokens deposited by Stability Pool depositors.\n *\n * When a trove is liquidated, then depending on system conditions, some of its ZUSD debt gets offset with\n * ZUSD in the Stability Pool: that is, the offset debt evaporates, and an equal amount of ZUSD tokens in the Stability Pool is burned.\n *\n * Thus, a liquidation causes each depositor to receive a ZUSD loss, in proportion to their deposit as a share of total deposits.\n * They also receive an ETH gain, as the ETH collateral of the liquidated trove is distributed among Stability depositors,\n * in the same proportion.\n *\n * When a liquidation occurs, it depletes every deposit by the same fraction: for example, a liquidation that depletes 40%\n * of the total ZUSD in the Stability Pool, depletes 40% of each deposit.\n *\n * A deposit that has experienced a series of liquidations is termed a \"compounded deposit\": each liquidation depletes the deposit,\n * multiplying it by some factor in range ]0,1[\n *\n *\n * --- IMPLEMENTATION ---\n *\n * We use a highly scalable method of tracking deposits and ETH gains that has O(1) complexity.\n *\n * When a liquidation occurs, rather than updating each depositor's deposit and ETH gain, we simply update two state variables:\n * a product P, and a sum S.\n *\n * A mathematical manipulation allows us to factor out the initial deposit, and accurately track all depositors' compounded deposits\n * and accumulated ETH gains over time, as liquidations occur, using just these two variables P and S. When depositors join the\n * Stability Pool, they get a snapshot of the latest P and S: P_t and S_t, respectively.\n *\n * The formula for a depositor's accumulated ETH gain is derived here:\n * https://github.com/liquity/dev/blob/main/packages/contracts/mathProofs/Scalable%20Compounding%20Stability%20Pool%20Deposits.pdf\n *\n * For a given deposit d_t, the ratio P/P_t tells us the factor by which a deposit has decreased since it joined the Stability Pool,\n * and the term d_t * (S - S_t)/P_t gives us the deposit's total accumulated ETH gain.\n *\n * Each liquidation updates the product P and sum S. After a series of liquidations, a compounded deposit and corresponding ETH gain\n * can be calculated using the initial deposit, the depositor’s snapshots of P and S, and the latest values of P and S.\n *\n * Any time a depositor updates their deposit (withdrawal, top-up) their accumulated ETH gain is paid out, their new deposit is recorded\n * (based on their latest compounded deposit and modified by the withdrawal/top-up), and they receive new snapshots of the latest P and S.\n * Essentially, they make a fresh deposit that overwrites the old one.\n *\n *\n * --- SCALE FACTOR ---\n *\n * Since P is a running product in range ]0,1] that is always-decreasing, it should never reach 0 when multiplied by a number in range ]0,1[.\n * Unfortunately, Solidity floor division always reaches 0, sooner or later.\n *\n * A series of liquidations that nearly empty the Pool (and thus each multiply P by a very small number in range ]0,1[ ) may push P\n * to its 18 digit decimal limit, and round it to 0, when in fact the Pool hasn't been emptied: this would break deposit tracking.\n *\n * So, to track P accurately, we use a scale factor: if a liquidation would cause P to decrease to <1e-9 (and be rounded to 0 by Solidity),\n * we first multiply P by 1e9, and increment a currentScale factor by 1.\n *\n * The added benefit of using 1e9 for the scale factor (rather than 1e18) is that it ensures negligible precision loss close to the\n * scale boundary: when P is at its minimum value of 1e9, the relative precision loss in P due to floor division is only on the\n * order of 1e-9.\n *\n * --- EPOCHS ---\n *\n * Whenever a liquidation fully empties the Stability Pool, all deposits should become 0. However, setting P to 0 would make P be 0\n * forever, and break all future reward calculations.\n *\n * So, every time the Stability Pool is emptied by a liquidation, we reset P = 1 and currentScale = 0, and increment the currentEpoch by 1.\n *\n * --- TRACKING DEPOSIT OVER SCALE CHANGES AND EPOCHS ---\n *\n * When a deposit is made, it gets snapshots of the currentEpoch and the currentScale.\n *\n * When calculating a compounded deposit, we compare the current epoch to the deposit's epoch snapshot. If the current epoch is newer,\n * then the deposit was present during a pool-emptying liquidation, and necessarily has been depleted to 0.\n *\n * Otherwise, we then compare the current scale to the deposit's scale snapshot. If they're equal, the compounded deposit is given by d_t * P/P_t.\n * If it spans one scale change, it is given by d_t * P/(P_t * 1e9). If it spans more than one scale change, we define the compounded deposit\n * as 0, since it is now less than 1e-9'th of its initial value (e.g. a deposit of 1 billion ZUSD has depleted to < 1 ZUSD).\n *\n *\n * --- TRACKING DEPOSITOR'S ETH GAIN OVER SCALE CHANGES AND EPOCHS ---\n *\n * In the current epoch, the latest value of S is stored upon each scale change, and the mapping (scale -> S) is stored for each epoch.\n *\n * This allows us to calculate a deposit's accumulated ETH gain, during the epoch in which the deposit was non-sov and earned ETH.\n *\n * We calculate the depositor's accumulated ETH gain for the scale at which they made the deposit, using the ETH gain formula:\n * e_1 = d_t * (S - S_t) / P_t\n *\n * and also for scale after, taking care to divide the latter by a factor of 1e9:\n * e_2 = d_t * S / (P_t * 1e9)\n *\n * The gain in the second scale will be full, as the starting point was in the previous scale, thus no need to subtract anything.\n * The deposit therefore was present for reward events from the beginning of that second scale.\n *\n * S_i-S_t + S_{i+1}\n * .<--------.------------>\n * . .\n * . S_i . S_{i+1}\n * <--.-------->.<----------->\n * S_t. .\n * <->. .\n * t .\n * |---+---------|-------------|-----...\n * i i+1\n *\n * The sum of (e_1 + e_2) captures the depositor's total accumulated ETH gain, handling the case where their\n * deposit spanned one scale change. We only care about gains across one scale change, since the compounded\n * deposit is defined as being 0 once it has spanned more than one scale change.\n *\n *\n * --- UPDATING P WHEN A LIQUIDATION OCCURS ---\n *\n * Please see the implementation spec in the proof document, which closely follows on from the compounded deposit / ETH gain derivations:\n * https://github.com/liquity/liquity/blob/master/papers/Scalable_Reward_Distribution_with_Compounding_Stakes.pdf\n *\n *\n * --- SOV ISSUANCE TO STABILITY POOL DEPOSITORS ---\n *\n * An SOV issuance event occurs at every deposit operation, and every liquidation.\n *\n * Each deposit is tagged with the address of the front end through which it was made.\n *\n * All deposits earn a share of the issued SOV in proportion to the deposit as a share of total deposits. The SOV earned\n * by a given deposit, is split between the depositor and the front end through which the deposit was made, based on the front end's kickbackRate.\n *\n * Please see the system Readme for an overview:\n * https://github.com/liquity/dev/blob/main/README.md#zero-issuance-to-stability-providers\n *\n * We use the same mathematical product-sum approach to track SOV gains for depositors, where 'G' is the sum corresponding to SOV gains.\n * The product P (and snapshot P_t) is re-used, as the ratio P/P_t tracks a deposit's depletion due to liquidations.\n *\n */\ncontract StabilityPool is LiquityBase, StabilityPoolStorage, CheckContract, IStabilityPool {\n using LiquitySafeMath128 for uint128;\n address private constant ADDRESS_ZERO = address(0);\n\n // --- Events ---\n\n event StabilityPoolETHBalanceUpdated(uint256 _newBalance);\n event StabilityPoolZUSDBalanceUpdated(uint256 _newBalance);\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n event DefaultPoolAddressChanged(address _newDefaultPoolAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event SortedTrovesAddressChanged(address _newSortedTrovesAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event CommunityIssuanceAddressChanged(address _newCommunityIssuanceAddress);\n\n event P_Updated(uint256 _P);\n event S_Updated(uint256 _S, uint128 _epoch, uint128 _scale);\n event G_Updated(uint256 _G, uint128 _epoch, uint128 _scale);\n event EpochUpdated(uint128 _currentEpoch);\n event ScaleUpdated(uint128 _currentScale);\n\n event FrontEndRegistered(address indexed _frontEnd, uint256 _kickbackRate);\n event FrontEndTagSet(address indexed _depositor, address indexed _frontEnd);\n\n event DepositSnapshotUpdated(address indexed _depositor, uint256 _P, uint256 _S, uint256 _G);\n event FrontEndSnapshotUpdated(address indexed _frontEnd, uint256 _P, uint256 _G);\n event UserDepositChanged(address indexed _depositor, uint256 _newDeposit);\n event FrontEndStakeChanged(\n address indexed _frontEnd,\n uint256 _newFrontEndStake,\n address _depositor\n );\n\n event ETHGainWithdrawn(address indexed _depositor, uint256 _ETH, uint256 _ZUSDLoss);\n event SOVPaidToDepositor(address indexed _depositor, uint256 _SOV);\n event SOVPaidToFrontEnd(address indexed _frontEnd, uint256 _SOV);\n event EtherSent(address _to, uint256 _amount);\n\n // --- Contract setters ---\n\n function setAddresses(\n address _liquityBaseParamsAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _zusdTokenAddress,\n address _sortedTrovesAddress,\n address _priceFeedAddress,\n address _communityIssuanceAddress\n ) external override onlyOwner {\n checkContract(_liquityBaseParamsAddress);\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_sortedTrovesAddress);\n checkContract(_priceFeedAddress);\n checkContract(_communityIssuanceAddress);\n\n P = DECIMAL_PRECISION;\n\n liquityBaseParams = ILiquityBaseParams(_liquityBaseParamsAddress);\n borrowerOperations = IBorrowerOperations(_borrowerOperationsAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n activePool = IActivePool(_activePoolAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n priceFeed = IPriceFeed(_priceFeedAddress);\n communityIssuance = ICommunityIssuance(_communityIssuanceAddress);\n\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n emit ZUSDTokenAddressChanged(_zusdTokenAddress);\n emit SortedTrovesAddressChanged(_sortedTrovesAddress);\n emit PriceFeedAddressChanged(_priceFeedAddress);\n emit CommunityIssuanceAddressChanged(_communityIssuanceAddress);\n }\n\n /**\n * @dev setter function specific for community issuance contract.\n * @param _communityIssuanceAddress address of new community issuance contract.\n */\n function setCommunityIssuanceAddress(address _communityIssuanceAddress) external onlyOwner {\n checkContract(_communityIssuanceAddress);\n communityIssuance = ICommunityIssuance(_communityIssuanceAddress);\n emit CommunityIssuanceAddressChanged(_communityIssuanceAddress);\n }\n\n // --- Getters for public variables. Required by IPool interface ---\n\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n function getTotalZUSDDeposits() external view override returns (uint256) {\n return totalZUSDDeposits;\n }\n\n // --- External Depositor Functions ---\n\n /** provideToSP():\n *\n * - Triggers a SOV issuance, based on time passed since the last issuance and total amount of ZUSD is deposited. The SOV issuance is shared between *all* depositors and front ends\n * - Tags the deposit with the provided front end tag param, if it's a new deposit\n * - Sends depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Increases deposit and tagged front end's stake, and takes new snapshots for each.\n */\n function provideToSP(uint256 _amount, address _frontEndTag) external override {\n _provideToSP(_amount, _frontEndTag);\n }\n\n function _provideToSP(uint256 _amount, address _frontEndTag) internal {\n _requireFrontEndIsRegisteredOrZero(_frontEndTag);\n _requireFrontEndNotRegistered(msg.sender);\n _requireNonZeroAmount(_amount);\n\n uint256 initialDeposit = deposits[msg.sender].initialValue;\n\n ICommunityIssuance communityIssuanceCached = communityIssuance;\n\n _triggerSOVIssuance(communityIssuanceCached);\n\n if (initialDeposit == 0) {\n _setFrontEndTag(msg.sender, _frontEndTag);\n }\n uint256 depositorETHGain = getDepositorETHGain(msg.sender);\n uint256 compoundedZUSDDeposit = getCompoundedZUSDDeposit(msg.sender);\n uint256 ZUSDLoss = initialDeposit.sub(compoundedZUSDDeposit); // Needed only for event log\n\n // First pay out any SOV gains\n address frontEnd = deposits[msg.sender].frontEndTag;\n _payOutSOVGains(communityIssuanceCached, msg.sender, frontEnd);\n\n // Update front end stake\n uint256 compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd);\n uint256 newFrontEndStake = compoundedFrontEndStake.add(_amount);\n _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake);\n emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender);\n\n _sendZUSDtoStabilityPool(msg.sender, _amount);\n\n uint256 newDeposit = compoundedZUSDDeposit.add(_amount);\n _updateDepositAndSnapshots(msg.sender, newDeposit);\n emit UserDepositChanged(msg.sender, newDeposit);\n\n emit ETHGainWithdrawn(msg.sender, depositorETHGain, ZUSDLoss); // ZUSD Loss required for event log\n\n _sendETHGainToDepositor(depositorETHGain);\n }\n\n ///DLLR _owner or _spender can convert a specified amount of DLLR into ZUSD via Sovryn Mynt and deposit the ZUSD into the SOV Stability Pool, all in a single transaction\n function provideToSpFromDLLR(\n uint256 _dllrAmount,\n IMassetManager.PermitParams calldata _permitParams\n ) external override {\n uint256 _ZUSDAmount = MyntLib.redeemZusdFromDllrWithPermit(\n borrowerOperations.getMassetManager(),\n _dllrAmount,\n address(zusdToken),\n _permitParams\n );\n\n _provideToSP(_ZUSDAmount, ADDRESS_ZERO);\n }\n\n /** withdrawFromSP():\n *\n * - Triggers a SOV issuance, based on time passed since the last issuance and total amount of ZUSD is deposited. The SOV issuance is shared between *all* depositors and front ends\n * - Removes the deposit's front end tag if it is a full withdrawal\n * - Sends all depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Decreases deposit and tagged front end's stake, and takes new snapshots for each.\n *\n * If _amount > userDeposit, the user withdraws all of their compounded deposit.\n */\n function withdrawFromSP(uint256 _amount) external override {\n _withdrawFromSpTo(_amount, msg.sender);\n }\n\n ///@return actual ZUSD amount withdrawn\n function _withdrawFromSpTo(uint256 _amount, address _receiver) internal returns (uint256) {\n require(_receiver != address(0), \"SP::_withdrawFromSpTo: _receiver is zero address\");\n if (_amount != 0) {\n _requireNoUnderCollateralizedTroves();\n }\n uint256 initialDeposit = deposits[msg.sender].initialValue;\n _requireUserHasDeposit(initialDeposit);\n\n ICommunityIssuance communityIssuanceCached = communityIssuance;\n\n _triggerSOVIssuance(communityIssuanceCached);\n\n uint256 depositorETHGain = getDepositorETHGain(msg.sender);\n\n uint256 compoundedZUSDDeposit = getCompoundedZUSDDeposit(msg.sender);\n uint256 ZUSDtoWithdraw = LiquityMath._min(_amount, compoundedZUSDDeposit);\n uint256 ZUSDLoss = initialDeposit.sub(compoundedZUSDDeposit); // Needed only for event log\n\n // First pay out any SOV gains\n address frontEnd = deposits[msg.sender].frontEndTag;\n _payOutSOVGains(communityIssuanceCached, msg.sender, frontEnd);\n\n // Update front end stake\n uint256 compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd);\n uint256 newFrontEndStake = compoundedFrontEndStake.sub(ZUSDtoWithdraw);\n _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake);\n emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender);\n\n _sendZUSDToDepositor(_receiver, ZUSDtoWithdraw);\n\n // Update deposit\n uint256 newDeposit = compoundedZUSDDeposit.sub(ZUSDtoWithdraw);\n _updateDepositAndSnapshots(msg.sender, newDeposit);\n emit UserDepositChanged(msg.sender, newDeposit);\n\n emit ETHGainWithdrawn(msg.sender, depositorETHGain, ZUSDLoss); // ZUSD Loss required for event log\n\n _sendETHGainTo(depositorETHGain, msg.sender);\n\n return ZUSDtoWithdraw;\n }\n\n ///Stability Pool depositor can withdraw a specified amount of ZUSD from the SOV Stability Pool and convert the ZUSD to DLLR via Sovryn Mynt, all in a single transaction\n function withdrawFromSpAndConvertToDLLR(uint256 _zusdAmountRequested) external override {\n IMassetManager massetManager = borrowerOperations.getMassetManager();\n uint256 amountWithdrawn = _withdrawFromSpTo(_zusdAmountRequested, address(this));\n require(\n zusdToken.approve(address(massetManager), amountWithdrawn),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n massetManager.mintTo(address(zusdToken), amountWithdrawn, msg.sender);\n emit WithdrawFromSpAndConvertToDLLR(msg.sender, _zusdAmountRequested, amountWithdrawn);\n }\n\n /** withdrawETHGainToTrove:\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Sends all depositor's SOV gain to depositor\n * - Sends all tagged front end's SOV gain to the tagged front end\n * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove\n * - Leaves their compounded deposit in the Stability Pool\n * - Updates snapshots for deposit and tagged front end stake */\n function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external override {\n uint256 initialDeposit = deposits[msg.sender].initialValue;\n _requireUserHasDeposit(initialDeposit);\n _requireUserHasTrove(msg.sender);\n _requireUserHasETHGain(msg.sender);\n\n ICommunityIssuance communityIssuanceCached = communityIssuance;\n\n _triggerSOVIssuance(communityIssuanceCached);\n\n uint256 depositorETHGain = getDepositorETHGain(msg.sender);\n\n uint256 compoundedZUSDDeposit = getCompoundedZUSDDeposit(msg.sender);\n uint256 ZUSDLoss = initialDeposit.sub(compoundedZUSDDeposit); // Needed only for event log\n\n // First pay out any SOV gains\n address frontEnd = deposits[msg.sender].frontEndTag;\n _payOutSOVGains(communityIssuanceCached, msg.sender, frontEnd);\n\n // Update front end stake\n uint256 compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd);\n uint256 newFrontEndStake = compoundedFrontEndStake;\n _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake);\n emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender);\n\n _updateDepositAndSnapshots(msg.sender, compoundedZUSDDeposit);\n\n /* Emit events before transferring ETH gain to Trove.\n This lets the event log make more sense (i.e. so it appears that first the ETH gain is withdrawn\n and then it is deposited into the Trove, not the other way around). */\n emit ETHGainWithdrawn(msg.sender, depositorETHGain, ZUSDLoss);\n emit UserDepositChanged(msg.sender, compoundedZUSDDeposit);\n\n ETH = ETH.sub(depositorETHGain);\n emit StabilityPoolETHBalanceUpdated(ETH);\n emit EtherSent(msg.sender, depositorETHGain);\n\n borrowerOperations.moveETHGainToTrove{ value: depositorETHGain }(\n msg.sender,\n _upperHint,\n _lowerHint\n );\n }\n\n // --- SOV issuance functions ---\n\n function _triggerSOVIssuance(ICommunityIssuance _communityIssuance) internal {\n uint256 SOVIssuance = _communityIssuance.issueSOV(totalZUSDDeposits);\n _updateG(SOVIssuance);\n }\n\n function _updateG(uint256 _SOVIssuance) internal {\n uint256 totalZUSD = totalZUSDDeposits; // cached to save an SLOAD\n /*\n * When total deposits is 0, G is not updated. In this case, the SOV issued can not be obtained by later\n * depositors - it is missed out on, and remains in the balanceof the CommunityIssuance contract.\n *\n */\n if (totalZUSD == 0 || _SOVIssuance == 0) {\n return;\n }\n\n uint256 SOVPerUnitStaked;\n SOVPerUnitStaked = _computeSOVPerUnitStaked(_SOVIssuance, totalZUSD);\n\n uint256 marginalSOVGain = SOVPerUnitStaked.mul(P);\n epochToScaleToG[currentEpoch][currentScale] = epochToScaleToG[currentEpoch][currentScale]\n .add(marginalSOVGain);\n\n emit G_Updated(epochToScaleToG[currentEpoch][currentScale], currentEpoch, currentScale);\n }\n\n function _computeSOVPerUnitStaked(uint256 _SOVIssuance, uint256 _totalZUSDDeposits)\n internal\n returns (uint256)\n {\n /*\n * Calculate the SOV-per-unit staked. Division uses a \"feedback\" error correction, to keep the\n * cumulative error low in the running total G:\n *\n * 1) Form a numerator which compensates for the floor division error that occurred the last time this\n * function was called.\n * 2) Calculate \"per-unit-staked\" ratio.\n * 3) Multiply the ratio back by its denominator, to reveal the current floor division error.\n * 4) Store this error for use in the next correction when this function is called.\n * 5) Note: static analysis tools complain about this \"division before multiplication\", however, it is intended.\n */\n uint256 SOVNumerator = _SOVIssuance.mul(DECIMAL_PRECISION).add(lastSOVError);\n\n uint256 SOVPerUnitStaked = SOVNumerator.div(_totalZUSDDeposits);\n lastSOVError = SOVNumerator.sub(SOVPerUnitStaked.mul(_totalZUSDDeposits));\n\n return SOVPerUnitStaked;\n }\n\n // --- Liquidation functions ---\n\n /**\n * Cancels out the specified debt against the ZUSD contained in the Stability Pool (as far as possible)\n * and transfers the Trove's ETH collateral from ActivePool to StabilityPool.\n * Only called by liquidation functions in the TroveManager.\n */\n function offset(uint256 _debtToOffset, uint256 _collToAdd) external override {\n _requireCallerIsTroveManager();\n uint256 totalZUSD = totalZUSDDeposits; // cached to save an SLOAD\n if (totalZUSD == 0 || _debtToOffset == 0) {\n return;\n }\n\n _triggerSOVIssuance(communityIssuance);\n\n (\n uint256 ETHGainPerUnitStaked,\n uint256 ZUSDLossPerUnitStaked\n ) = _computeRewardsPerUnitStaked(_collToAdd, _debtToOffset, totalZUSD);\n\n _updateRewardSumAndProduct(ETHGainPerUnitStaked, ZUSDLossPerUnitStaked); // updates S and P\n\n _moveOffsetCollAndDebt(_collToAdd, _debtToOffset);\n }\n\n // --- Offset helper functions ---\n\n function _computeRewardsPerUnitStaked(\n uint256 _collToAdd,\n uint256 _debtToOffset,\n uint256 _totalZUSDDeposits\n ) internal returns (uint256 ETHGainPerUnitStaked, uint256 ZUSDLossPerUnitStaked) {\n /*\n * Compute the ZUSD and ETH rewards. Uses a \"feedback\" error correction, to keep\n * the cumulative error in the P and S state variables low:\n *\n * 1) Form numerators which compensate for the floor division errors that occurred the last time this\n * function was called.\n * 2) Calculate \"per-unit-staked\" ratios.\n * 3) Multiply each ratio back by its denominator, to reveal the current floor division error.\n * 4) Store these errors for use in the next correction when this function is called.\n * 5) Note: static analysis tools complain about this \"division before multiplication\", however, it is intended.\n */\n uint256 ETHNumerator = _collToAdd.mul(DECIMAL_PRECISION).add(lastETHError_Offset);\n\n assert(_debtToOffset <= _totalZUSDDeposits);\n if (_debtToOffset == _totalZUSDDeposits) {\n ZUSDLossPerUnitStaked = DECIMAL_PRECISION; // When the Pool depletes to 0, so does each deposit\n lastZUSDLossError_Offset = 0;\n } else {\n uint256 ZUSDLossNumerator = _debtToOffset.mul(DECIMAL_PRECISION).sub(\n lastZUSDLossError_Offset\n );\n /*\n * Add 1 to make error in quotient positive. We want \"slightly too much\" ZUSD loss,\n * which ensures the error in any given compoundedZUSDDeposit favors the Stability Pool.\n */\n ZUSDLossPerUnitStaked = (ZUSDLossNumerator.div(_totalZUSDDeposits)).add(1);\n lastZUSDLossError_Offset = (ZUSDLossPerUnitStaked.mul(_totalZUSDDeposits)).sub(\n ZUSDLossNumerator\n );\n }\n\n ETHGainPerUnitStaked = ETHNumerator.div(_totalZUSDDeposits);\n lastETHError_Offset = ETHNumerator.sub(ETHGainPerUnitStaked.mul(_totalZUSDDeposits));\n\n return (ETHGainPerUnitStaked, ZUSDLossPerUnitStaked);\n }\n\n /// Update the Stability Pool reward sum S and product P\n function _updateRewardSumAndProduct(\n uint256 _ETHGainPerUnitStaked,\n uint256 _ZUSDLossPerUnitStaked\n ) internal {\n uint256 currentP = P;\n uint256 newP;\n\n assert(_ZUSDLossPerUnitStaked <= DECIMAL_PRECISION);\n /*\n * The newProductFactor is the factor by which to change all deposits, due to the depletion of Stability Pool ZUSD in the liquidation.\n * We make the product factor 0 if there was a pool-emptying. Otherwise, it is (1 - ZUSDLossPerUnitStaked)\n */\n uint256 newProductFactor = uint256(DECIMAL_PRECISION).sub(_ZUSDLossPerUnitStaked);\n\n uint128 currentScaleCached = currentScale;\n uint128 currentEpochCached = currentEpoch;\n uint256 currentS = epochToScaleToSum[currentEpochCached][currentScaleCached];\n\n /*\n * Calculate the new S first, before we update P.\n * The ETH gain for any given depositor from a liquidation depends on the value of their deposit\n * (and the value of totalDeposits) prior to the Stability being depleted by the debt in the liquidation.\n *\n * Since S corresponds to ETH gain, and P to deposit loss, we update S first.\n */\n uint256 marginalETHGain = _ETHGainPerUnitStaked.mul(currentP);\n uint256 newS = currentS.add(marginalETHGain);\n epochToScaleToSum[currentEpochCached][currentScaleCached] = newS;\n emit S_Updated(newS, currentEpochCached, currentScaleCached);\n\n // If the Stability Pool was emptied, increment the epoch, and reset the scale and product P\n if (newProductFactor == 0) {\n currentEpoch = currentEpochCached.add(1);\n emit EpochUpdated(currentEpoch);\n currentScale = 0;\n emit ScaleUpdated(currentScale);\n newP = DECIMAL_PRECISION;\n\n // If multiplying P by a non-sov product factor would reduce P below the scale boundary, increment the scale\n } else if (currentP.mul(newProductFactor).div(DECIMAL_PRECISION) < SCALE_FACTOR) {\n newP = currentP.mul(newProductFactor).mul(SCALE_FACTOR).div(DECIMAL_PRECISION);\n currentScale = currentScaleCached.add(1);\n emit ScaleUpdated(currentScale);\n } else {\n newP = currentP.mul(newProductFactor).div(DECIMAL_PRECISION);\n }\n\n assert(newP > 0);\n P = newP;\n\n emit P_Updated(newP);\n }\n\n function _moveOffsetCollAndDebt(uint256 _collToAdd, uint256 _debtToOffset) internal {\n IActivePool activePoolCached = activePool;\n\n // Cancel the liquidated ZUSD debt with the ZUSD in the stability pool\n activePoolCached.decreaseZUSDDebt(_debtToOffset);\n _decreaseZUSD(_debtToOffset);\n\n // Burn the debt that was successfully offset\n zusdToken.burn(address(this), _debtToOffset);\n\n activePoolCached.sendETH(address(this), _collToAdd);\n }\n\n function _decreaseZUSD(uint256 _amount) internal {\n uint256 newTotalZUSDDeposits = totalZUSDDeposits.sub(_amount);\n totalZUSDDeposits = newTotalZUSDDeposits;\n emit StabilityPoolZUSDBalanceUpdated(newTotalZUSDDeposits);\n }\n\n // --- Reward calculator functions for depositor and front end ---\n\n /** Calculates the ETH gain earned by the deposit since its last snapshots were taken.\n * Given by the formula: E = d0 * (S - S(0))/P(0)\n * where S(0) and P(0) are the depositor's snapshots of the sum S and product P, respectively.\n * d0 is the last recorded deposit value.\n */\n function getDepositorETHGain(address _depositor) public view override returns (uint256) {\n uint256 initialDeposit = deposits[_depositor].initialValue;\n\n if (initialDeposit == 0) {\n return 0;\n }\n\n Snapshots memory snapshots = depositSnapshots[_depositor];\n\n uint256 ETHGain = _getETHGainFromSnapshots(initialDeposit, snapshots);\n return ETHGain;\n }\n\n function _getETHGainFromSnapshots(uint256 initialDeposit, Snapshots memory snapshots)\n internal\n view\n returns (uint256)\n {\n /*\n * Grab the sum 'S' from the epoch at which the stake was made. The ETH gain may span up to one scale change.\n * If it does, the second portion of the ETH gain is scaled by 1e9.\n * If the gain spans no scale change, the second portion will be 0.\n */\n uint128 epochSnapshot = snapshots.epoch;\n uint128 scaleSnapshot = snapshots.scale;\n uint256 S_Snapshot = snapshots.S;\n uint256 P_Snapshot = snapshots.P;\n\n uint256 firstPortion = epochToScaleToSum[epochSnapshot][scaleSnapshot].sub(S_Snapshot);\n uint256 secondPortion = epochToScaleToSum[epochSnapshot][scaleSnapshot.add(1)].div(\n SCALE_FACTOR\n );\n\n uint256 ETHGain = initialDeposit.mul(firstPortion.add(secondPortion)).div(P_Snapshot).div(\n DECIMAL_PRECISION\n );\n\n return ETHGain;\n }\n\n /**\n * Calculate the SOV gain earned by a deposit since its last snapshots were taken.\n * Given by the formula: SOV = d0 * (G - G(0))/P(0)\n * where G(0) and P(0) are the depositor's snapshots of the sum G and product P, respectively.\n * d0 is the last recorded deposit value.\n */\n function getDepositorSOVGain(address _depositor) public view override returns (uint256) {\n uint256 initialDeposit = deposits[_depositor].initialValue;\n if (initialDeposit == 0) {\n return 0;\n }\n\n address frontEndTag = deposits[_depositor].frontEndTag;\n\n /*\n * If not tagged with a front end, the depositor gets a 100% cut of what their deposit earned.\n * Otherwise, their cut of the deposit's earnings is equal to the kickbackRate, set by the front end through\n * which they made their deposit.\n */\n uint256 kickbackRate = frontEndTag == ADDRESS_ZERO\n ? DECIMAL_PRECISION\n : frontEnds[frontEndTag].kickbackRate;\n\n Snapshots memory snapshots = depositSnapshots[_depositor];\n\n uint256 SOVGain = kickbackRate\n .mul(_getSOVGainFromSnapshots(initialDeposit, snapshots))\n .div(DECIMAL_PRECISION);\n\n return SOVGain;\n }\n\n /**\n * Return the SOV gain earned by the front end. Given by the formula: E = D0 * (G - G(0))/P(0)\n * where G(0) and P(0) are the depositor's snapshots of the sum G and product P, respectively.\n *\n * D0 is the last recorded value of the front end's total tagged deposits.\n */\n function getFrontEndSOVGain(address _frontEnd) public view override returns (uint256) {\n uint256 frontEndStake = frontEndStakes[_frontEnd];\n if (frontEndStake == 0) {\n return 0;\n }\n\n uint256 kickbackRate = frontEnds[_frontEnd].kickbackRate;\n uint256 frontEndShare = uint256(DECIMAL_PRECISION).sub(kickbackRate);\n\n Snapshots memory snapshots = frontEndSnapshots[_frontEnd];\n\n uint256 SOVGain = frontEndShare\n .mul(_getSOVGainFromSnapshots(frontEndStake, snapshots))\n .div(DECIMAL_PRECISION);\n return SOVGain;\n }\n\n function _getSOVGainFromSnapshots(uint256 initialStake, Snapshots memory snapshots)\n internal\n view\n returns (uint256)\n {\n /*\n * Grab the sum 'G' from the epoch at which the stake was made. The SOV gain may span up to one scale change.\n * If it does, the second portion of the SOV gain is scaled by 1e9.\n * If the gain spans no scale change, the second portion will be 0.\n */\n uint128 epochSnapshot = snapshots.epoch;\n uint128 scaleSnapshot = snapshots.scale;\n uint256 G_Snapshot = snapshots.G;\n uint256 P_Snapshot = snapshots.P;\n\n uint256 firstPortion = epochToScaleToG[epochSnapshot][scaleSnapshot].sub(G_Snapshot);\n uint256 secondPortion = epochToScaleToG[epochSnapshot][scaleSnapshot.add(1)].div(\n SCALE_FACTOR\n );\n\n uint256 SOVGain = initialStake.mul(firstPortion.add(secondPortion)).div(P_Snapshot).div(\n DECIMAL_PRECISION\n );\n\n return SOVGain;\n }\n\n // --- Compounded deposit and compounded front end stake ---\n\n /**\n * Return the user's compounded deposit. Given by the formula: d = d0 * P/P(0)\n * where P(0) is the depositor's snapshot of the product P, taken when they last updated their deposit.\n */\n function getCompoundedZUSDDeposit(address _depositor) public view override returns (uint256) {\n uint256 initialDeposit = deposits[_depositor].initialValue;\n if (initialDeposit == 0) {\n return 0;\n }\n\n Snapshots memory snapshots = depositSnapshots[_depositor];\n\n uint256 compoundedDeposit = _getCompoundedStakeFromSnapshots(initialDeposit, snapshots);\n return compoundedDeposit;\n }\n\n /**\n * Return the front end's compounded stake. Given by the formula: D = D0 * P/P(0)\n * where P(0) is the depositor's snapshot of the product P, taken at the last time\n * when one of the front end's tagged deposits updated their deposit.\n *\n * The front end's compounded stake is equal to the sum of its depositors' compounded deposits.\n */\n function getCompoundedFrontEndStake(address _frontEnd) public view override returns (uint256) {\n uint256 frontEndStake = frontEndStakes[_frontEnd];\n if (frontEndStake == 0) {\n return 0;\n }\n\n Snapshots memory snapshots = frontEndSnapshots[_frontEnd];\n\n uint256 compoundedFrontEndStake = _getCompoundedStakeFromSnapshots(\n frontEndStake,\n snapshots\n );\n return compoundedFrontEndStake;\n }\n\n // Internal function, used to calculcate compounded deposits and compounded front end stakes.\n function _getCompoundedStakeFromSnapshots(uint256 initialStake, Snapshots memory snapshots)\n internal\n view\n returns (uint256)\n {\n uint256 snapshot_P = snapshots.P;\n uint128 scaleSnapshot = snapshots.scale;\n uint128 epochSnapshot = snapshots.epoch;\n\n // If stake was made before a pool-emptying event, then it has been fully cancelled with debt -- so, return 0\n if (epochSnapshot < currentEpoch) {\n return 0;\n }\n\n uint256 compoundedStake;\n uint128 scaleDiff = currentScale.sub(scaleSnapshot);\n\n /* Compute the compounded stake. If a scale change in P was made during the stake's lifetime,\n * account for it. If more than one scale change was made, then the stake has decreased by a factor of\n * at least 1e-9 -- so return 0.\n */\n if (scaleDiff == 0) {\n compoundedStake = initialStake.mul(P).div(snapshot_P);\n } else if (scaleDiff == 1) {\n compoundedStake = initialStake.mul(P).div(snapshot_P).div(SCALE_FACTOR);\n } else {\n // if scaleDiff >= 2\n compoundedStake = 0;\n }\n\n /*\n * If compounded deposit is less than a billionth of the initial deposit, return 0.\n *\n * NOTE: originally, this line was in place to stop rounding errors making the deposit too large. However, the error\n * corrections should ensure the error in P \"favors the Pool\", i.e. any given compounded deposit should slightly less\n * than it's theoretical value.\n *\n * Thus it's unclear whether this line is still really needed.\n */\n if (compoundedStake < initialStake.div(1e9)) {\n return 0;\n }\n\n return compoundedStake;\n }\n\n // --- Sender functions for ZUSD deposit, ETH gains and SOV gains ---\n\n /// Transfer the ZUSD tokens from the user to the Stability Pool's address, and update its recorded ZUSD\n function _sendZUSDtoStabilityPool(address _address, uint256 _amount) internal {\n zusdToken.sendToPool(_address, address(this), _amount);\n uint256 newTotalZUSDDeposits = totalZUSDDeposits.add(_amount);\n totalZUSDDeposits = newTotalZUSDDeposits;\n emit StabilityPoolZUSDBalanceUpdated(newTotalZUSDDeposits);\n }\n\n function _sendETHGainToDepositor(uint256 _amount) internal {\n _sendETHGainTo(_amount, msg.sender);\n }\n\n function _sendETHGainTo(uint256 _amount, address _receiver) internal {\n require(_receiver != address(0), \"SP::_sendETHGainTo: _receiver is zero address\");\n if (_amount == 0) {\n return;\n }\n uint256 newETH = ETH.sub(_amount);\n ETH = newETH;\n emit StabilityPoolETHBalanceUpdated(newETH);\n emit EtherSent(msg.sender, _amount);\n\n (bool success, ) = msg.sender.call{ value: _amount }(\"\");\n require(success, \"StabilityPool: sending ETH failed\");\n }\n\n /// Send ZUSD to user and decrease ZUSD in Pool\n function _sendZUSDToDepositor(address _depositor, uint256 ZUSDWithdrawal) internal {\n if (ZUSDWithdrawal == 0) {\n return;\n }\n\n zusdToken.returnFromPool(address(this), _depositor, ZUSDWithdrawal);\n _decreaseZUSD(ZUSDWithdrawal);\n }\n\n // --- External Front End functions ---\n\n /// Front end makes a one-time selection of kickback rate upon registering\n function registerFrontEnd(uint256 _kickbackRate) external override {\n _requireFrontEndNotRegistered(msg.sender);\n _requireUserHasNoDeposit(msg.sender);\n _requireValidKickbackRate(_kickbackRate);\n\n frontEnds[msg.sender].kickbackRate = _kickbackRate;\n frontEnds[msg.sender].registered = true;\n\n emit FrontEndRegistered(msg.sender, _kickbackRate);\n }\n\n // --- Stability Pool Deposit Functionality ---\n\n function _setFrontEndTag(address _depositor, address _frontEndTag) internal {\n deposits[_depositor].frontEndTag = _frontEndTag;\n emit FrontEndTagSet(_depositor, _frontEndTag);\n }\n\n function _updateDepositAndSnapshots(address _depositor, uint256 _newValue) internal {\n deposits[_depositor].initialValue = _newValue;\n\n if (_newValue == 0) {\n delete deposits[_depositor].frontEndTag;\n delete depositSnapshots[_depositor];\n emit DepositSnapshotUpdated(_depositor, 0, 0, 0);\n return;\n }\n uint128 currentScaleCached = currentScale;\n uint128 currentEpochCached = currentEpoch;\n uint256 currentP = P;\n\n // Get S and G for the current epoch and current scale\n uint256 currentS = epochToScaleToSum[currentEpochCached][currentScaleCached];\n uint256 currentG = epochToScaleToG[currentEpochCached][currentScaleCached];\n\n // Record new snapshots of the latest running product P, sum S, and sum G, for the depositor\n depositSnapshots[_depositor].P = currentP;\n depositSnapshots[_depositor].S = currentS;\n depositSnapshots[_depositor].G = currentG;\n depositSnapshots[_depositor].scale = currentScaleCached;\n depositSnapshots[_depositor].epoch = currentEpochCached;\n\n emit DepositSnapshotUpdated(_depositor, currentP, currentS, currentG);\n }\n\n function _updateFrontEndStakeAndSnapshots(address _frontEnd, uint256 _newValue) internal {\n frontEndStakes[_frontEnd] = _newValue;\n\n if (_newValue == 0) {\n delete frontEndSnapshots[_frontEnd];\n emit FrontEndSnapshotUpdated(_frontEnd, 0, 0);\n return;\n }\n\n uint128 currentScaleCached = currentScale;\n uint128 currentEpochCached = currentEpoch;\n uint256 currentP = P;\n\n // Get G for the current epoch and current scale\n uint256 currentG = epochToScaleToG[currentEpochCached][currentScaleCached];\n\n // Record new snapshots of the latest running product P and sum G for the front end\n frontEndSnapshots[_frontEnd].P = currentP;\n frontEndSnapshots[_frontEnd].G = currentG;\n frontEndSnapshots[_frontEnd].scale = currentScaleCached;\n frontEndSnapshots[_frontEnd].epoch = currentEpochCached;\n\n emit FrontEndSnapshotUpdated(_frontEnd, currentP, currentG);\n }\n\n function _payOutSOVGains(\n ICommunityIssuance _communityIssuance,\n address _depositor,\n address _frontEnd\n ) internal {\n // Pay out front end's SOV gain\n if (_frontEnd != ADDRESS_ZERO) {\n uint256 frontEndSOVGain = getFrontEndSOVGain(_frontEnd);\n _communityIssuance.sendSOV(_frontEnd, frontEndSOVGain);\n emit SOVPaidToFrontEnd(_frontEnd, frontEndSOVGain);\n }\n\n // Pay out depositor's SOV gain\n uint256 depositorSOVGain = getDepositorSOVGain(_depositor);\n _communityIssuance.sendSOV(_depositor, depositorSOVGain);\n emit SOVPaidToDepositor(_depositor, depositorSOVGain);\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == address(activePool), \"StabilityPool: Caller is not ActivePool\");\n }\n\n function _requireCallerIsTroveManager() internal view {\n require(msg.sender == address(troveManager), \"StabilityPool: Caller is not TroveManager\");\n }\n\n function _requireNoUnderCollateralizedTroves() internal {\n uint256 price = priceFeed.fetchPrice();\n address lowestTrove = sortedTroves.getLast();\n uint256 ICR = troveManager.getCurrentICR(lowestTrove, price);\n require(\n ICR >= liquityBaseParams.MCR(),\n \"StabilityPool: Cannot withdraw while there are troves with ICR < MCR\"\n );\n }\n\n function _requireUserHasDeposit(uint256 _initialDeposit) internal pure {\n require(_initialDeposit > 0, \"StabilityPool: User must have a non-zero deposit\");\n }\n\n function _requireUserHasNoDeposit(address _address) internal view {\n uint256 initialDeposit = deposits[_address].initialValue;\n require(initialDeposit == 0, \"StabilityPool: User must have no deposit\");\n }\n\n function _requireNonZeroAmount(uint256 _amount) internal pure {\n require(_amount > 0, \"StabilityPool: Amount must be non-zero\");\n }\n\n function _requireUserHasTrove(address _depositor) internal view {\n require(\n troveManager.getTroveStatus(_depositor) == 1,\n \"StabilityPool: caller must have an active trove to withdraw ETHGain to\"\n );\n }\n\n function _requireUserHasETHGain(address _depositor) internal view {\n uint256 ETHGain = getDepositorETHGain(_depositor);\n require(ETHGain > 0, \"StabilityPool: caller must have non-zero ETH Gain\");\n }\n\n function _requireFrontEndNotRegistered(address _address) internal view {\n require(\n !frontEnds[_address].registered,\n \"StabilityPool: must not already be a registered front end\"\n );\n }\n\n function _requireFrontEndIsRegisteredOrZero(address _address) internal view {\n require(\n frontEnds[_address].registered || _address == ADDRESS_ZERO,\n \"StabilityPool: Tag must be a registered front end, or the zero address\"\n );\n }\n\n function _requireValidKickbackRate(uint256 _kickbackRate) internal pure {\n require(\n _kickbackRate <= DECIMAL_PRECISION,\n \"StabilityPool: Kickback rate must be in range [0,1]\"\n );\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsActivePool();\n ETH = ETH.add(msg.value);\n StabilityPoolETHBalanceUpdated(ETH);\n }\n}\n" + }, + "contracts/StabilityPoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ICommunityIssuance.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/BaseMath.sol\";\n\ncontract StabilityPoolStorage is Ownable, BaseMath {\n string public constant NAME = \"StabilityPool\";\n\n IBorrowerOperations public borrowerOperations;\n\n ITroveManager public troveManager;\n\n IZUSDToken public zusdToken;\n\n // Needed to check if there are pending liquidations\n ISortedTroves public sortedTroves;\n\n ICommunityIssuance public communityIssuance;\n\n uint256 internal ETH; // deposited ether tracker\n\n // Tracker for ZUSD held in the pool. Changes when users deposit/withdraw, and when Trove debt is offset.\n uint256 internal totalZUSDDeposits;\n\n // --- Data structures ---\n\n struct FrontEnd {\n uint256 kickbackRate;\n bool registered;\n }\n\n struct Deposit {\n uint256 initialValue;\n address frontEndTag;\n }\n\n struct Snapshots {\n uint256 S;\n uint256 P;\n uint256 G;\n uint128 scale;\n uint128 epoch;\n }\n\n mapping(address => Deposit) public deposits; // depositor address -> Deposit struct\n mapping(address => Snapshots) public depositSnapshots; // depositor address -> snapshots struct\n\n mapping(address => FrontEnd) public frontEnds; // front end address -> FrontEnd struct\n mapping(address => uint256) public frontEndStakes; // front end address -> last recorded total deposits, tagged with that front end\n mapping(address => Snapshots) public frontEndSnapshots; // front end address -> snapshots struct\n\n /* Product 'P': Running product by which to multiply an initial deposit, in order to find the current compounded deposit,\n * after a series of liquidations have occurred, each of which cancel some ZUSD debt with the deposit.\n *\n * During its lifetime, a deposit's value evolves from d_t to d_t * P / P_t , where P_t\n * is the snapshot of P taken at the instant the deposit was made. 18-digit decimal.\n */\n uint256 public P;\n\n uint256 public constant SCALE_FACTOR = 1e9;\n\n // Each time the scale of P shifts by SCALE_FACTOR, the scale is incremented by 1\n uint128 public currentScale;\n\n // With each offset that fully empties the Pool, the epoch is incremented by 1\n uint128 public currentEpoch;\n\n /* ETH Gain sum 'S': During its lifetime, each deposit d_t earns an ETH gain of ( d_t * [S - S_t] )/P_t, where S_t\n * is the depositor's snapshot of S taken at the time t when the deposit was made.\n *\n * The 'S' sums are stored in a nested mapping (epoch => scale => sum):\n *\n * - The inner mapping records the sum S at different scales\n * - The outer mapping records the (scale => sum) mappings, for different epochs.\n */\n mapping(uint128 => mapping(uint128 => uint256)) public epochToScaleToSum;\n\n /*\n * Similarly, the sum 'G' is used to calculate SOV gains. During it's lifetime, each deposit d_t earns a SOV gain of\n * ( d_t * [G - G_t] )/P_t, where G_t is the depositor's snapshot of G taken at time t when the deposit was made.\n *\n * SOV reward events occur are triggered by depositor operations (new deposit, topup, withdrawal), and liquidations.\n * In each case, the SOV reward is issued (i.e. G is updated), before other state changes are made.\n */\n mapping(uint128 => mapping(uint128 => uint256)) public epochToScaleToG;\n\n // Error tracker for the error correction in the SOV issuance calculation\n uint256 public lastSOVError;\n // Error trackers for the error correction in the offset calculation\n uint256 public lastETHError_Offset;\n uint256 public lastZUSDLossError_Offset;\n}\n" + }, + "contracts/TestContracts/ActivePoolTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ActivePool.sol\";\n\ncontract ActivePoolTester is ActivePool {\n \n function unprotectedIncreaseZUSDDebt(uint _amount) external {\n ZUSDDebt = ZUSDDebt.add(_amount);\n }\n\n function unprotectedPayable() external payable {\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/TestContracts/BorrowerOperationsTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../BorrowerOperations.sol\";\n\n/* Tester contract inherits from BorrowerOperations, and provides external functions \nfor testing the parent's internal functions. */\ncontract BorrowerOperationsTester is BorrowerOperations {\n\n function getNewICRFromTroveChange\n (\n uint _coll, \n uint _debt, \n uint _collChange, \n bool isCollIncrease, \n uint _debtChange, \n bool isDebtIncrease, \n uint _price\n ) \n external\n pure\n returns (uint)\n {\n return _getNewICRFromTroveChange(_coll, _debt, _collChange, isCollIncrease, _debtChange, isDebtIncrease, _price);\n }\n\n function getNewTCRFromTroveChange\n (\n uint _collChange, \n bool isCollIncrease, \n uint _debtChange, \n bool isDebtIncrease, \n uint _price\n ) \n external \n view\n returns (uint) \n {\n return _getNewTCRFromTroveChange(_collChange, isCollIncrease, _debtChange, isDebtIncrease, _price);\n }\n\n function getUSDValue(uint _coll, uint _price) external pure returns (uint) {\n return _getUSDValue(_coll, _price);\n }\n\n function callInternalAdjustLoan\n (\n address _borrower, \n uint _collWithdrawal, \n uint _debtChange, \n bool _isDebtIncrease, \n address _upperHint,\n address _lowerHint)\n external \n {\n _adjustTrove(_borrower, _collWithdrawal, _debtChange, _isDebtIncrease, _upperHint, _lowerHint, 0);\n }\n\n\n // Payable fallback function\n receive() external payable { }\n}\n" + }, + "contracts/TestContracts/CommunityIssuanceTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/CommunityIssuance.sol\";\n\ncontract CommunityIssuanceTester is CommunityIssuance {\n function obtainSOV(uint _amount) external {\n sovToken.transfer(msg.sender, _amount);\n }\n\n function unprotectedIssueSOV(uint256 _totalZUSDDeposits) external returns (uint) {\n // No checks on caller address\n \n uint256 timePassedSinceLastIssuance = (block.timestamp.sub(lastIssuanceTime));\n uint256 latestTotalSOVIssued = _ZUSDToSOV(_totalZUSDDeposits.mul(APR).div(MAX_BPS).mul(timePassedSinceLastIssuance).div(365 days));\n \n uint256 issuance = latestTotalSOVIssued.sub(totalSOVIssued);\n\n totalSOVIssued = latestTotalSOVIssued;\n lastIssuanceTime = block.timestamp;\n emit TotalSOVIssuedUpdated(latestTotalSOVIssued);\n\n return issuance;\n }\n}\n" + }, + "contracts/TestContracts/DefaultPoolTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../DefaultPool.sol\";\n\ncontract DefaultPoolTester is DefaultPool {\n \n function unprotectedIncreaseZUSDDebt(uint _amount) external {\n ZUSDDebt = ZUSDDebt.add(_amount);\n }\n\n function unprotectedPayable() external payable {\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/TestContracts/EchidnaProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../TroveManager.sol\";\nimport \"../BorrowerOperations.sol\";\nimport \"../StabilityPool.sol\";\nimport \"../ZUSDToken.sol\";\n\ncontract EchidnaProxy {\n TroveManager troveManager;\n BorrowerOperations borrowerOperations;\n StabilityPool stabilityPool;\n ZUSDToken zusdToken;\n\n constructor(\n TroveManager _troveManager,\n BorrowerOperations _borrowerOperations,\n StabilityPool _stabilityPool,\n ZUSDToken _zusdToken\n ) public {\n troveManager = _troveManager;\n borrowerOperations = _borrowerOperations;\n stabilityPool = _stabilityPool;\n zusdToken = _zusdToken;\n }\n\n receive() external payable {\n // do nothing\n }\n\n // TroveManager\n\n function liquidatePrx(address _user) external {\n troveManager.liquidate(_user);\n }\n\n function liquidateTrovesPrx(uint _n) external {\n troveManager.liquidateTroves(_n);\n }\n\n function batchLiquidateTrovesPrx(address[] calldata _troveArray) external {\n troveManager.batchLiquidateTroves(_troveArray);\n }\n\n function redeemCollateralPrx(\n uint _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint _partialRedemptionHintNICR,\n uint _maxIterations,\n uint _maxFee\n ) external {\n troveManager.redeemCollateral(_ZUSDAmount, _firstRedemptionHint, _upperPartialRedemptionHint, _lowerPartialRedemptionHint, _partialRedemptionHintNICR, _maxIterations, _maxFee);\n }\n\n // Borrower Operations\n function openTrovePrx(uint _ETH, uint _ZUSDAmount, address _upperHint, address _lowerHint, uint _maxFee) external payable {\n borrowerOperations.openTrove{value: _ETH}(_maxFee, _ZUSDAmount, _upperHint, _lowerHint);\n }\n\n function addCollPrx(uint _ETH, address _upperHint, address _lowerHint) external payable {\n borrowerOperations.addColl{value: _ETH}(_upperHint, _lowerHint);\n }\n\n function withdrawCollPrx(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.withdrawColl(_amount, _upperHint, _lowerHint);\n }\n\n function withdrawZUSDPrx(uint _amount, address _upperHint, address _lowerHint, uint _maxFee) external {\n borrowerOperations.withdrawZUSD(_maxFee, _amount, _upperHint, _lowerHint);\n }\n\n function repayZUSDPrx(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.repayZUSD(_amount, _upperHint, _lowerHint);\n }\n\n function closeTrovePrx() external {\n borrowerOperations.closeTrove();\n }\n\n function adjustTrovePrx(uint _ETH, uint _collWithdrawal, uint _debtChange, bool _isDebtIncrease, address _upperHint, address _lowerHint, uint _maxFee) external payable {\n borrowerOperations.adjustTrove{value: _ETH}(_maxFee, _collWithdrawal, _debtChange, _isDebtIncrease, _upperHint, _lowerHint);\n }\n\n // Pool Manager\n function provideToSPPrx(uint _amount, address _frontEndTag) external {\n stabilityPool.provideToSP(_amount, _frontEndTag);\n }\n\n function withdrawFromSPPrx(uint _amount) external {\n stabilityPool.withdrawFromSP(_amount);\n }\n\n // ZUSD Token\n\n function transferPrx(address recipient, uint256 amount) external returns (bool) {\n return zusdToken.transfer(recipient, amount);\n }\n\n function approvePrx(address spender, uint256 amount) external returns (bool) {\n return zusdToken.approve(spender, amount);\n }\n\n function transferFromPrx(address sender, address recipient, uint256 amount) external returns (bool) {\n return zusdToken.transferFrom(sender, recipient, amount);\n }\n\n function increaseAllowancePrx(address spender, uint256 addedValue) external returns (bool) {\n return zusdToken.increaseAllowance(spender, addedValue);\n }\n\n function decreaseAllowancePrx(address spender, uint256 subtractedValue) external returns (bool) {\n return zusdToken.decreaseAllowance(spender, subtractedValue);\n }\n}\n" + }, + "contracts/TestContracts/EchidnaTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../LiquityBaseParams.sol\";\nimport \"../Interfaces/ITroveManager.sol\";\nimport \"../TroveManager.sol\";\nimport \"../TroveManagerStorage.sol\";\nimport \"../Dependencies/TroveManagerRedeemOps.sol\";\nimport \"../BorrowerOperations.sol\";\nimport \"../ActivePool.sol\";\nimport \"../DefaultPool.sol\";\nimport \"../StabilityPool.sol\";\nimport \"../GasPool.sol\";\nimport \"../CollSurplusPool.sol\";\nimport \"../ZUSDToken.sol\";\nimport \"./PriceFeedTestnet.sol\";\nimport \"../SortedTroves.sol\";\nimport \"./EchidnaProxy.sol\";\n\n//import \"../Dependencies/console.sol\";\n\n// Run with:\n// rm -f fuzzTests/corpus/* # (optional)\n// ~/.local/bin/echidna-test contracts/TestContracts/EchidnaTester.sol --contract EchidnaTester --config fuzzTests/echidna_config.yaml\n\ncontract EchidnaTester {\n using SafeMath for uint;\n\n uint private constant NUMBER_OF_ACTORS = 100;\n uint private constant INITIAL_BALANCE = 1e24;\n uint private MCR;\n uint private CCR;\n uint private ZUSD_GAS_COMPENSATION;\n\n LiquityBaseParams public liquityBaseParams;\n TroveManagerRedeemOps public troveManagerRedeemOps;\n TroveManager public troveManager;\n BorrowerOperations public borrowerOperations;\n ActivePool public activePool;\n DefaultPool public defaultPool;\n StabilityPool public stabilityPool;\n GasPool public gasPool;\n CollSurplusPool public collSurplusPool;\n ZUSDToken public zusdToken;\n PriceFeedTestnet priceFeedTestnet;\n SortedTroves sortedTroves;\n\n EchidnaProxy[NUMBER_OF_ACTORS] public echidnaProxies;\n\n uint private numberOfTroves;\n\n constructor() public payable {\n liquityBaseParams = new LiquityBaseParams();\n troveManagerRedeemOps = new TroveManagerRedeemOps(14 * 86400);\n troveManager = new TroveManager(14 days);\n borrowerOperations = new BorrowerOperations();\n activePool = new ActivePool();\n defaultPool = new DefaultPool();\n stabilityPool = new StabilityPool();\n gasPool = new GasPool();\n zusdToken = new ZUSDToken();\n zusdToken.initialize(\n address(troveManager),\n address(stabilityPool),\n address(borrowerOperations)\n );\n\n collSurplusPool = new CollSurplusPool();\n priceFeedTestnet = new PriceFeedTestnet();\n\n sortedTroves = new SortedTroves();\n\n troveManager.setAddresses(\n ITroveManager.TroveManagerInitAddressesParams(\n address(0),\n address(troveManagerRedeemOps),\n address(liquityBaseParams),\n address(borrowerOperations),\n address(activePool),\n address(defaultPool),\n address(stabilityPool),\n address(gasPool),\n address(collSurplusPool),\n address(priceFeedTestnet),\n address(zusdToken),\n address(sortedTroves),\n address(0),\n address(0)\n )\n );\n\n borrowerOperations.setAddresses(\n address(0),\n address(liquityBaseParams),\n address(troveManager),\n address(activePool),\n address(defaultPool),\n address(stabilityPool),\n address(gasPool),\n address(collSurplusPool),\n address(priceFeedTestnet),\n address(sortedTroves),\n address(zusdToken),\n address(0)\n );\n\n activePool.setAddresses(\n address(borrowerOperations),\n address(troveManager),\n address(stabilityPool),\n address(defaultPool)\n );\n\n defaultPool.setAddresses(address(troveManager), address(activePool));\n\n stabilityPool.setAddresses(\n address(liquityBaseParams),\n address(borrowerOperations),\n address(troveManager),\n address(activePool),\n address(zusdToken),\n address(sortedTroves),\n address(priceFeedTestnet),\n address(0)\n );\n\n collSurplusPool.setAddresses(\n address(borrowerOperations),\n address(troveManager),\n address(activePool)\n );\n\n sortedTroves.setParams(1e18, address(troveManager), address(borrowerOperations));\n\n for (uint i = 0; i < NUMBER_OF_ACTORS; i++) {\n echidnaProxies[i] = new EchidnaProxy(\n troveManager,\n borrowerOperations,\n stabilityPool,\n zusdToken\n );\n (bool success, ) = address(echidnaProxies[i]).call{ value: INITIAL_BALANCE }(\"\");\n require(success);\n }\n\n MCR = borrowerOperations.liquityBaseParams().MCR();\n CCR = borrowerOperations.liquityBaseParams().CCR();\n ZUSD_GAS_COMPENSATION = borrowerOperations.ZUSD_GAS_COMPENSATION();\n require(MCR > 0);\n require(CCR > 0);\n\n // TODO:\n priceFeedTestnet.setPrice(1e22);\n }\n\n // TroveManager\n\n function liquidateExt(uint _i, address _user) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].liquidatePrx(_user);\n }\n\n function liquidateTrovesExt(uint _i, uint _n) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].liquidateTrovesPrx(_n);\n }\n\n function batchLiquidateTrovesExt(uint _i, address[] calldata _troveArray) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].batchLiquidateTrovesPrx(_troveArray);\n }\n\n function redeemCollateralExt(\n uint _i,\n uint _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint _partialRedemptionHintNICR\n ) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].redeemCollateralPrx(\n _ZUSDAmount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n 0,\n 0\n );\n }\n\n // Borrower Operations\n\n function getAdjustedETH(\n uint actorBalance,\n uint _ETH,\n uint ratio\n ) internal view returns (uint) {\n uint price = priceFeedTestnet.getPrice();\n require(price > 0);\n uint minETH = ratio.mul(ZUSD_GAS_COMPENSATION).div(price);\n require(actorBalance > minETH);\n uint ETH = minETH + (_ETH % (actorBalance - minETH));\n return ETH;\n }\n\n function getAdjustedZUSD(uint ETH, uint _ZUSDAmount, uint ratio) internal view returns (uint) {\n uint price = priceFeedTestnet.getPrice();\n uint ZUSDAmount = _ZUSDAmount;\n uint compositeDebt = ZUSDAmount.add(ZUSD_GAS_COMPENSATION);\n uint ICR = LiquityMath._computeCR(ETH, compositeDebt, price);\n if (ICR < ratio) {\n compositeDebt = ETH.mul(price).div(ratio);\n ZUSDAmount = compositeDebt.sub(ZUSD_GAS_COMPENSATION);\n }\n return ZUSDAmount;\n }\n\n function openTroveExt(uint _i, uint _ETH, uint _ZUSDAmount) public payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n EchidnaProxy echidnaProxy = echidnaProxies[actor];\n uint actorBalance = address(echidnaProxy).balance;\n\n // we pass in CCR instead of MCR in case it’s the first one\n uint ETH = getAdjustedETH(actorBalance, _ETH, CCR);\n uint ZUSDAmount = getAdjustedZUSD(ETH, _ZUSDAmount, CCR);\n\n echidnaProxy.openTrovePrx(ETH, ZUSDAmount, address(0), address(0), 0);\n\n numberOfTroves = troveManager.getTroveOwnersCount();\n assert(numberOfTroves > 0);\n // canary\n //assert(numberOfTroves == 0);\n }\n\n function openTroveRawExt(\n uint _i,\n uint _ETH,\n uint _ZUSDAmount,\n address _upperHint,\n address _lowerHint,\n uint _maxFee\n ) public payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].openTrovePrx(_ETH, _ZUSDAmount, _upperHint, _lowerHint, _maxFee);\n }\n\n function addCollExt(uint _i, uint _ETH) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n EchidnaProxy echidnaProxy = echidnaProxies[actor];\n uint actorBalance = address(echidnaProxy).balance;\n\n uint ETH = getAdjustedETH(actorBalance, _ETH, MCR);\n\n echidnaProxy.addCollPrx(ETH, address(0), address(0));\n }\n\n function addCollRawExt(\n uint _i,\n uint _ETH,\n address _upperHint,\n address _lowerHint\n ) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].addCollPrx(_ETH, _upperHint, _lowerHint);\n }\n\n function withdrawCollExt(\n uint _i,\n uint _amount,\n address _upperHint,\n address _lowerHint\n ) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].withdrawCollPrx(_amount, _upperHint, _lowerHint);\n }\n\n function withdrawZUSDExt(\n uint _i,\n uint _amount,\n address _upperHint,\n address _lowerHint,\n uint _maxFee\n ) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].withdrawZUSDPrx(_amount, _upperHint, _lowerHint, _maxFee);\n }\n\n function repayZUSDExt(uint _i, uint _amount, address _upperHint, address _lowerHint) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].repayZUSDPrx(_amount, _upperHint, _lowerHint);\n }\n\n function closeTroveExt(uint _i) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].closeTrovePrx();\n }\n\n function adjustTroveExt(\n uint _i,\n uint _ETH,\n uint _collWithdrawal,\n uint _debtChange,\n bool _isDebtIncrease\n ) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n EchidnaProxy echidnaProxy = echidnaProxies[actor];\n uint actorBalance = address(echidnaProxy).balance;\n\n uint ETH = getAdjustedETH(actorBalance, _ETH, MCR);\n uint debtChange = _debtChange;\n if (_isDebtIncrease) {\n // TODO: add current amount already withdrawn:\n debtChange = getAdjustedZUSD(ETH, uint(_debtChange), MCR);\n }\n // TODO: collWithdrawal, debtChange\n echidnaProxy.adjustTrovePrx(\n ETH,\n _collWithdrawal,\n debtChange,\n _isDebtIncrease,\n address(0),\n address(0),\n 0\n );\n }\n\n function adjustTroveRawExt(\n uint _i,\n uint _ETH,\n uint _collWithdrawal,\n uint _debtChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n uint _maxFee\n ) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].adjustTrovePrx(\n _ETH,\n _collWithdrawal,\n _debtChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFee\n );\n }\n\n // Pool Manager\n\n function provideToSPExt(uint _i, uint _amount, address _frontEndTag) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].provideToSPPrx(_amount, _frontEndTag);\n }\n\n function withdrawFromSPExt(uint _i, uint _amount) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].withdrawFromSPPrx(_amount);\n }\n\n // ZUSD Token\n\n function transferExt(uint _i, address recipient, uint256 amount) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].transferPrx(recipient, amount);\n }\n\n function approveExt(uint _i, address spender, uint256 amount) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].approvePrx(spender, amount);\n }\n\n function transferFromExt(\n uint _i,\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].transferFromPrx(sender, recipient, amount);\n }\n\n function increaseAllowanceExt(\n uint _i,\n address spender,\n uint256 addedValue\n ) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].increaseAllowancePrx(spender, addedValue);\n }\n\n function decreaseAllowanceExt(\n uint _i,\n address spender,\n uint256 subtractedValue\n ) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].decreaseAllowancePrx(spender, subtractedValue);\n }\n\n // PriceFeed\n\n function setPriceExt(uint256 _price) external {\n bool result = priceFeedTestnet.setPrice(_price);\n assert(result);\n }\n\n // --------------------------\n // Invariants and properties\n // --------------------------\n\n function echidna_canary_number_of_troves() public view returns (bool) {\n if (numberOfTroves > 20) {\n return false;\n }\n\n return true;\n }\n\n function echidna_canary_active_pool_balance() public view returns (bool) {\n if (address(activePool).balance > 0) {\n return false;\n }\n return true;\n }\n\n function echidna_troves_order() external view returns (bool) {\n address currentTrove = sortedTroves.getFirst();\n address nextTrove = sortedTroves.getNext(currentTrove);\n\n while (currentTrove != address(0) && nextTrove != address(0)) {\n if (troveManager.getNominalICR(nextTrove) > troveManager.getNominalICR(currentTrove)) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n currentTrove = nextTrove;\n nextTrove = sortedTroves.getNext(currentTrove);\n }\n\n return true;\n }\n\n /**\n * Status\n * Minimum debt (gas compensation)\n * Stake > 0\n */\n function echidna_trove_properties() public view returns (bool) {\n address currentTrove = sortedTroves.getFirst();\n while (currentTrove != address(0)) {\n // Status\n if (\n TroveManagerStorage.Status(troveManager.getTroveStatus(currentTrove)) !=\n TroveManagerStorage.Status.active\n ) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n // Minimum debt (gas compensation)\n if (troveManager.getTroveDebt(currentTrove) < ZUSD_GAS_COMPENSATION) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n // Stake > 0\n if (troveManager.getTroveStake(currentTrove) == 0) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n currentTrove = sortedTroves.getNext(currentTrove);\n }\n return true;\n }\n\n function echidna_ETH_balances() public view returns (bool) {\n if (address(troveManager).balance > 0) {\n return false;\n }\n\n if (address(borrowerOperations).balance > 0) {\n return false;\n }\n\n if (address(activePool).balance != activePool.getETH()) {\n return false;\n }\n\n if (address(defaultPool).balance != defaultPool.getETH()) {\n return false;\n }\n\n if (address(stabilityPool).balance != stabilityPool.getETH()) {\n return false;\n }\n\n if (address(zusdToken).balance > 0) {\n return false;\n }\n\n if (address(priceFeedTestnet).balance > 0) {\n return false;\n }\n\n if (address(sortedTroves).balance > 0) {\n return false;\n }\n\n return true;\n }\n\n // TODO: What should we do with this? Should it be allowed? Should it be a canary?\n function echidna_price() public view returns (bool) {\n uint price = priceFeedTestnet.getPrice();\n\n if (price == 0) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n return true;\n }\n\n // Total ZUSD matches\n function echidna_ZUSD_global_balances() public view returns (bool) {\n uint totalSupply = zusdToken.totalSupply();\n uint gasPoolBalance = zusdToken.balanceOf(address(gasPool));\n\n uint activePoolBalance = activePool.getZUSDDebt();\n uint defaultPoolBalance = defaultPool.getZUSDDebt();\n if (totalSupply != activePoolBalance + defaultPoolBalance) {\n return false;\n }\n\n uint stabilityPoolBalance = stabilityPool.getTotalZUSDDeposits();\n address currentTrove = sortedTroves.getFirst();\n uint trovesBalance;\n while (currentTrove != address(0)) {\n trovesBalance += zusdToken.balanceOf(address(currentTrove));\n currentTrove = sortedTroves.getNext(currentTrove);\n }\n // we cannot state equality because tranfers are made to external addresses too\n if (totalSupply <= stabilityPoolBalance + trovesBalance + gasPoolBalance) {\n return false;\n }\n\n return true;\n }\n\n /*\n function echidna_test() public view returns(bool) {\n return true;\n }\n */\n}\n" + }, + "contracts/TestContracts/ExternalPriceFeedTester.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Dependencies/PriceFeed/IExternalPriceFeed.sol\";\n\ninterface IMoCBaseOracle {\n function peek() external view returns (bytes32, bool);\n}\n\ncontract ExternalPriceFeedTester is IExternalPriceFeed {\n uint256 price;\n bool success;\n\n function setLatestAnswer(uint256 _price, bool _success) external {\n price = _price;\n success = _success;\n }\n\n function latestAnswer() external view override returns (uint256, bool) {\n return (price, success);\n }\n}\n" + }, + "contracts/TestContracts/FunctionCaller.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/ITroveManager.sol\";\nimport \"../Interfaces/ISortedTroves.sol\";\nimport \"../Interfaces/IPriceFeed.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\n\n/* Wrapper contract - used for calculating gas of read-only and internal functions. \nNot part of the Zero application. */\ncontract FunctionCaller {\n ITroveManager troveManager;\n address public troveManagerAddress;\n\n ISortedTroves sortedTroves;\n address public sortedTrovesAddress;\n\n IPriceFeed priceFeed;\n address public priceFeedAddress;\n\n // --- Dependency setters ---\n\n function setTroveManagerAddress(address _troveManagerAddress) external {\n troveManagerAddress = _troveManagerAddress;\n troveManager = ITroveManager(_troveManagerAddress);\n }\n\n function setSortedTrovesAddress(address _sortedTrovesAddress) external {\n troveManagerAddress = _sortedTrovesAddress;\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n }\n\n function setPriceFeedAddress(address _priceFeedAddress) external {\n priceFeedAddress = _priceFeedAddress;\n priceFeed = IPriceFeed(_priceFeedAddress);\n }\n\n // --- Non-view wrapper functions used for calculating gas ---\n\n function troveManager_getCurrentICR(address _address, uint256 _price)\n external\n returns (uint256)\n {\n return troveManager.getCurrentICR(_address, _price);\n }\n\n function sortedTroves_findInsertPosition(\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external returns (address, address) {\n return sortedTroves.findInsertPosition(_NICR, _prevId, _nextId);\n }\n}\n" + }, + "contracts/TestContracts/LiquityMathTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/LiquityMath.sol\";\n\n/* Tester contract for math functions in Math.sol library. */\n\ncontract LiquityMathTester {\n\n function callMax(uint _a, uint _b) external pure returns (uint) {\n return LiquityMath._max(_a, _b);\n }\n\n // Non-view wrapper for gas test\n function callDecPowTx(uint _base, uint _n) external returns (uint) {\n return LiquityMath._decPow(_base, _n);\n }\n\n // External wrapper\n function callDecPow(uint _base, uint _n) external pure returns (uint) {\n return LiquityMath._decPow(_base, _n);\n }\n}\n" + }, + "contracts/TestContracts/LiquitySafeMath128Tester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/LiquitySafeMath128.sol\";\n\n/* Tester contract for math functions in LiquitySafeMath128.sol library. */\n\ncontract LiquitySafeMath128Tester {\n using LiquitySafeMath128 for uint128;\n\n function add(uint128 a, uint128 b) external pure returns (uint128) {\n return a.add(b);\n }\n\n function sub(uint128 a, uint128 b) external pure returns (uint128) {\n return a.sub(b);\n }\n}\n" + }, + "contracts/TestContracts/MassetManagerTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { ERC20Permit } from \"@openzeppelin/contracts/drafts/ERC20Permit.sol\";\nimport \"../BorrowerOperationsStorage.sol\";\nimport \"hardhat/console.sol\";\n\n//TODO: rename NueMockToken to contract DLLRMockToken is ERC20(\"Sovryn Dollar\", \"DLLR\")\ncontract NueMockToken is ERC20(\"Nuestro\", \"NUE\"), ERC20Permit(\"Nuestro\"), Ownable {\n constructor() public {}\n\n function mint(address _account, uint256 _amount) public onlyOwner {\n _mint(_account, _amount);\n }\n\n function burn(address _account, uint256 _amount) public onlyOwner {\n _burn(_account, _amount);\n }\n\n function getChainId() external pure returns (uint256 chainID) {\n //return _chainID(); // it’s private\n assembly {\n chainID := chainid()\n }\n }\n\n function transferWithPermit(\n address _from,\n address _to,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external {\n permit(_from, msg.sender, _amount, _deadline, _v, _r, _s);\n transferFrom(_from, _to, _amount);\n }\n\n //TODO: add EIP-2612 Permit functionality\n}\n\ncontract MassetManagerTester is IMassetManager {\n NueMockToken public nueMockToken;\n\n constructor() public {\n nueMockToken = new NueMockToken();\n }\n\n function mintTo(\n address _bAsset,\n uint256 _bAssetQuantity,\n address _recipient\n ) external override returns (uint256) {\n IERC20(_bAsset).transferFrom(msg.sender, address(this), _bAssetQuantity);\n uint256 nueBalanceOfRecipientBeforeMint = nueMockToken.balanceOf(_recipient);\n nueMockToken.mint(_recipient, _bAssetQuantity);\n return nueMockToken.balanceOf(_recipient) - nueBalanceOfRecipientBeforeMint;\n }\n\n function getToken() external view override returns (address) {\n return address(nueMockToken);\n }\n\n /// @dev Transfer 'bAsset' to the recipient then burn the 'aggregator' nueMockToken\n function redeemTo(\n address _bAsset, //ZUSD nueMockToken\n uint256 _massetQuantity,\n address _recipient //user\n ) external override returns (uint256 massetRedeemed) {\n ERC20(_bAsset).transfer(_recipient, _massetQuantity);\n // nueMockToken.burn(_recipient, _massetQuantity); // _recipient used to be for the previous bridge-like implementation\n nueMockToken.burn(msg.sender, _massetQuantity);\n\n return _massetQuantity;\n }\n}\n" + }, + "contracts/TestContracts/MockFeeSharingCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/ZEROToken.sol\";\n\ninterface MockIFeeSharingCollector {\n\tfunction transferTokens(address _token, uint96 _amount) external;\n}\n\n/// @dev Simple contract that will receive ZERO tokens issued to the SOV stakers.\ncontract MockFeeSharingCollector is MockIFeeSharingCollector {\n\tfunction transferTokens(address _token, uint96 _amount) override external {\n\t\t/// Just a fake function to receive the tokens\n\t\tZEROToken(_token).transferFrom(msg.sender, address(this), _amount);\n\t}\n\n\tfunction transferRBTC() external payable {}\n}\n" + }, + "contracts/TestContracts/PriceFeedSovryn.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IPriceFeedSovryn.sol\";\nimport \"../Dependencies/SafeMath.sol\";\n\n/*\n* PriceFeed placeholder for testnet and development. The price is simply set manually and saved in a state \n* variable. The contract does not connect to a live Chainlink price feed. \n*/\ncontract PriceFeedSovryn {\n using SafeMath for uint256;\n\n mapping(address => mapping(address => uint256)) public prices;\n\n // --- Functions ---\n // Manual external price setter.\n function setPrice(address sourceToken, address destToken, uint256 price) external {\n prices[sourceToken][destToken] = price;\n }\n\n function queryRate(address sourceToken, address destToken) public view returns(uint256 rate, uint256 precision) {\n return (prices[sourceToken][destToken], 1e18);\n }\n\n function queryReturn(\n address sourceToken,\n address destToken,\n uint256 sourceAmount\n ) public view returns (uint256 destAmount) {\n (uint256 rate, uint256 precision) = queryRate(sourceToken, destToken);\n return sourceAmount.mul(rate).div(precision);\n }\n}\n" + }, + "contracts/TestContracts/PriceFeedTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../PriceFeed.sol\";\n\ncontract PriceFeedTester is PriceFeed {\n function setLastGoodPrice(uint256 _lastGoodPrice) external {\n lastGoodPrice = _lastGoodPrice;\n }\n}\n" + }, + "contracts/TestContracts/PriceFeedTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IPriceFeed.sol\";\n\n/*\n* PriceFeed placeholder for testnet and development. The price is simply set manually and saved in a state \n* variable. The contract does not connect to a live Chainlink price feed. \n*/\ncontract PriceFeedTestnet is IPriceFeed {\n \n uint256 private _price = 200 * 1e18;\n\n // --- Functions ---\n\n // View price getter for simplicity in tests\n function getPrice() external view returns (uint256) {\n return _price;\n }\n\n function fetchPrice() external override returns (uint256) {\n // Fire an event just like the mainnet version would.\n // This lets the subgraph rely on events to get the latest price even when developing locally.\n emit LastGoodPriceUpdated(_price);\n return _price;\n }\n\n // Manual external price setter.\n function setPrice(uint256 price) external returns (bool) {\n _price = price;\n return true;\n }\n}\n" + }, + "contracts/TestContracts/SortedTrovesTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/ISortedTroves.sol\";\n\n\ncontract SortedTrovesTester {\n ISortedTroves sortedTroves;\n\n function setSortedTroves(address _sortedTrovesAddress) external {\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n }\n\n function insert(address _id, uint256 _NICR, address _prevId, address _nextId) external {\n sortedTroves.insert(_id, _NICR, _prevId, _nextId);\n }\n\n function remove(address _id) external {\n sortedTroves.remove(_id);\n }\n\n function reInsert(address _id, uint256 _newNICR, address _prevId, address _nextId) external {\n sortedTroves.reInsert(_id, _newNICR, _prevId, _nextId);\n }\n\n function getNominalICR(address) external pure returns (uint) {\n return 1;\n }\n\n function getCurrentICR(address, uint) external pure returns (uint) {\n return 1;\n }\n}\n" + }, + "contracts/TestContracts/StabilityPoolTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../StabilityPool.sol\";\n\ncontract StabilityPoolTester is StabilityPool {\n \n function unprotectedPayable() external payable {\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/TestContracts/TroveManagerTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../TroveManager.sol\";\n\n/* Tester contract inherits from TroveManager, and provides external functions \nfor testing the parent's internal functions. */\n\ncontract TroveManagerTester is TroveManager(14 days) {\n function computeICR(uint _coll, uint _debt, uint _price) external pure returns (uint) {\n return LiquityMath._computeCR(_coll, _debt, _price);\n }\n\n function getCollGasCompensation(uint _coll) external view returns (uint) {\n return _getCollGasCompensation(_coll);\n }\n\n function getZUSDGasCompensation() external pure returns (uint) {\n return ZUSD_GAS_COMPENSATION;\n }\n\n function getCompositeDebt(uint _debt) external pure returns (uint) {\n return _getCompositeDebt(_debt);\n }\n\n function unprotectedDecayBaseRateFromBorrowing() external returns (uint) {\n baseRate = _calcDecayedBaseRate();\n assert(baseRate >= 0 && baseRate <= DECIMAL_PRECISION);\n\n _updateLastFeeOpTime();\n return baseRate;\n }\n\n function minutesPassedSinceLastFeeOp() external view returns (uint) {\n return _minutesPassedSinceLastFeeOp();\n }\n\n function setLastFeeOpTimeToNow() external {\n lastFeeOperationTime = block.timestamp;\n }\n\n function setBaseRate(uint _baseRate) external {\n baseRate = _baseRate;\n }\n\n function callGetRedemptionFee(uint _ETHDrawn) external view returns (uint) {\n _getRedemptionFee(_ETHDrawn);\n }\n\n function getActualDebtFromComposite(uint _debtVal) external pure returns (uint) {\n return _getNetDebt(_debtVal);\n }\n\n function callInternalRemoveTroveOwner(address _troveOwner) external {\n uint troveOwnersArrayLength = TroveOwners.length;\n _removeTroveOwner(_troveOwner, troveOwnersArrayLength);\n }\n}\n" + }, + "contracts/TestContracts/UpgradableProxyTester.sol": { + "content": "\n// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Proxy/UpgradableProxy.sol\";\ncontract Storage {\n uint someVar;\n}\n\ncontract ProxiableContract is Storage {\n\n function getSomeVar() public view returns (uint) {\n return someVar;\n }\n\n function setSomeVar(uint value) public {\n someVar = value;\n }\n}\n\ncontract Storage2 {\n uint anotherVar;\n}\n\ncontract ProxiableContract2 is ProxiableContract, Storage2 {\n\n function getAnotherVar() public view returns (uint) {\n return anotherVar;\n }\n\n function setAnotherVar(uint value) public {\n anotherVar = value;\n }\n\n function mulVars() public view returns (uint) {\n return someVar * anotherVar;\n }\n}\n\ncontract UpgradableProxyTester is UpgradableProxy, Storage {}\n" + }, + "contracts/TestContracts/ZEROStakingTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/ZEROStaking.sol\";\n\n\ncontract ZEROStakingTester is ZEROStaking {\n function requireCallerIsFeeDistributor() external view {\n _requireCallerIsFeeDistributor();\n }\n}\n" + }, + "contracts/TestContracts/ZEROTokenTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/ZEROToken.sol\";\n\ncontract ZEROTokenTester is ZEROToken {\n constructor\n (\n address _zeroStakingAddress,\n address _marketMakerAddress,\n address _presaleAddress\n ) \n public \n {\n initialize(\n _zeroStakingAddress,\n _marketMakerAddress,\n _presaleAddress\n );\n } \n\n function unprotectedMint(address account, uint256 amount) external {\n // No check for the caller here\n\n _mint(account, amount);\n }\n\n function unprotectedSendToZEROStaking(address _sender, uint256 _amount) external {\n // No check for the caller here\n \n _transfer(_sender, zeroStakingAddress, _amount);\n }\n\n function callInternalApprove(address owner, address spender, uint256 amount) external returns (bool) {\n _approve(owner, spender, amount);\n }\n\n function callInternalTransfer(address sender, address recipient, uint256 amount) external returns (bool) {\n _transfer(sender, recipient, amount);\n }\n\n function getChainId() external pure returns (uint256 chainID) {\n //return _chainID(); // it’s private\n assembly {\n chainID := chainid()\n }\n }\n}" + }, + "contracts/TestContracts/ZUSDTokenCaller.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IZUSDToken.sol\";\n\ncontract ZUSDTokenCaller {\n IZUSDToken ZUSD;\n\n function setZUSD(IZUSDToken _ZUSD) external {\n ZUSD = _ZUSD;\n }\n\n function zusdMint(address _account, uint _amount) external {\n ZUSD.mint(_account, _amount);\n }\n\n function zusdBurn(address _account, uint _amount) external {\n ZUSD.burn(_account, _amount);\n }\n\n function zusdSendToPool(address _sender, address _poolAddress, uint256 _amount) external {\n ZUSD.sendToPool(_sender, _poolAddress, _amount);\n }\n\n function zusdReturnFromPool(address _poolAddress, address _receiver, uint256 _amount ) external {\n ZUSD.returnFromPool(_poolAddress, _receiver, _amount);\n }\n}\n" + }, + "contracts/TestContracts/ZUSDTokenTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZUSDToken.sol\";\n\ncontract ZUSDTokenTester is ZUSDToken {\n \n constructor( \n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) public {\n initialize(_troveManagerAddress, _stabilityPoolAddress, _borrowerOperationsAddress);\n }\n \n function unprotectedMint(address _account, uint256 _amount) external {\n // No check on caller here\n\n _mint(_account, _amount);\n }\n\n function unprotectedBurn(address _account, uint _amount) external {\n // No check on caller here\n \n _burn(_account, _amount);\n }\n\n function unprotectedSendToPool(address _sender, address _poolAddress, uint256 _amount) external {\n // No check on caller here\n\n _transfer(_sender, _poolAddress, _amount);\n }\n\n function unprotectedReturnFromPool(address _poolAddress, address _receiver, uint256 _amount ) external {\n // No check on caller here\n\n _transfer(_poolAddress, _receiver, _amount);\n }\n\n function callInternalApprove(address owner, address spender, uint256 amount) external returns (bool) {\n _approve(owner, spender, amount);\n }\n\n function getChainId() external pure returns (uint256 chainID) {\n //return _chainID(); // it’s private\n assembly {\n chainID := chainid()\n }\n }\n\n function getDigest(address owner, address spender, uint amount, uint nonce, uint deadline) external view returns (bytes32) {\n return keccak256(abi.encodePacked(\n uint16(0x1901),\n domainSeparator(),\n keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, amount, nonce, deadline))\n )\n );\n }\n\n function recoverAddress(bytes32 digest, uint8 v, bytes32 r, bytes32 s) external pure returns (address) {\n return ecrecover(digest, v, r, s);\n }\n}\n" + }, + "contracts/TestContracts/ZUSDTokenTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IZUSDToken.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/console.sol\";\nimport \"../ZUSDToken.sol\";\n\n/**\n *\n * Based upon OpenZeppelin's ERC20 contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol\n *\n * and their EIP2612 (ERC20Permit / ERC712) functionality:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\n *\n *\n * --- Functionality added specific to the ZUSDToken ---\n *\n * 1) Transfer protection: blacklist of addresses that are invalid recipients (i.e. core Zero contracts) in external\n * transfer() and transferFrom() calls. The purpose is to protect users from losing tokens by mistakenly sending ZUSD directly to a Zero\n * core contract, when they should rather call the right function.\n *\n * 2) sendToPool() and returnFromPool(): functions callable only Zero core contracts, which move ZUSD tokens between Zero <-> user.\n */\n\n/// @dev ZUSDTokenTestnet has unptotected initialize function to bypass initializer() modifier validation\n/// @notice use if need to redeploy the token logic AND run initialize() again on the proxy\ncontract ZUSDTokenTestnet is ZUSDToken {\n function initialize(\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) public override onlyOwner {\n _initialize(_troveManagerAddress, _stabilityPoolAddress, _borrowerOperationsAddress);\n }\n}\n" + }, + "contracts/TroveManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROToken.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./Dependencies/TroveManagerBase.sol\";\nimport \"./TroveManagerStorage.sol\";\n\ncontract TroveManager is TroveManagerBase, CheckContract, ITroveManager {\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerRedeemOpsAddressChanged(address _troveManagerRedeemOps);\n event LiquityBaseParamsAddressChanges(address _borrowerOperationsAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZEROTokenAddressChanged(address _zeroTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n\n ///@param _bootstrapPeriod During bootsrap period redemptions are not allowed\n constructor(uint256 _bootstrapPeriod) public TroveManagerBase(_bootstrapPeriod) {}\n\n // --- Dependency setter ---\n function setAddresses(\n TroveManagerInitAddressesParams memory _troveManagerInitAddressesParams\n ) external override onlyOwner {\n {\n checkContract(_troveManagerInitAddressesParams._feeDistributorAddress);\n checkContract(_troveManagerInitAddressesParams._troveManagerRedeemOps);\n checkContract(_troveManagerInitAddressesParams._liquityBaseParamsAddress);\n checkContract(_troveManagerInitAddressesParams._borrowerOperationsAddress);\n checkContract(_troveManagerInitAddressesParams._activePoolAddress);\n checkContract(_troveManagerInitAddressesParams._defaultPoolAddress);\n checkContract(_troveManagerInitAddressesParams._stabilityPoolAddress);\n checkContract(_troveManagerInitAddressesParams._gasPoolAddress);\n checkContract(_troveManagerInitAddressesParams._collSurplusPoolAddress);\n checkContract(_troveManagerInitAddressesParams._priceFeedAddress);\n checkContract(_troveManagerInitAddressesParams._zusdTokenAddress);\n checkContract(_troveManagerInitAddressesParams._sortedTrovesAddress);\n checkContract(_troveManagerInitAddressesParams._zeroTokenAddress);\n checkContract(_troveManagerInitAddressesParams._zeroStakingAddress);\n }\n\n feeDistributor = IFeeDistributor(_troveManagerInitAddressesParams._feeDistributorAddress);\n troveManagerRedeemOps = _troveManagerInitAddressesParams._troveManagerRedeemOps;\n liquityBaseParams = ILiquityBaseParams(\n _troveManagerInitAddressesParams._liquityBaseParamsAddress\n );\n {\n borrowerOperationsAddress = _troveManagerInitAddressesParams\n ._borrowerOperationsAddress;\n activePool = IActivePool(_troveManagerInitAddressesParams._activePoolAddress);\n defaultPool = IDefaultPool(_troveManagerInitAddressesParams._defaultPoolAddress);\n _stabilityPool = IStabilityPool(\n _troveManagerInitAddressesParams._stabilityPoolAddress\n );\n gasPoolAddress = _troveManagerInitAddressesParams._gasPoolAddress;\n collSurplusPool = ICollSurplusPool(\n _troveManagerInitAddressesParams._collSurplusPoolAddress\n );\n priceFeed = IPriceFeed(_troveManagerInitAddressesParams._priceFeedAddress);\n _zusdToken = IZUSDToken(_troveManagerInitAddressesParams._zusdTokenAddress);\n sortedTroves = ISortedTroves(_troveManagerInitAddressesParams._sortedTrovesAddress);\n _zeroToken = IZEROToken(_troveManagerInitAddressesParams._zeroTokenAddress);\n _zeroStaking = IZEROStaking(_troveManagerInitAddressesParams._zeroStakingAddress);\n }\n\n emit FeeDistributorAddressChanged(_troveManagerInitAddressesParams._feeDistributorAddress);\n emit TroveManagerRedeemOpsAddressChanged(\n _troveManagerInitAddressesParams._troveManagerRedeemOps\n );\n emit LiquityBaseParamsAddressChanges(\n _troveManagerInitAddressesParams._borrowerOperationsAddress\n );\n emit BorrowerOperationsAddressChanged(\n _troveManagerInitAddressesParams._borrowerOperationsAddress\n );\n emit ActivePoolAddressChanged(_troveManagerInitAddressesParams._activePoolAddress);\n emit DefaultPoolAddressChanged(_troveManagerInitAddressesParams._defaultPoolAddress);\n emit StabilityPoolAddressChanged(_troveManagerInitAddressesParams._stabilityPoolAddress);\n emit GasPoolAddressChanged(_troveManagerInitAddressesParams._gasPoolAddress);\n emit CollSurplusPoolAddressChanged(\n _troveManagerInitAddressesParams._collSurplusPoolAddress\n );\n emit PriceFeedAddressChanged(_troveManagerInitAddressesParams._priceFeedAddress);\n emit ZUSDTokenAddressChanged(_troveManagerInitAddressesParams._zusdTokenAddress);\n emit SortedTrovesAddressChanged(_troveManagerInitAddressesParams._sortedTrovesAddress);\n emit ZEROTokenAddressChanged(_troveManagerInitAddressesParams._zeroTokenAddress);\n emit ZEROStakingAddressChanged(_troveManagerInitAddressesParams._zeroStakingAddress);\n }\n\n function setTroveManagerRedeemOps(address _troveManagerRedeemOps) external override onlyOwner {\n checkContract(_troveManagerRedeemOps);\n troveManagerRedeemOps = _troveManagerRedeemOps;\n emit TroveManagerRedeemOpsAddressChanged(_troveManagerRedeemOps);\n }\n\n // --- Getters ---\n\n function getTroveOwnersCount() external view override returns (uint256) {\n return TroveOwners.length;\n }\n\n function getTroveFromTroveOwnersArray(\n uint256 _index\n ) external view override returns (address) {\n return TroveOwners[_index];\n }\n\n // --- Trove Liquidation functions ---\n\n /// Single liquidation function. Closes the trove if its ICR is lower than the minimum collateral ratio.\n function liquidate(address _borrower) external override {\n _requireTroveIsActive(_borrower);\n\n address[] memory borrowers = new address[](1);\n borrowers[0] = _borrower;\n batchLiquidateTroves(borrowers);\n }\n\n // --- Inner single liquidation functions ---\n\n /// Liquidate one trove, in Normal Mode.\n function _liquidateNormalMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n address _borrower,\n uint256 _ZUSDInStabPool\n ) internal returns (LiquidationValues memory singleLiquidation) {\n LocalVariables_InnerSingleLiquidateFunction memory vars;\n\n (\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n vars.pendingDebtReward,\n vars.pendingCollReward\n ) = getEntireDebtAndColl(_borrower);\n\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n _removeStake(_borrower);\n\n singleLiquidation.collGasCompensation = _getCollGasCompensation(\n singleLiquidation.entireTroveColl\n );\n singleLiquidation.ZUSDGasCompensation = ZUSD_GAS_COMPENSATION;\n uint256 collToLiquidate = singleLiquidation.entireTroveColl.sub(\n singleLiquidation.collGasCompensation\n );\n\n (\n singleLiquidation.debtToOffset,\n singleLiquidation.collToSendToSP,\n singleLiquidation.debtToRedistribute,\n singleLiquidation.collToRedistribute\n ) = _getOffsetAndRedistributionVals(\n singleLiquidation.entireTroveDebt,\n collToLiquidate,\n _ZUSDInStabPool\n );\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n TroveManagerOperation.liquidateInNormalMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInNormalMode);\n return singleLiquidation;\n }\n\n /// Liquidate one trove, in Recovery Mode.\n function _liquidateRecoveryMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n address _borrower,\n uint256 _ICR,\n uint256 _ZUSDInStabPool,\n uint256 _TCR,\n uint256 _price\n ) internal returns (LiquidationValues memory singleLiquidation) {\n LocalVariables_InnerSingleLiquidateFunction memory vars;\n if (TroveOwners.length <= 1) {\n return singleLiquidation;\n } // don't liquidate if last trove\n (\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n vars.pendingDebtReward,\n vars.pendingCollReward\n ) = getEntireDebtAndColl(_borrower);\n\n singleLiquidation.collGasCompensation = _getCollGasCompensation(\n singleLiquidation.entireTroveColl\n );\n singleLiquidation.ZUSDGasCompensation = ZUSD_GAS_COMPENSATION;\n vars.collToLiquidate = singleLiquidation.entireTroveColl.sub(\n singleLiquidation.collGasCompensation\n );\n\n // If ICR <= 100%, purely redistribute the Trove across all active Troves\n if (_ICR <= _100pct) {\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n _removeStake(_borrower);\n\n singleLiquidation.debtToOffset = 0;\n singleLiquidation.collToSendToSP = 0;\n singleLiquidation.debtToRedistribute = singleLiquidation.entireTroveDebt;\n singleLiquidation.collToRedistribute = vars.collToLiquidate;\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n TroveManagerOperation.liquidateInRecoveryMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode);\n\n // If 100% < ICR < MCR, offset as much as possible, and redistribute the remainder\n } else if ((_ICR > _100pct) && (_ICR < liquityBaseParams.MCR())) {\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n _removeStake(_borrower);\n\n (\n singleLiquidation.debtToOffset,\n singleLiquidation.collToSendToSP,\n singleLiquidation.debtToRedistribute,\n singleLiquidation.collToRedistribute\n ) = _getOffsetAndRedistributionVals(\n singleLiquidation.entireTroveDebt,\n vars.collToLiquidate,\n _ZUSDInStabPool\n );\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n TroveManagerOperation.liquidateInRecoveryMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode);\n /*\n * If 110% <= ICR < current TCR (accounting for the preceding liquidations in the current sequence)\n * and there is ZUSD in the Stability Pool, only offset, with no redistribution,\n * but at a capped rate of 1.1 and only if the whole debt can be liquidated.\n * The remainder due to the capped rate will be claimable as collateral surplus.\n */\n } else if (\n (_ICR >= liquityBaseParams.MCR()) &&\n (_ICR < _TCR) &&\n (singleLiquidation.entireTroveDebt <= _ZUSDInStabPool)\n ) {\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n assert(_ZUSDInStabPool != 0);\n\n _removeStake(_borrower);\n singleLiquidation = _getCappedOffsetVals(\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n _price\n );\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n if (singleLiquidation.collSurplus > 0) {\n collSurplusPool.accountSurplus(_borrower, singleLiquidation.collSurplus);\n }\n\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.collToSendToSP,\n TroveManagerOperation.liquidateInRecoveryMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode);\n } else {\n // if (_ICR >= liquityBaseParams.MCR() && ( _ICR >= _TCR || singleLiquidation.entireTroveDebt > _ZUSDInStabPool))\n LiquidationValues memory zeroVals;\n return zeroVals;\n }\n\n return singleLiquidation;\n }\n\n /** In a full liquidation, returns the values for a trove's coll and debt to be offset, and coll and debt to be\n * redistributed to active troves.\n */\n function _getOffsetAndRedistributionVals(\n uint256 _debt,\n uint256 _coll,\n uint256 _ZUSDInStabPool\n )\n internal\n pure\n returns (\n uint256 debtToOffset,\n uint256 collToSendToSP,\n uint256 debtToRedistribute,\n uint256 collToRedistribute\n )\n {\n if (_ZUSDInStabPool > 0) {\n /*\n * Offset as much debt & collateral as possible against the Stability Pool, and redistribute the remainder\n * between all active troves.\n *\n * If the trove's debt is larger than the deposited ZUSD in the Stability Pool:\n *\n * - Offset an amount of the trove's debt equal to the ZUSD in the Stability Pool\n * - Send a fraction of the trove's collateral to the Stability Pool, equal to the fraction of its offset debt\n *\n */\n debtToOffset = LiquityMath._min(_debt, _ZUSDInStabPool);\n collToSendToSP = _coll.mul(debtToOffset).div(_debt);\n debtToRedistribute = _debt.sub(debtToOffset);\n collToRedistribute = _coll.sub(collToSendToSP);\n } else {\n debtToOffset = 0;\n collToSendToSP = 0;\n debtToRedistribute = _debt;\n collToRedistribute = _coll;\n }\n }\n\n /**\n * Get its offset coll/debt and ETH gas comp, and close the trove.\n */\n function _getCappedOffsetVals(\n uint256 _entireTroveDebt,\n uint256 _entireTroveColl,\n uint256 _price\n ) internal view returns (LiquidationValues memory singleLiquidation) {\n singleLiquidation.entireTroveDebt = _entireTroveDebt;\n singleLiquidation.entireTroveColl = _entireTroveColl;\n uint256 collToOffset = _entireTroveDebt.mul(liquityBaseParams.MCR()).div(_price);\n\n singleLiquidation.collGasCompensation = _getCollGasCompensation(collToOffset);\n singleLiquidation.ZUSDGasCompensation = ZUSD_GAS_COMPENSATION;\n\n singleLiquidation.debtToOffset = _entireTroveDebt;\n singleLiquidation.collToSendToSP = collToOffset.sub(singleLiquidation.collGasCompensation);\n singleLiquidation.collSurplus = _entireTroveColl.sub(collToOffset);\n singleLiquidation.debtToRedistribute = 0;\n singleLiquidation.collToRedistribute = 0;\n }\n\n /**\n * Liquidate a sequence of troves. Closes a maximum number of n under-collateralized Troves,\n * starting from the one with the lowest collateral ratio in the system, and moving upwards\n */\n function liquidateTroves(uint256 _n) external override {\n ContractsCache memory contractsCache = ContractsCache(\n activePool,\n defaultPool,\n IZUSDToken(address(0)),\n IZEROStaking(address(0)),\n sortedTroves,\n ICollSurplusPool(address(0)),\n address(0)\n );\n IStabilityPool stabilityPoolCached = _stabilityPool;\n\n LocalVariables_OuterLiquidationFunction memory vars;\n\n LiquidationTotals memory totals;\n\n vars.price = priceFeed.fetchPrice();\n vars.ZUSDInStabPool = stabilityPoolCached.getTotalZUSDDeposits();\n vars.recoveryModeAtStart = _checkRecoveryMode(vars.price);\n\n // Perform the appropriate liquidation sequence - tally the values, and obtain their totals\n if (vars.recoveryModeAtStart) {\n totals = _getTotalsFromLiquidateTrovesSequence_RecoveryMode(\n contractsCache,\n vars.price,\n vars.ZUSDInStabPool,\n _n\n );\n } else {\n // if !vars.recoveryModeAtStart\n totals = _getTotalsFromLiquidateTrovesSequence_NormalMode(\n contractsCache.activePool,\n contractsCache.defaultPool,\n vars.price,\n vars.ZUSDInStabPool,\n _n\n );\n }\n\n require(totals.totalDebtInSequence > 0, \"TroveManager: nothing to liquidate\");\n\n // Move liquidated ETH and ZUSD to the appropriate pools\n stabilityPoolCached.offset(totals.totalDebtToOffset, totals.totalCollToSendToSP);\n _redistributeDebtAndColl(\n contractsCache.activePool,\n contractsCache.defaultPool,\n totals.totalDebtToRedistribute,\n totals.totalCollToRedistribute\n );\n if (totals.totalCollSurplus > 0) {\n contractsCache.activePool.sendETH(address(collSurplusPool), totals.totalCollSurplus);\n }\n\n // Update system snapshots\n _updateSystemSnapshots_excludeCollRemainder(\n contractsCache.activePool,\n totals.totalCollGasCompensation\n );\n\n vars.liquidatedDebt = totals.totalDebtInSequence;\n vars.liquidatedColl = totals.totalCollInSequence.sub(totals.totalCollGasCompensation).sub(\n totals.totalCollSurplus\n );\n emit Liquidation(\n vars.liquidatedDebt,\n vars.liquidatedColl,\n totals.totalCollGasCompensation,\n totals.totalZUSDGasCompensation\n );\n\n // Send gas compensation to caller\n _sendGasCompensation(\n contractsCache.activePool,\n msg.sender,\n totals.totalZUSDGasCompensation,\n totals.totalCollGasCompensation\n );\n }\n\n /**\n * This function is used when the liquidateTroves sequence starts during Recovery Mode. However, it\n * handle the case where the system *leaves* Recovery Mode, part way through the liquidation sequence\n */\n function _getTotalsFromLiquidateTrovesSequence_RecoveryMode(\n ContractsCache memory _contractsCache,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n uint256 _n\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n vars.backToNormalMode = false;\n vars.entireSystemDebt = getEntireSystemDebt();\n vars.entireSystemColl = getEntireSystemColl();\n\n vars.user = _contractsCache.sortedTroves.getLast();\n address firstUser = _contractsCache.sortedTroves.getFirst();\n for (vars.i = 0; vars.i < _n && vars.user != firstUser; vars.i++) {\n // we need to cache it, because current user is likely going to be deleted\n address nextUser = _contractsCache.sortedTroves.getPrev(vars.user);\n\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (!vars.backToNormalMode) {\n // Break the loop if ICR is greater than liquityBaseParams.MCR() and Stability Pool is empty\n if (vars.ICR >= liquityBaseParams.MCR() && vars.remainingZUSDInStabPool == 0) {\n break;\n }\n\n uint256 TCR = LiquityMath._computeCR(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n\n singleLiquidation = _liquidateRecoveryMode(\n _contractsCache.activePool,\n _contractsCache.defaultPool,\n vars.user,\n vars.ICR,\n vars.remainingZUSDInStabPool,\n TCR,\n _price\n );\n\n // Update aggregate trackers\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n vars.entireSystemDebt = vars.entireSystemDebt.sub(singleLiquidation.debtToOffset);\n vars.entireSystemColl = vars\n .entireSystemColl\n .sub(singleLiquidation.collToSendToSP)\n .sub(singleLiquidation.collSurplus);\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n\n vars.backToNormalMode = !_checkPotentialRecoveryMode(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n } else if (vars.backToNormalMode && vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _contractsCache.activePool,\n _contractsCache.defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n } else break; // break if the loop reaches a Trove with ICR >= MCR\n\n vars.user = nextUser;\n }\n }\n\n function _getTotalsFromLiquidateTrovesSequence_NormalMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n uint256 _n\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n ISortedTroves sortedTrovesCached = sortedTroves;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n\n for (vars.i = 0; vars.i < _n; vars.i++) {\n vars.user = sortedTrovesCached.getLast();\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n } else break; // break if the loop reaches a Trove with ICR >= MCR\n }\n }\n\n /**\n * Attempt to liquidate a custom list of troves provided by the caller.\n */\n function batchLiquidateTroves(address[] memory _troveArray) public override {\n require(_troveArray.length != 0, \"TroveManager: Calldata address array must not be empty\");\n\n IActivePool activePoolCached = activePool;\n IDefaultPool defaultPoolCached = defaultPool;\n IStabilityPool stabilityPoolCached = _stabilityPool;\n\n LocalVariables_OuterLiquidationFunction memory vars;\n LiquidationTotals memory totals;\n\n vars.price = priceFeed.fetchPrice();\n vars.ZUSDInStabPool = stabilityPoolCached.getTotalZUSDDeposits();\n vars.recoveryModeAtStart = _checkRecoveryMode(vars.price);\n\n // Perform the appropriate liquidation sequence - tally values and obtain their totals.\n if (vars.recoveryModeAtStart) {\n totals = _getTotalFromBatchLiquidate_RecoveryMode(\n activePoolCached,\n defaultPoolCached,\n vars.price,\n vars.ZUSDInStabPool,\n _troveArray\n );\n } else {\n // if !vars.recoveryModeAtStart\n totals = _getTotalsFromBatchLiquidate_NormalMode(\n activePoolCached,\n defaultPoolCached,\n vars.price,\n vars.ZUSDInStabPool,\n _troveArray\n );\n }\n\n require(totals.totalDebtInSequence > 0, \"TroveManager: nothing to liquidate\");\n\n // Move liquidated ETH and ZUSD to the appropriate pools\n stabilityPoolCached.offset(totals.totalDebtToOffset, totals.totalCollToSendToSP);\n _redistributeDebtAndColl(\n activePoolCached,\n defaultPoolCached,\n totals.totalDebtToRedistribute,\n totals.totalCollToRedistribute\n );\n if (totals.totalCollSurplus > 0) {\n activePoolCached.sendETH(address(collSurplusPool), totals.totalCollSurplus);\n }\n\n // Update system snapshots\n _updateSystemSnapshots_excludeCollRemainder(\n activePoolCached,\n totals.totalCollGasCompensation\n );\n\n vars.liquidatedDebt = totals.totalDebtInSequence;\n vars.liquidatedColl = totals.totalCollInSequence.sub(totals.totalCollGasCompensation).sub(\n totals.totalCollSurplus\n );\n emit Liquidation(\n vars.liquidatedDebt,\n vars.liquidatedColl,\n totals.totalCollGasCompensation,\n totals.totalZUSDGasCompensation\n );\n\n // Send gas compensation to caller\n _sendGasCompensation(\n activePoolCached,\n msg.sender,\n totals.totalZUSDGasCompensation,\n totals.totalCollGasCompensation\n );\n }\n\n /**\n * This function is used when the batch liquidation sequence starts during Recovery Mode. However, it\n * handle the case where the system *leaves* Recovery Mode, part way through the liquidation sequence\n */\n function _getTotalFromBatchLiquidate_RecoveryMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n address[] memory _troveArray\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n vars.backToNormalMode = false;\n vars.entireSystemDebt = getEntireSystemDebt();\n vars.entireSystemColl = getEntireSystemColl();\n\n for (vars.i = 0; vars.i < _troveArray.length; vars.i++) {\n vars.user = _troveArray[vars.i];\n // Skip non-active troves\n if (Troves[vars.user].status != Status.active) {\n continue;\n }\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (!vars.backToNormalMode) {\n // Skip this trove if ICR is greater than liquityBaseParams.MCR() and Stability Pool is empty\n if (vars.ICR >= liquityBaseParams.MCR() && vars.remainingZUSDInStabPool == 0) {\n continue;\n }\n\n uint256 TCR = LiquityMath._computeCR(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n\n singleLiquidation = _liquidateRecoveryMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.ICR,\n vars.remainingZUSDInStabPool,\n TCR,\n _price\n );\n\n // Update aggregate trackers\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n vars.entireSystemDebt = vars.entireSystemDebt.sub(singleLiquidation.debtToOffset);\n vars.entireSystemColl = vars.entireSystemColl.sub(\n singleLiquidation.collToSendToSP\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n\n vars.backToNormalMode = !_checkPotentialRecoveryMode(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n } else if (vars.backToNormalMode && vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n } else continue; // In Normal Mode skip troves with ICR >= MCR\n }\n }\n\n function _getTotalsFromBatchLiquidate_NormalMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n address[] memory _troveArray\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n\n for (vars.i = 0; vars.i < _troveArray.length; vars.i++) {\n vars.user = _troveArray[vars.i];\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n }\n }\n }\n\n // --- Liquidation helper functions ---\n\n function _addLiquidationValuesToTotals(\n LiquidationTotals memory oldTotals,\n LiquidationValues memory singleLiquidation\n ) internal pure returns (LiquidationTotals memory newTotals) {\n // Tally all the values with their respective running totals\n newTotals.totalCollGasCompensation = oldTotals.totalCollGasCompensation.add(\n singleLiquidation.collGasCompensation\n );\n newTotals.totalZUSDGasCompensation = oldTotals.totalZUSDGasCompensation.add(\n singleLiquidation.ZUSDGasCompensation\n );\n newTotals.totalDebtInSequence = oldTotals.totalDebtInSequence.add(\n singleLiquidation.entireTroveDebt\n );\n newTotals.totalCollInSequence = oldTotals.totalCollInSequence.add(\n singleLiquidation.entireTroveColl\n );\n newTotals.totalDebtToOffset = oldTotals.totalDebtToOffset.add(\n singleLiquidation.debtToOffset\n );\n newTotals.totalCollToSendToSP = oldTotals.totalCollToSendToSP.add(\n singleLiquidation.collToSendToSP\n );\n newTotals.totalDebtToRedistribute = oldTotals.totalDebtToRedistribute.add(\n singleLiquidation.debtToRedistribute\n );\n newTotals.totalCollToRedistribute = oldTotals.totalCollToRedistribute.add(\n singleLiquidation.collToRedistribute\n );\n newTotals.totalCollSurplus = oldTotals.totalCollSurplus.add(singleLiquidation.collSurplus);\n\n return newTotals;\n }\n\n function _sendGasCompensation(\n IActivePool _activePool,\n address _liquidator,\n uint256 _ZUSD,\n uint256 _ETH\n ) internal {\n if (_ZUSD > 0) {\n _zusdToken.returnFromPool(gasPoolAddress, _liquidator, _ZUSD);\n }\n\n if (_ETH > 0) {\n _activePool.sendETH(_liquidator, _ETH);\n }\n }\n\n // --- Helper functions ---\n\n /// @return the nominal collateral ratio (ICR) of a given Trove, without the price. Takes a trove's pending coll and debt rewards from redistributions into account.\n function getNominalICR(address _borrower) public view override returns (uint256) {\n (uint256 currentETH, uint256 currentZUSDDebt) = _getCurrentTroveAmounts(_borrower);\n\n uint256 NICR = LiquityMath._computeNominalCR(currentETH, currentZUSDDebt);\n return NICR;\n }\n\n function applyPendingRewards(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _applyPendingRewards(activePool, defaultPool, _borrower);\n }\n\n /// Update borrower's snapshots of L_ETH and L_ZUSDDebt to reflect the current values\n function updateTroveRewardSnapshots(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _updateTroveRewardSnapshots(_borrower);\n }\n\n /// Return the Troves entire debt and coll, including pending rewards from redistributions.\n function getEntireDebtAndColl(\n address _borrower\n )\n public\n view\n override\n returns (\n uint256 debt,\n uint256 coll,\n uint256 pendingZUSDDebtReward,\n uint256 pendingETHReward\n )\n {\n debt = Troves[_borrower].debt;\n coll = Troves[_borrower].coll;\n\n pendingZUSDDebtReward = getPendingZUSDDebtReward(_borrower);\n pendingETHReward = getPendingETHReward(_borrower);\n\n debt = debt.add(pendingZUSDDebtReward);\n coll = coll.add(pendingETHReward);\n }\n\n function removeStake(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _removeStake(_borrower);\n }\n\n function updateStakeAndTotalStakes(address _borrower) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n return _updateStakeAndTotalStakes(_borrower);\n }\n\n function _redistributeDebtAndColl(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _debt,\n uint256 _coll\n ) internal {\n if (_debt == 0) {\n return;\n }\n\n /*\n * Add distributed coll and debt rewards-per-unit-staked to the running totals. Division uses a \"feedback\"\n * error correction, to keep the cumulative error low in the running totals L_ETH and L_ZUSDDebt:\n *\n * 1) Form numerators which compensate for the floor division errors that occurred the last time this\n * function was called.\n * 2) Calculate \"per-unit-staked\" ratios.\n * 3) Multiply each ratio back by its denominator, to reveal the current floor division error.\n * 4) Store these errors for use in the next correction when this function is called.\n * 5) Note: static analysis tools complain about this \"division before multiplication\", however, it is intended.\n */\n uint256 ETHNumerator = _coll.mul(DECIMAL_PRECISION).add(lastETHError_Redistribution);\n uint256 ZUSDDebtNumerator = _debt.mul(DECIMAL_PRECISION).add(\n lastZUSDDebtError_Redistribution\n );\n\n // Get the per-unit-staked terms\n uint256 ETHRewardPerUnitStaked = ETHNumerator.div(totalStakes);\n uint256 ZUSDDebtRewardPerUnitStaked = ZUSDDebtNumerator.div(totalStakes);\n\n lastETHError_Redistribution = ETHNumerator.sub(ETHRewardPerUnitStaked.mul(totalStakes));\n lastZUSDDebtError_Redistribution = ZUSDDebtNumerator.sub(\n ZUSDDebtRewardPerUnitStaked.mul(totalStakes)\n );\n\n // Add per-unit-staked terms to the running totals\n L_ETH = L_ETH.add(ETHRewardPerUnitStaked);\n L_ZUSDDebt = L_ZUSDDebt.add(ZUSDDebtRewardPerUnitStaked);\n\n emit LTermsUpdated(L_ETH, L_ZUSDDebt);\n\n // Transfer coll and debt from ActivePool to DefaultPool\n _activePool.decreaseZUSDDebt(_debt);\n _defaultPool.increaseZUSDDebt(_debt);\n _activePool.sendETH(address(_defaultPool), _coll);\n }\n\n function closeTrove(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _closeTrove(_borrower, Status.closedByOwner);\n }\n\n /**\n * Updates snapshots of system total stakes and total collateral, excluding a given collateral remainder from the calculation.\n * Used in a liquidation sequence.\n *\n * The calculation excludes a portion of collateral that is in the ActivePool:\n *\n * the total ETH gas compensation from the liquidation sequence\n *\n * The ETH as compensation must be excluded as it is always sent out at the very end of the liquidation sequence.\n */\n function _updateSystemSnapshots_excludeCollRemainder(\n IActivePool _activePool,\n uint256 _collRemainder\n ) internal {\n totalStakesSnapshot = totalStakes;\n\n uint256 activeColl = _activePool.getETH();\n uint256 liquidatedColl = defaultPool.getETH();\n totalCollateralSnapshot = activeColl.sub(_collRemainder).add(liquidatedColl);\n\n emit SystemSnapshotsUpdated(totalStakesSnapshot, totalCollateralSnapshot);\n }\n\n /// Push the owner's address to the Trove owners list, and record the corresponding array index on the Trove struct\n function addTroveOwnerToArray(address _borrower) external override returns (uint256 index) {\n _requireCallerIsBorrowerOperations();\n return _addTroveOwnerToArray(_borrower);\n }\n\n function _addTroveOwnerToArray(address _borrower) internal returns (uint128 index) {\n /* Max array size is 2**128 - 1, i.e. ~3e30 troves. No risk of overflow, since troves have minimum ZUSD\n debt of liquidation reserve plus MIN_NET_DEBT. 3e30 ZUSD dwarfs the value of all wealth in the world ( which is < 1e15 USD). */\n\n // Push the Troveowner to the array\n TroveOwners.push(_borrower);\n\n // Record the index of the new Troveowner on their Trove struct\n index = uint128(TroveOwners.length.sub(1));\n Troves[_borrower].arrayIndex = index;\n\n return index;\n }\n\n // --- Recovery Mode and TCR functions ---\n\n function getTCR(uint256 _price) external view override returns (uint256) {\n return _getTCR(_price);\n }\n\n function MCR() external view override returns (uint256) {\n return liquityBaseParams.MCR();\n }\n\n function CCR() external view override returns (uint256) {\n return liquityBaseParams.CCR();\n }\n\n function checkRecoveryMode(uint256 _price) external view override returns (bool) {\n return _checkRecoveryMode(_price);\n }\n\n // Check whether or not the system *would be* in Recovery Mode, given an ETH:USD price, and the entire system coll and debt.\n function _checkPotentialRecoveryMode(\n uint256 _entireSystemColl,\n uint256 _entireSystemDebt,\n uint256 _price\n ) internal view returns (bool) {\n uint256 TCR = LiquityMath._computeCR(_entireSystemColl, _entireSystemDebt, _price);\n\n return TCR < liquityBaseParams.CCR();\n }\n\n function getRedemptionRateWithDecay() public view override returns (uint256) {\n return _calcRedemptionRate(_calcDecayedBaseRate());\n }\n\n function getRedemptionFeeWithDecay(\n uint256 _ETHDrawn\n ) external view override returns (uint256) {\n return _calcRedemptionFee(getRedemptionRateWithDecay(), _ETHDrawn);\n }\n\n // --- Borrowing fee functions ---\n\n function getBorrowingRate() public view override returns (uint256) {\n return _calcBorrowingRate(baseRate);\n }\n\n function getBorrowingRateWithDecay() public view override returns (uint256) {\n return _calcBorrowingRate(_calcDecayedBaseRate());\n }\n\n function _calcBorrowingRate(uint256 _baseRate) internal view returns (uint256) {\n return\n LiquityMath._min(\n liquityBaseParams.BORROWING_FEE_FLOOR().add(_baseRate),\n liquityBaseParams.MAX_BORROWING_FEE()\n );\n }\n\n function getBorrowingFee(uint256 _ZUSDDebt) external view override returns (uint256) {\n return _calcBorrowingFee(getBorrowingRate(), _ZUSDDebt);\n }\n\n function getBorrowingFeeWithDecay(uint256 _ZUSDDebt) external view override returns (uint256) {\n return _calcBorrowingFee(getBorrowingRateWithDecay(), _ZUSDDebt);\n }\n\n function _calcBorrowingFee(\n uint256 _borrowingRate,\n uint256 _ZUSDDebt\n ) internal pure returns (uint256) {\n return _borrowingRate.mul(_ZUSDDebt).div(DECIMAL_PRECISION);\n }\n\n /// Updates the baseRate state variable based on time elapsed since the last redemption or ZUSD borrowing operation.\n function decayBaseRateFromBorrowing() external override {\n _requireCallerIsBorrowerOperations();\n\n uint256 decayedBaseRate = _calcDecayedBaseRate();\n assert(decayedBaseRate <= DECIMAL_PRECISION); // The baseRate can decay to 0\n\n baseRate = decayedBaseRate;\n emit BaseRateUpdated(decayedBaseRate);\n\n _updateLastFeeOpTime();\n }\n\n // --- Internal fee functions ---\n\n // --- Trove property getters ---\n\n function getTroveStatus(address _borrower) external view override returns (uint256) {\n return uint256(Troves[_borrower].status);\n }\n\n function getTroveStake(address _borrower) external view override returns (uint256) {\n return Troves[_borrower].stake;\n }\n\n function getTroveDebt(address _borrower) external view override returns (uint256) {\n return Troves[_borrower].debt;\n }\n\n function getTroveColl(address _borrower) external view override returns (uint256) {\n return Troves[_borrower].coll;\n }\n\n // --- Trove property setters, called by BorrowerOperations ---\n\n function setTroveStatus(address _borrower, uint256 _num) external override {\n _requireCallerIsBorrowerOperations();\n Troves[_borrower].status = Status(_num);\n }\n\n function increaseTroveColl(\n address _borrower,\n uint256 _collIncrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newColl = Troves[_borrower].coll.add(_collIncrease);\n Troves[_borrower].coll = newColl;\n return newColl;\n }\n\n function decreaseTroveColl(\n address _borrower,\n uint256 _collDecrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newColl = Troves[_borrower].coll.sub(_collDecrease);\n Troves[_borrower].coll = newColl;\n return newColl;\n }\n\n function increaseTroveDebt(\n address _borrower,\n uint256 _debtIncrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newDebt = Troves[_borrower].debt.add(_debtIncrease);\n Troves[_borrower].debt = newDebt;\n return newDebt;\n }\n\n function decreaseTroveDebt(\n address _borrower,\n uint256 _debtDecrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newDebt = Troves[_borrower].debt.sub(_debtDecrease);\n Troves[_borrower].debt = newDebt;\n return newDebt;\n }\n\n function getCurrentICR(\n address _borrower,\n uint256 _price\n ) external view override returns (uint256) {\n return _getCurrentICR(_borrower, _price);\n }\n\n function getPendingETHReward(address _borrower) public view override returns (uint256) {\n return _getPendingETHReward(_borrower);\n }\n\n function getPendingZUSDDebtReward(address _borrower) public view override returns (uint256) {\n return _getPendingZUSDDebtReward(_borrower);\n }\n\n function hasPendingRewards(address _borrower) public view override returns (bool) {\n return _hasPendingRewards(_borrower);\n }\n\n function getRedemptionRate() public view override returns (uint256) {\n return _getRedemptionRate();\n }\n\n /// @dev this function forwards the call to the troveManagerRedeemOps in a delegate call fashion\n /// so the parameters are not needed\n function redeemCollateral(\n uint256 _ZUSDamount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage\n ) external override {\n (bool success, bytes memory returndata) = troveManagerRedeemOps.delegatecall(msg.data);\n require(success, string(returndata));\n }\n\n /// @dev this function forwards the call to the troveManagerRedeemOps in a delegate call fashion\n /// so the parameters are not needed\n ///DLLR _owner or _spender can use Sovryn Mynt to convert DLLR to ZUSD, then use the Zero redemption mechanism to redeem ZUSD for RBTC, all in a single transaction\n function redeemCollateralViaDLLR(\n uint256 _dllrAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage,\n IMassetManager.PermitParams calldata _permitParams\n ) external override {\n (bool success, bytes memory returndata) = troveManagerRedeemOps.delegatecall(msg.data);\n require(success, string(returndata));\n }\n}\n" + }, + "contracts/TroveManagerStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROToken.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/BaseMath.sol\";\nimport \"./Dependencies/console.sol\";\n\ncontract TroveManagerStorage is Ownable, BaseMath {\n string public constant NAME = \"TroveManager\";\n\n // --- Connected contract declarations ---\n\n address public troveManagerRedeemOps;\n\n address public borrowerOperationsAddress;\n\n IStabilityPool public _stabilityPool;\n\n address gasPoolAddress;\n\n ICollSurplusPool collSurplusPool;\n\n IZUSDToken public _zusdToken;\n\n IZEROToken public _zeroToken;\n\n IZEROStaking public _zeroStaking;\n\n IFeeDistributor public feeDistributor;\n\n // A doubly linked list of Troves, sorted by their sorted by their collateral ratios\n ISortedTroves public sortedTroves;\n\n // --- Data structures ---\n\n uint256 public baseRate;\n\n // The timestamp of the latest fee operation (redemption or new ZUSD issuance)\n uint256 public lastFeeOperationTime;\n\n enum Status {\n nonExistent,\n active,\n closedByOwner,\n closedByLiquidation,\n closedByRedemption\n }\n\n // Store the necessary data for a trove\n struct Trove {\n uint256 debt;\n uint256 coll;\n uint256 stake;\n Status status;\n uint128 arrayIndex;\n }\n\n mapping(address => Trove) public Troves;\n\n uint256 public totalStakes;\n\n // Snapshot of the value of totalStakes, taken immediately after the latest liquidation\n uint256 public totalStakesSnapshot;\n\n // Snapshot of the total collateral across the ActivePool and DefaultPool, immediately after the latest liquidation.\n uint256 public totalCollateralSnapshot;\n\n /*\n * L_ETH and L_ZUSDDebt track the sums of accumulated liquidation rewards per unit staked. During its lifetime, each stake earns:\n *\n * An ETH gain of ( stake * [L_ETH - L_ETH(0)] )\n * A ZUSDDebt increase of ( stake * [L_ZUSDDebt - L_ZUSDDebt(0)] )\n *\n * Where L_ETH(0) and L_ZUSDDebt(0) are snapshots of L_ETH and L_ZUSDDebt for the active Trove taken at the instant the stake was made\n */\n uint256 public L_ETH;\n uint256 public L_ZUSDDebt;\n\n // Map addresses with active troves to their RewardSnapshot\n mapping(address => RewardSnapshot) public rewardSnapshots;\n\n // Object containing the ETH and ZUSD snapshots for a given active trove\n struct RewardSnapshot {\n uint256 ETH;\n uint256 ZUSDDebt;\n }\n\n // Array of all active trove addresses - used to to compute an approximate hint off-chain, for the sorted list insertion\n address[] public TroveOwners;\n\n // Error trackers for the trove redistribution calculation\n uint256 public lastETHError_Redistribution;\n uint256 public lastZUSDDebtError_Redistribution;\n}\n" + }, + "contracts/ZERO/CommunityIssuance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Interfaces/ICommunityIssuance.sol\";\nimport \"../Interfaces/IStabilityPool.sol\";\nimport \"../Dependencies/BaseMath.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"./CommunityIssuanceStorage.sol\";\n\ncontract CommunityIssuance is\n CommunityIssuanceStorage,\n CheckContract,\n BaseMath\n{\n using SafeMath for uint256;\n\n // --- Events ---\n\n event SOVTokenAddressSet(address _sovTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event StabilityPoolAddressSet(address _stabilityPoolAddress);\n event PriceFeedAddressSet(address _priceFeed);\n event RewardManagerAddressSet(address _rewardManagerAddress);\n event TotalSOVIssuedUpdated(uint256 _latestSOVIssued);\n event APRSet(uint256 _APR);\n\n // --- Modifier ---\n modifier onlyRewardManager() {\n require(msg.sender == rewardManager, \"Permission::rewardManager: access denied\");\n _;\n }\n\n // --- Functions ---\n\n /**\n * @dev initialization function to set configs.\n * can only be initialized by owner.\n * @param _sovTokenAddress sov token address.\n * @param _zusdTokenAddress zero token address.\n * @param _stabilityPoolAddress stability pool address.\n * @param _priceFeed price feed address.\n * @param _APR apr in basis points.\n */\n function initialize(\n address _sovTokenAddress,\n address _zusdTokenAddress,\n address _stabilityPoolAddress,\n address _priceFeed,\n uint256 _APR\n ) external initializer onlyOwner {\n checkContract(_sovTokenAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_priceFeed);\n\n _validateAPR(_APR);\n\n sovToken = IERC20(_sovTokenAddress);\n zusdToken = IERC20(_zusdTokenAddress);\n stabilityPoolAddress = _stabilityPoolAddress;\n priceFeed = IPriceFeedSovryn(_priceFeed);\n APR = _APR;\n lastIssuanceTime = block.timestamp;\n\n emit SOVTokenAddressSet(_sovTokenAddress);\n emit StabilityPoolAddressSet(_stabilityPoolAddress);\n emit PriceFeedAddressSet(_priceFeed);\n emit APRSet(_APR);\n }\n\n /**\n * @dev setter function to set the APR value in basis points.\n * can only be called by reward manager.\n * @param _APR apr value in basis points.\n */\n function setAPR(uint256 _APR) external onlyRewardManager {\n _validateAPR(_APR);\n\n // We need to trigger issueSOV function before set the new APR\n // because otherwise, we will change the APR retrospectively for the time passed since last issuance.\n uint256 _totalZUSDDeposits = IStabilityPool(stabilityPoolAddress).getTotalZUSDDeposits();\n _issueSOV(_totalZUSDDeposits);\n\n APR = _APR;\n\n emit APRSet(_APR);\n }\n\n /**\n * @dev setter function to set the price feed.\n * can only be called by the owner.\n * @param _priceFeedAddress price feed address.\n */\n function setPriceFeed(address _priceFeedAddress) external onlyOwner {\n checkContract(_priceFeedAddress);\n\n priceFeed = IPriceFeedSovryn(_priceFeedAddress);\n\n emit PriceFeedAddressSet(_priceFeedAddress);\n }\n\n /**\n * @dev setter function to set reward manager.\n * can only be called by the owner.\n * @param _rewardManagerAddress reward manager address.\n */\n function setRewardManager(address _rewardManagerAddress) external onlyOwner {\n require(_rewardManagerAddress != address(0), \"Account cannot be zero address\");\n\n rewardManager = _rewardManagerAddress;\n\n emit RewardManagerAddressSet(_rewardManagerAddress);\n }\n\n /**\n * @dev validate the APR value.\n * the value must be >= 0 <= MAX_BPS (10000)\n */\n function _validateAPR(uint256 _APR) private {\n require(_APR <= MAX_BPS, \"APR must be less than 10000\");\n }\n\n\n function issueSOV(uint256 _totalZUSDDeposits) public returns (uint256) {\n _requireCallerIsStabilityPool();\n\n return _issueSOV(_totalZUSDDeposits);\n }\n\n function _issueSOV(uint256 _totalZUSDDeposits) private returns (uint256) {\n uint256 timePassedSinceLastIssuance = (block.timestamp.sub(lastIssuanceTime));\n uint256 issuance = _ZUSDToSOV(_totalZUSDDeposits.mul(APR).div(MAX_BPS).mul(timePassedSinceLastIssuance).div(365 days));\n\n totalSOVIssued = totalSOVIssued + issuance;\n lastIssuanceTime = block.timestamp;\n emit TotalSOVIssuedUpdated(totalSOVIssued);\n\n return issuance;\n }\n\n function sendSOV(address _account, uint256 _SOVamount) public {\n _requireCallerIsStabilityPool();\n\n bool success = sovToken.transfer(_account, _SOVamount);\n require(success, \"Failed to send ZERO\");\n }\n\n function _requireCallerIsStabilityPool() internal view {\n require(msg.sender == stabilityPoolAddress, \"CommunityIssuance: caller is not SP\");\n }\n\n /**\n * @dev get the ZUSD to SOV rate conversion. Mostly will be using Sovryn's PriceFeed.\n * @param _zusdAmount zusd amount to get the rate conversion\n * @return the total SOV will be returned.\n */\n function _ZUSDToSOV(uint256 _zusdAmount) internal view returns (uint256) {\n return priceFeed.queryReturn(address(zusdToken), address(sovToken), _zusdAmount);\n }\n}\n" + }, + "contracts/ZERO/CommunityIssuanceStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Interfaces/IPriceFeedSovryn.sol\";\nimport \"../Dependencies/Initializable.sol\";\n\ncontract CommunityIssuanceStorage is Ownable, Initializable {\n // --- Data ---\n\n string constant public NAME = \"CommunityIssuance\";\n\n uint256 constant MAX_BPS = 10000;\n\n IERC20 public sovToken;\n\n IERC20 public zusdToken;\n\n address public stabilityPoolAddress;\n\n uint256 public totalSOVIssued;\n\n uint256 public lastIssuanceTime;\n\n uint256 public APR; //in basis points\n\n address public rewardManager;\n\n IPriceFeedSovryn public priceFeed;\n}\n" + }, + "contracts/ZERO/ZEROStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/BaseMath.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/console.sol\";\nimport \"../Interfaces/IZEROToken.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\nimport \"../Interfaces/IZUSDToken.sol\";\nimport \"./ZEROStakingStorage.sol\";\n\ncontract ZEROStaking is ZEROStakingStorage, IZEROStaking, CheckContract, BaseMath {\n using SafeMath for uint256;\n\n // --- Events ---\n\n event ZEROTokenAddressSet(address _zeroTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event FeeDistributorAddressSet(address _feeDistributorAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event StakeChanged(address indexed staker, uint256 newStake);\n event StakingGainsWithdrawn(address indexed staker, uint256 ZUSDGain, uint256 ETHGain);\n event F_ETHUpdated(uint256 _F_ETH);\n event F_ZUSDUpdated(uint256 _F_ZUSD);\n event TotalZEROStakedUpdated(uint256 _totalZEROStaked);\n event EtherSent(address _account, uint256 _amount);\n event StakerSnapshotsUpdated(address _staker, uint256 _F_ETH, uint256 _F_ZUSD);\n\n // --- Functions ---\n\n function setAddresses(\n address _zeroTokenAddress,\n address _zusdTokenAddress,\n address _feeDistributorAddress,\n address _activePoolAddress\n ) external override onlyOwner {\n checkContract(_zeroTokenAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_feeDistributorAddress);\n checkContract(_activePoolAddress);\n\n zeroToken = IZEROToken(_zeroTokenAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n feeDistributorAddress = _feeDistributorAddress;\n activePoolAddress = _activePoolAddress;\n\n emit ZEROTokenAddressSet(_zeroTokenAddress);\n emit ZEROTokenAddressSet(_zusdTokenAddress);\n emit FeeDistributorAddressSet(_feeDistributorAddress);\n emit ActivePoolAddressSet(_activePoolAddress);\n }\n\n // If caller has a pre-existing stake, send any accumulated ETH and ZUSD gains to them.\n function stake(uint256 _ZEROamount) external override {\n _requireNonZeroAmount(_ZEROamount);\n\n uint256 currentStake = stakes[msg.sender];\n\n uint256 ETHGain;\n uint256 ZUSDGain;\n // Grab any accumulated ETH and ZUSD gains from the current stake\n if (currentStake != 0) {\n ETHGain = _getPendingETHGain(msg.sender);\n ZUSDGain = _getPendingZUSDGain(msg.sender);\n }\n\n _updateUserSnapshots(msg.sender);\n\n uint256 newStake = currentStake.add(_ZEROamount);\n\n // Increase user’s stake and total ZERO staked\n stakes[msg.sender] = newStake;\n totalZEROStaked = totalZEROStaked.add(_ZEROamount);\n emit TotalZEROStakedUpdated(totalZEROStaked);\n\n // Transfer ZERO from caller to this contract\n zeroToken.sendToZEROStaking(msg.sender, _ZEROamount);\n\n emit StakeChanged(msg.sender, newStake);\n emit StakingGainsWithdrawn(msg.sender, ZUSDGain, ETHGain);\n\n // Send accumulated ZUSD and ETH gains to the caller\n if (currentStake != 0) {\n require(zusdToken.transfer(msg.sender, ZUSDGain), \"Coudn't execute ZUSD transfer\");\n _sendETHGainToUser(ETHGain);\n }\n }\n\n /// Unstake the ZERO and send the it back to the caller, along with their accumulated ZUSD & ETH gains.\n /// If requested amount > stake, send their entire stake.\n function unstake(uint256 _ZEROamount) external override {\n uint256 currentStake = stakes[msg.sender];\n _requireUserHasStake(currentStake);\n\n // Grab any accumulated ETH and ZUSD gains from the current stake\n uint256 ETHGain = _getPendingETHGain(msg.sender);\n uint256 ZUSDGain = _getPendingZUSDGain(msg.sender);\n\n _updateUserSnapshots(msg.sender);\n\n if (_ZEROamount > 0) {\n uint256 ZEROToWithdraw = LiquityMath._min(_ZEROamount, currentStake);\n\n uint256 newStake = currentStake.sub(ZEROToWithdraw);\n\n // Decrease user's stake and total ZERO staked\n stakes[msg.sender] = newStake;\n totalZEROStaked = totalZEROStaked.sub(ZEROToWithdraw);\n emit TotalZEROStakedUpdated(totalZEROStaked);\n\n // Transfer unstaked ZERO to user\n require(\n zeroToken.transfer(msg.sender, ZEROToWithdraw),\n \"Couldn't execute ZUSD transfer\"\n );\n\n emit StakeChanged(msg.sender, newStake);\n }\n\n emit StakingGainsWithdrawn(msg.sender, ZUSDGain, ETHGain);\n\n // Send accumulated ZUSD and ETH gains to the caller\n require(zusdToken.transfer(msg.sender, ZUSDGain), \"Couldn't execute ZUSD transfer\");\n _sendETHGainToUser(ETHGain);\n }\n\n // --- Reward-per-unit-staked increase functions. Called by Zero core contracts ---\n\n function increaseF_ETH(uint256 _ETHFee) external override {\n _requireCallerIsFeeDistributor();\n uint256 ETHFeePerZEROStaked;\n\n if (totalZEROStaked > 0) {\n ETHFeePerZEROStaked = _ETHFee.mul(DECIMAL_PRECISION).div(totalZEROStaked);\n }\n\n F_ETH = F_ETH.add(ETHFeePerZEROStaked);\n emit F_ETHUpdated(F_ETH);\n }\n\n function increaseF_ZUSD(uint256 _ZUSDFee) external override {\n _requireCallerIsFeeDistributor();\n uint256 ZUSDFeePerZEROStaked;\n\n if (totalZEROStaked > 0) {\n ZUSDFeePerZEROStaked = _ZUSDFee.mul(DECIMAL_PRECISION).div(totalZEROStaked);\n }\n\n F_ZUSD = F_ZUSD.add(ZUSDFeePerZEROStaked);\n emit F_ZUSDUpdated(F_ZUSD);\n }\n\n // --- Pending reward functions ---\n\n function getPendingETHGain(address _user) external view override returns (uint256) {\n return _getPendingETHGain(_user);\n }\n\n function _getPendingETHGain(address _user) internal view returns (uint256) {\n uint256 F_ETH_Snapshot = snapshots[_user].F_ETH_Snapshot;\n uint256 ETHGain = stakes[_user].mul(F_ETH.sub(F_ETH_Snapshot)).div(DECIMAL_PRECISION);\n return ETHGain;\n }\n\n function getPendingZUSDGain(address _user) external view override returns (uint256) {\n return _getPendingZUSDGain(_user);\n }\n\n function _getPendingZUSDGain(address _user) internal view returns (uint256) {\n uint256 F_ZUSD_Snapshot = snapshots[_user].F_ZUSD_Snapshot;\n uint256 ZUSDGain = stakes[_user].mul(F_ZUSD.sub(F_ZUSD_Snapshot)).div(DECIMAL_PRECISION);\n return ZUSDGain;\n }\n\n // --- Internal helper functions ---\n\n function _updateUserSnapshots(address _user) internal {\n snapshots[_user].F_ETH_Snapshot = F_ETH;\n snapshots[_user].F_ZUSD_Snapshot = F_ZUSD;\n emit StakerSnapshotsUpdated(_user, F_ETH, F_ZUSD);\n }\n\n function _sendETHGainToUser(uint256 ETHGain) internal {\n emit EtherSent(msg.sender, ETHGain);\n (bool success, ) = msg.sender.call{value: ETHGain}(\"\");\n require(success, \"ZEROStaking: Failed to send accumulated ETHGain\");\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsFeeDistributor() internal view {\n require(msg.sender == feeDistributorAddress, \"ZEROStaking: caller is not FeeDistributor\");\n }\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"ZEROStaking: caller is not ActivePool\");\n }\n\n function _requireUserHasStake(uint256 currentStake) internal pure {\n require(currentStake > 0, \"ZEROStaking: User must have a non-zero stake\");\n }\n\n function _requireNonZeroAmount(uint256 _amount) internal pure {\n require(_amount > 0, \"ZEROStaking: Amount must be non-zero\");\n }\n\n receive() external payable {\n _requireCallerIsFeeDistributor();\n }\n}\n" + }, + "contracts/ZERO/ZEROStakingStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Interfaces/IZEROToken.sol\";\nimport \"../Interfaces/IZUSDToken.sol\";\n\ncontract ZEROStakingStorage is Ownable {\n // --- Data ---\n string constant public NAME = \"ZEROStaking\";\n\n mapping( address => uint) public stakes;\n uint public totalZEROStaked;\n\n uint public F_ETH; // Running sum of ETH fees per-ZERO-staked\n uint public F_ZUSD; // Running sum of ZERO fees per-ZERO-staked\n\n // User snapshots of F_ETH and F_ZUSD, taken at the point at which their latest deposit was made\n mapping (address => Snapshot) public snapshots; \n\n struct Snapshot {\n uint F_ETH_Snapshot;\n uint F_ZUSD_Snapshot;\n }\n \n IZEROToken public zeroToken;\n IZUSDToken public zusdToken;\n\n address public feeDistributorAddress;\n address public activePoolAddress;\n\n}\n" + }, + "contracts/ZERO/ZEROToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Interfaces/IZEROToken.sol\";\nimport \"./ZEROTokenStorage.sol\";\n\n/**\n * Based upon OpenZeppelin's ERC20 contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol\n *\n * and their EIP2612 (ERC20Permit / ERC712) functionality:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\n *\n *\n * --- Functionality added specific to the ZEROToken ---\n *\n * 1) Transfer protection: blacklist of addresses that are invalid recipients (i.e. core Zero contracts) in external\n * transfer() and transferFrom() calls. The purpose is to protect users from losing tokens by mistakenly sending ZERO directly to a Zero\n * core contract, when they should rather call the right function.\n *\n * 2) sendToZEROStaking(): callable only by Zero core contracts, which move ZERO tokens from user -> ZEROStaking contract.\n *\n */\n\ncontract ZEROToken is ZEROTokenStorage, CheckContract, IZEROToken {\n using SafeMath for uint256;\n\n // --- Functions ---\n\n function initialize(\n address _zeroStakingAddress,\n address _marketMakerAddress,\n address _presaleAddress\n ) public initializer {\n // checkContract(_marketMakerAddress);\n // checkContract(_presaleAddress);\n\n deploymentStartTime = block.timestamp;\n\n zeroStakingAddress = _zeroStakingAddress;\n marketMakerAddress = _marketMakerAddress;\n presale = IBalanceRedirectPresale(_presaleAddress);\n\n bytes32 hashedName = keccak256(bytes(_NAME));\n bytes32 hashedVersion = keccak256(bytes(_VERSION));\n\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = _chainID();\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(_TYPE_HASH, hashedName, hashedVersion);\n }\n\n // --- External functions ---\n\n /// @notice Generates `amount` tokens that are assigned to `account`\n /// @param account The address that will be assigned the new tokens\n /// @param amount The quantity of tokens generated\n function mint(address account, uint256 amount) external {\n require(\n msg.sender == marketMakerAddress || msg.sender == address(presale),\n \"Invalid caller\"\n );\n _mint(account, amount);\n }\n\n /// @notice Burns `amount` tokens from `account`\n /// @param account The address that will lose the tokens\n /// @param amount The quantity of tokens to burn\n function burn(address account, uint256 amount) external {\n require(msg.sender == marketMakerAddress, \"Invalid caller\");\n _burn(account, amount);\n }\n\n function totalSupply() external view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) external view override returns (uint256) {\n return _balances[account];\n }\n\n function getDeploymentStartTime() external view override returns (uint256) {\n return deploymentStartTime;\n }\n\n function transfer(address recipient, uint256 amount) external override returns (bool) {\n _requireValidRecipient(recipient);\n\n // Otherwise, standard transfer functionality\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) external view override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) external override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external override returns (bool) {\n _requireValidRecipient(recipient);\n\n _transfer(sender, recipient, amount);\n _approve(\n sender,\n msg.sender,\n _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\")\n );\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue)\n external\n override\n returns (bool)\n {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue)\n external\n override\n returns (bool)\n {\n _approve(\n msg.sender,\n spender,\n _allowances[msg.sender][spender].sub(\n subtractedValue,\n \"ERC20: decreased allowance below zero\"\n )\n );\n return true;\n }\n\n function sendToZEROStaking(address _sender, uint256 _amount) external override {\n _requireCallerIsZEROStaking();\n _transfer(_sender, zeroStakingAddress, _amount);\n }\n\n // --- EIP 2612 functionality ---\n\n function domainSeparator() public view override returns (bytes32) {\n if (_chainID() == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external override {\n require(deadline >= now, \"ZERO: expired deadline\");\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n domainSeparator(),\n keccak256(\n abi.encode(_PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner]++, deadline)\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress == owner, \"ZERO: invalid signature\");\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) external view override returns (uint256) {\n // FOR EIP 2612\n return _nonces[owner];\n }\n\n // --- Internal operations ---\n\n function _chainID() private pure returns (uint256 chainID) {\n assembly {\n chainID := chainid()\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 name,\n bytes32 version\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, name, version, _chainID(), address(this)));\n }\n\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal {\n return; // disable the func call - ZEROToken is not used in beta\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n require(presale.isClosed(), \"Presale is not over yet\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account, uint256 amount) internal {\n return; // disable the func call - ZEROToken is not used in beta\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n function _burn(address account, uint256 amount) internal {\n return; // disable the func call - ZEROToken is not used in beta\n require(account != address(0), \"ERC20: mint to the zero address\");\n require(amount <= _balances[account], \"balance too low\");\n\n _totalSupply = _totalSupply.sub(amount);\n _balances[account] = _balances[account].sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n // --- Helper functions ---\n\n // --- 'require' functions ---\n\n function _requireValidRecipient(address _recipient) internal view {\n require(\n _recipient != address(0) && _recipient != address(this),\n \"ZERO: Cannot transfer tokens directly to the ZERO token contract or the zero address\"\n );\n }\n\n function _requireCallerIsZEROStaking() internal view {\n require(\n msg.sender == zeroStakingAddress,\n \"ZEROToken: caller must be the ZEROStaking contract\"\n );\n }\n\n // --- Optional functions ---\n\n function name() external view override returns (string memory) {\n return _NAME;\n }\n\n function symbol() external view override returns (string memory) {\n return _SYMBOL;\n }\n\n function decimals() external view override returns (uint8) {\n return _DECIMALS;\n }\n\n function version() external view override returns (string memory) {\n return _VERSION;\n }\n\n function permitTypeHash() external view override returns (bytes32) {\n return _PERMIT_TYPEHASH;\n }\n}\n" + }, + "contracts/ZERO/ZEROTokenStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IBalanceRedirectPresale.sol\";\nimport \"../Dependencies/Initializable.sol\";\n\ncontract ZEROTokenStorage is Initializable {\n // --- ERC20 Data ---\n\n string constant internal _NAME = \"ZERO\";\n string constant internal _SYMBOL = \"ZERO\";\n string constant internal _VERSION = \"1\";\n uint8 constant internal _DECIMALS = 18;\n\n mapping (address => uint256) internal _balances;\n mapping (address => mapping (address => uint256)) internal _allowances;\n uint internal _totalSupply;\n\n // --- EIP 2612 Data ---\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 internal constant _PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n // keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n bytes32 internal constant _TYPE_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 internal _CACHED_DOMAIN_SEPARATOR;\n uint256 internal _CACHED_CHAIN_ID;\n\n bytes32 internal _HASHED_NAME;\n bytes32 internal _HASHED_VERSION;\n \n mapping (address => uint256) internal _nonces;\n\n // --- ZEROToken specific data ---\n\n uint public constant ONE_YEAR_IN_SECONDS = 31536000; // 60 * 60 * 24 * 365\n\n // uint for use with SafeMath\n uint internal constant _1_MILLION = 1e24; // 1e6 * 1e18 = 1e24\n\n uint internal deploymentStartTime;\n\n address public zeroStakingAddress;\n address public marketMakerAddress;\n IBalanceRedirectPresale public presale;\n\n}\n" + }, + "contracts/ZUSDToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./ZUSDTokenStorage.sol\";\n\n/**\n *\n * Based upon OpenZeppelin's ERC20 contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol\n *\n * and their EIP2612 (ERC20Permit / ERC712) functionality:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\n *\n *\n * --- Functionality added specific to the ZUSDToken ---\n *\n * 1) Transfer protection: blacklist of addresses that are invalid recipients (i.e. core Zero contracts) in external\n * transfer() and transferFrom() calls. The purpose is to protect users from losing tokens by mistakenly sending ZUSD directly to a Zero\n * core contract, when they should rather call the right function.\n *\n * 2) sendToPool() and returnFromPool(): functions callable only Zero core contracts, which move ZUSD tokens between Zero <-> user.\n */\n\ncontract ZUSDToken is ZUSDTokenStorage, CheckContract, IZUSDToken, Ownable {\n using SafeMath for uint256;\n // --- Events ---\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event StabilityPoolAddressChanged(address _newStabilityPoolAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n\n function initialize(\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) public virtual initializer onlyOwner {\n _initialize(_troveManagerAddress, _stabilityPoolAddress, _borrowerOperationsAddress);\n }\n\n function _initialize(\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) internal {\n checkContract(_troveManagerAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_borrowerOperationsAddress);\n\n troveManagerAddress = _troveManagerAddress;\n emit TroveManagerAddressChanged(_troveManagerAddress);\n\n stabilityPoolAddress = _stabilityPoolAddress;\n emit StabilityPoolAddressChanged(_stabilityPoolAddress);\n\n borrowerOperationsAddress = _borrowerOperationsAddress;\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n\n bytes32 hashedName = keccak256(bytes(_NAME));\n bytes32 hashedVersion = keccak256(bytes(_VERSION));\n\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = _chainID();\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(_TYPE_HASH, hashedName, hashedVersion);\n }\n\n // --- Functions for intra-Zero calls ---\n\n function mint(address _account, uint256 _amount) external override {\n _requireCallerIsBorrowerOperations();\n _mint(_account, _amount);\n }\n\n function burn(address _account, uint256 _amount) external override {\n _requireCallerIsBOorTroveMorSP();\n _burn(_account, _amount);\n }\n\n function sendToPool(\n address _sender,\n address _poolAddress,\n uint256 _amount\n ) external override {\n _requireCallerIsStabilityPool();\n _transfer(_sender, _poolAddress, _amount);\n }\n\n function returnFromPool(\n address _poolAddress,\n address _receiver,\n uint256 _amount\n ) external override {\n _requireCallerIsTroveMorSP();\n _transfer(_poolAddress, _receiver, _amount);\n }\n\n // --- External functions ---\n\n function totalSupply() external view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) external view override returns (uint256) {\n return _balances[account];\n }\n\n function transfer(address recipient, uint256 amount) external override returns (bool) {\n _requireValidRecipient(recipient);\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) external view override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) external override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external override returns (bool) {\n _requireValidRecipient(recipient);\n _transfer(sender, recipient, amount);\n _approve(\n sender,\n msg.sender,\n _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\")\n );\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue)\n external\n override\n returns (bool)\n {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue)\n external\n override\n returns (bool)\n {\n _approve(\n msg.sender,\n spender,\n _allowances[msg.sender][spender].sub(\n subtractedValue,\n \"ERC20: decreased allowance below zero\"\n )\n );\n return true;\n }\n\n // --- EIP 2612 Functionality ---\n\n function domainSeparator() public view override returns (bytes32) {\n if (_chainID() == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external override {\n require(deadline >= now, \"ZUSD: expired deadline\");\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n domainSeparator(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n _nonces[owner]++,\n deadline\n )\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress == owner, \"ZUSD: invalid signature\");\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) external view override returns (uint256) {\n // FOR EIP 2612\n return _nonces[owner];\n }\n\n // --- Internal operations ---\n\n function _chainID() private pure returns (uint256 chainID) {\n assembly {\n chainID := chainid()\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 name,\n bytes32 version\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, name, version, _chainID(), address(this)));\n }\n\n // --- Internal operations ---\n // Warning: sanity checks (for sender and recipient) should have been done before calling these internal functions\n\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal {\n assert(sender != address(0));\n assert(recipient != address(0));\n\n _balances[sender] = _balances[sender].sub(\n amount,\n \"ERC20: transfer amount exceeds balance\"\n );\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account, uint256 amount) internal {\n assert(account != address(0));\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n function _burn(address account, uint256 amount) internal {\n assert(account != address(0));\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal {\n assert(owner != address(0));\n assert(spender != address(0));\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n // --- 'require' functions ---\n\n function _requireValidRecipient(address _recipient) internal view {\n require(\n _recipient != address(0) && _recipient != address(this),\n \"ZUSD: Cannot transfer tokens directly to the ZUSD token contract or the zero address\"\n );\n }\n\n function _requireCallerIsBorrowerOperations() internal view {\n require(\n msg.sender == borrowerOperationsAddress,\n \"ZUSDToken: Caller is not BorrowerOperations\"\n );\n }\n\n function _requireCallerIsBOorTroveMorSP() internal view {\n require(\n msg.sender == borrowerOperationsAddress ||\n msg.sender == troveManagerAddress ||\n msg.sender == stabilityPoolAddress,\n \"ZUSD: Caller is neither BorrowerOperations nor TroveManager nor StabilityPool\"\n );\n }\n\n function _requireCallerIsStabilityPool() internal view {\n require(msg.sender == stabilityPoolAddress, \"ZUSD: Caller is not the StabilityPool\");\n }\n\n function _requireCallerIsTroveMorSP() internal view {\n require(\n msg.sender == troveManagerAddress || msg.sender == stabilityPoolAddress,\n \"ZUSD: Caller is neither TroveManager nor StabilityPool\"\n );\n }\n\n // --- Optional functions ---\n\n function name() external view override returns (string memory) {\n return _NAME;\n }\n\n function symbol() external view override returns (string memory) {\n return _SYMBOL;\n }\n\n function decimals() external view override returns (uint8) {\n return _DECIMALS;\n }\n\n function version() external view override returns (string memory) {\n return _VERSION;\n }\n\n function permitTypeHash() external view override returns (bytes32) {\n return _PERMIT_TYPEHASH;\n }\n}\n" + }, + "contracts/ZUSDTokenStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Dependencies/Initializable.sol\";\n\ncontract ZUSDTokenStorage is Initializable {\n uint256 internal _totalSupply;\n string internal constant _NAME = \"ZUSD Stablecoin\";\n string internal constant _SYMBOL = \"ZUSD\";\n string internal constant _VERSION = \"1\";\n uint8 internal constant _DECIMALS = 18;\n\n // --- Data for EIP2612 ---\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 internal constant _PERMIT_TYPEHASH =\n 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n // keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n bytes32 internal constant _TYPE_HASH =\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n // Cache the domain separator, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 internal _CACHED_DOMAIN_SEPARATOR;\n uint256 internal _CACHED_CHAIN_ID;\n\n bytes32 internal _HASHED_NAME;\n bytes32 internal _HASHED_VERSION;\n\n mapping(address => uint256) internal _nonces;\n\n // User data for ZUSD token\n mapping(address => uint256) internal _balances;\n mapping(address => mapping(address => uint256)) internal _allowances;\n\n // --- Addresses ---\n address internal troveManagerAddress;\n address internal stabilityPoolAddress;\n address internal borrowerOperationsAddress;\n}\n" + }, + "hardhat/console.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >= 0.4.22 <0.9.0;\n\nlibrary console {\n\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n\tfunction _sendLogPayload(bytes memory payload) private view {\n\t\tuint256 payloadLength = payload.length;\n\t\taddress consoleAddress = CONSOLE_ADDRESS;\n\t\tassembly {\n\t\t\tlet payloadStart := add(payload, 32)\n\t\t\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n\t\t}\n\t}\n\n\tfunction log() internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log()\"));\n\t}\n\n\tfunction logInt(int256 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n\t}\n\n\tfunction logUint(uint256 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n\t}\n\n\tfunction logString(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction logBool(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction logAddress(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction logBytes(bytes memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n\t}\n\n\tfunction logBytes1(bytes1 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n\t}\n\n\tfunction logBytes2(bytes2 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n\t}\n\n\tfunction logBytes3(bytes3 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n\t}\n\n\tfunction logBytes4(bytes4 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n\t}\n\n\tfunction logBytes5(bytes5 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n\t}\n\n\tfunction logBytes6(bytes6 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n\t}\n\n\tfunction logBytes7(bytes7 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n\t}\n\n\tfunction logBytes8(bytes8 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n\t}\n\n\tfunction logBytes9(bytes9 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n\t}\n\n\tfunction logBytes10(bytes10 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n\t}\n\n\tfunction logBytes11(bytes11 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n\t}\n\n\tfunction logBytes12(bytes12 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n\t}\n\n\tfunction logBytes13(bytes13 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n\t}\n\n\tfunction logBytes14(bytes14 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n\t}\n\n\tfunction logBytes15(bytes15 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n\t}\n\n\tfunction logBytes16(bytes16 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n\t}\n\n\tfunction logBytes17(bytes17 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n\t}\n\n\tfunction logBytes18(bytes18 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n\t}\n\n\tfunction logBytes19(bytes19 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n\t}\n\n\tfunction logBytes20(bytes20 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n\t}\n\n\tfunction logBytes21(bytes21 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n\t}\n\n\tfunction logBytes22(bytes22 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n\t}\n\n\tfunction logBytes23(bytes23 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n\t}\n\n\tfunction logBytes24(bytes24 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n\t}\n\n\tfunction logBytes25(bytes25 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n\t}\n\n\tfunction logBytes26(bytes26 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n\t}\n\n\tfunction logBytes27(bytes27 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n\t}\n\n\tfunction logBytes28(bytes28 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n\t}\n\n\tfunction logBytes29(bytes29 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n\t}\n\n\tfunction logBytes30(bytes30 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n\t}\n\n\tfunction logBytes31(bytes31 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n\t}\n\n\tfunction logBytes32(bytes32 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n\t}\n\n\tfunction log(uint256 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n\t}\n\n\tfunction log(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction log(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction log(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n\t}\n\n\tfunction log(address p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256)\", p0, p1));\n\t}\n\n\tfunction log(address p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n\t}\n\n\tfunction log(address p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n\t}\n\n\tfunction log(address p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/754dff2eec82e13c98a907fdc90582aa.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/754dff2eec82e13c98a907fdc90582aa.json new file mode 100644 index 00000000..6731b61a --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/754dff2eec82e13c98a907fdc90582aa.json @@ -0,0 +1,376 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n // Check the signature length\n if (signature.length != 65) {\n revert(\"ECDSA: invalid signature length\");\n }\n\n // Divide the signature in r, s and v variables\n bytes32 r;\n bytes32 s;\n uint8 v;\n\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n\n return recover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover-bytes32-bytes-} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, \"ECDSA: invalid signature 's' value\");\n require(v == 27 || v == 28, \"ECDSA: invalid signature 'v' value\");\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n require(signer != address(0), \"ECDSA: invalid signature\");\n\n return signer;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * replicates the behavior of the\n * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]\n * JSON-RPC method.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n}\n" + }, + "@openzeppelin/contracts/drafts/EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) internal {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = _getChainId();\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view virtual returns (bytes32) {\n if (_getChainId() == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(bytes32 typeHash, bytes32 name, bytes32 version) private view returns (bytes32) {\n return keccak256(\n abi.encode(\n typeHash,\n name,\n version,\n _getChainId(),\n address(this)\n )\n );\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", _domainSeparatorV4(), structHash));\n }\n\n function _getChainId() private view returns (uint256 chainId) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n // solhint-disable-next-line no-inline-assembly\n assembly {\n chainId := chainid()\n }\n }\n}\n" + }, + "@openzeppelin/contracts/drafts/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.5 <0.8.0;\n\nimport \"../token/ERC20/ERC20.sol\";\nimport \"./IERC20Permit.sol\";\nimport \"../cryptography/ECDSA.sol\";\nimport \"../utils/Counters.sol\";\nimport \"./EIP712.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping (address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private immutable _PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) internal EIP712(name, \"1\") {\n }\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\n // solhint-disable-next-line not-rely-on-time\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n _nonces[owner].current(),\n deadline\n )\n );\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _nonces[owner].increment();\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n}\n" + }, + "@openzeppelin/contracts/drafts/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens,\n * given `owner`'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for `permit`, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a, \"SafeMath: subtraction overflow\");\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: modulo by zero\");\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name_, string memory symbol_) public {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n * called.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../math/SafeMath.sol\";\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\n * directly accessed.\n */\nlibrary Counters {\n using SafeMath for uint256;\n\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n" + }, + "contracts/ActivePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IActivePool.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\n\nimport \"./ActivePoolStorage.sol\";\n\n/**\n * @title Active Pool\n * @notice The Active Pool holds the ETH collateral and ZUSD debt (but not ZUSD tokens) for all active troves.\n *\n * When a trove is liquidated, it's ETH and ZUSD debt are transferred from the Active Pool, to either the\n * Stability Pool, the Default Pool, or both, depending on the liquidation conditions.\n */\ncontract ActivePool is CheckContract, IActivePool, ActivePoolStorage {\n using SafeMath for uint256;\n // --- Events ---\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolZUSDDebtUpdated(uint256 _ZUSDDebt);\n event ActivePoolETHBalanceUpdated(uint256 _ETH);\n\n // --- Contract setters ---\n /// @notice initializer function that sets required addresses\n /// @dev Checks addresses are contracts. Only callable by contract owner.\n /// @param _borrowerOperationsAddress BorrowerOperations contract address\n /// @param _troveManagerAddress TroveManager contract address\n /// @param _stabilityPoolAddress StabilityPool contract address\n /// @param _defaultPoolAddress DefaultPool contract address\n function setAddresses(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _defaultPoolAddress\n ) external onlyOwner {\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_defaultPoolAddress);\n\n borrowerOperationsAddress = _borrowerOperationsAddress;\n troveManagerAddress = _troveManagerAddress;\n stabilityPoolAddress = _stabilityPoolAddress;\n defaultPoolAddress = _defaultPoolAddress;\n\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit StabilityPoolAddressChanged(_stabilityPoolAddress);\n emit DefaultPoolAddressChanged(_defaultPoolAddress);\n }\n\n // --- Getters for public variables. Required by IPool interface ---\n\n /// @notice Not necessarily equal to the the contract's raw ETH balance - ether can be forcibly sent to contracts.\n /// @return the ETH state variable.\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n /// @return the ZUSD debt state variable\n function getZUSDDebt() external view override returns (uint256) {\n return ZUSDDebt;\n }\n\n // --- Pool functionality ---\n\n /// @notice Send ETH amount to given account. Updates ActivePool balance. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _account account to receive the ETH amount\n /// @param _amount ETH amount to send\n function sendETH(address _account, uint256 _amount) external override {\n _requireCallerIsBOorTroveMorSP();\n ETH = ETH.sub(_amount);\n emit ActivePoolETHBalanceUpdated(ETH);\n emit EtherSent(_account, _amount);\n\n (bool success, ) = _account.call{ value: _amount }(\"\");\n require(success, \"ActivePool: sending ETH failed\");\n }\n\n /// @notice Increases ZUSD debt of the active pool. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _amount ZUSD amount to add to the pool debt\n function increaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsBOorTroveM();\n ZUSDDebt = ZUSDDebt.add(_amount);\n ActivePoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n /// @notice Decreases ZUSD debt of the active pool. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _amount ZUSD amount to sub to the pool debt\n function decreaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsBOorTroveMorSP();\n ZUSDDebt = ZUSDDebt.sub(_amount);\n ActivePoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsBorrowerOperationsOrDefaultPool() internal view {\n require(\n msg.sender == borrowerOperationsAddress || msg.sender == defaultPoolAddress,\n \"ActivePool: Caller is neither BO nor Default Pool\"\n );\n }\n\n function _requireCallerIsBOorTroveMorSP() internal view {\n require(\n msg.sender == borrowerOperationsAddress ||\n msg.sender == troveManagerAddress ||\n msg.sender == stabilityPoolAddress,\n \"ActivePool: Caller is neither BorrowerOperations nor TroveManager nor StabilityPool\"\n );\n }\n\n function _requireCallerIsBOorTroveM() internal view {\n require(\n msg.sender == borrowerOperationsAddress || msg.sender == troveManagerAddress,\n \"ActivePool: Caller is neither BorrowerOperations nor TroveManager\"\n );\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsBorrowerOperationsOrDefaultPool();\n ETH = ETH.add(msg.value);\n emit ActivePoolETHBalanceUpdated(ETH);\n }\n}\n" + }, + "contracts/ActivePoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Dependencies/Ownable.sol\";\n\n/**\n * @title Active Pool Storage\n * @dev Stores Active Pool required addresses and internal ETH and ZUSD debt states\n * Extends Ownable\n */\ncontract ActivePoolStorage is Ownable {\n string public constant NAME = \"ActivePool\";\n\n address public borrowerOperationsAddress;\n address public troveManagerAddress;\n address public stabilityPoolAddress;\n address public defaultPoolAddress;\n uint256 internal ETH; // deposited ether tracker\n uint256 internal ZUSDDebt;\n}\n" + }, + "contracts/BorrowerOperations.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./BorrowerOperationsStorage.sol\";\nimport \"./Dependencies/Mynt/MyntLib.sol\";\n\ncontract BorrowerOperations is\n LiquityBase,\n BorrowerOperationsStorage,\n CheckContract,\n IBorrowerOperations\n{\n /* --- Variable container structs ---\n\n Used to hold, return and assign variables inside a function, in order to avoid the error:\n \"CompilerError: Stack too deep\". */\n\n struct LocalVariables_adjustTrove {\n uint256 price;\n uint256 collChange;\n uint256 netDebtChange;\n bool isCollIncrease;\n uint256 debt;\n uint256 coll;\n uint256 oldICR;\n uint256 newICR;\n uint256 newTCR;\n uint256 ZUSDFee;\n uint256 newDebt;\n uint256 newColl;\n uint256 stake;\n uint256 newNICR;\n bool isRecoveryMode;\n }\n\n struct LocalVariables_openTrove {\n uint256 price;\n uint256 ZUSDFee;\n uint256 netDebt;\n uint256 compositeDebt;\n uint256 ICR;\n uint256 NICR;\n uint256 stake;\n uint256 arrayIndex;\n }\n\n struct ContractsCache {\n ITroveManager troveManager;\n IActivePool activePool;\n IZUSDToken zusdToken;\n }\n\n enum BorrowerOperation {\n openTrove,\n closeTrove,\n adjustTrove\n }\n\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n event MassetManagerAddressChanged(address _massetManagerAddress);\n\n event TroveCreated(address indexed _borrower, uint256 arrayIndex);\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 stake,\n BorrowerOperation operation\n );\n event ZUSDBorrowingFeePaid(address indexed _borrower, uint256 _ZUSDFee);\n\n // --- Dependency setters ---\n\n function setAddresses(\n address _feeDistributorAddress,\n address _liquityBaseParamsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _defaultPoolAddress,\n address _stabilityPoolAddress,\n address _gasPoolAddress,\n address _collSurplusPoolAddress,\n address _priceFeedAddress,\n address _sortedTrovesAddress,\n address _zusdTokenAddress,\n address _zeroStakingAddress\n ) external override onlyOwner {\n // This makes impossible to open a trove with zero withdrawn ZUSD\n assert(MIN_NET_DEBT > 0);\n\n checkContract(_feeDistributorAddress);\n checkContract(_liquityBaseParamsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n checkContract(_defaultPoolAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_gasPoolAddress);\n checkContract(_collSurplusPoolAddress);\n checkContract(_priceFeedAddress);\n checkContract(_sortedTrovesAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_zeroStakingAddress);\n\n feeDistributor = IFeeDistributor(_feeDistributorAddress);\n liquityBaseParams = ILiquityBaseParams(_liquityBaseParamsAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n activePool = IActivePool(_activePoolAddress);\n defaultPool = IDefaultPool(_defaultPoolAddress);\n stabilityPoolAddress = _stabilityPoolAddress;\n gasPoolAddress = _gasPoolAddress;\n collSurplusPool = ICollSurplusPool(_collSurplusPoolAddress);\n priceFeed = IPriceFeed(_priceFeedAddress);\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n zeroStakingAddress = _zeroStakingAddress;\n zeroStaking = IZEROStaking(_zeroStakingAddress);\n\n emit FeeDistributorAddressChanged(_feeDistributorAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n emit DefaultPoolAddressChanged(_defaultPoolAddress);\n emit StabilityPoolAddressChanged(_stabilityPoolAddress);\n emit GasPoolAddressChanged(_gasPoolAddress);\n emit CollSurplusPoolAddressChanged(_collSurplusPoolAddress);\n emit PriceFeedAddressChanged(_priceFeedAddress);\n emit SortedTrovesAddressChanged(_sortedTrovesAddress);\n emit ZUSDTokenAddressChanged(_zusdTokenAddress);\n emit ZEROStakingAddressChanged(_zeroStakingAddress);\n }\n\n function setMassetManagerAddress(address _massetManagerAddress) external onlyOwner {\n massetManager = IMassetManager(_massetManagerAddress);\n emit MassetManagerAddressChanged(_massetManagerAddress);\n }\n\n function openTrove(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n _openTrove(_maxFeePercentage, _ZUSDAmount, _upperHint, _lowerHint, msg.sender);\n }\n\n function openNueTrove(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n require(address(massetManager) != address(0), \"Masset address not set\");\n\n _openTrove(_maxFeePercentage, _ZUSDAmount, _upperHint, _lowerHint, address(this));\n require(\n zusdToken.approve(address(massetManager), _ZUSDAmount),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n massetManager.mintTo(address(zusdToken), _ZUSDAmount, msg.sender);\n }\n\n // --- Borrower Trove Operations ---\n function _openTrove(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint,\n address _tokensRecipient\n ) internal {\n ContractsCache memory contractsCache = ContractsCache(troveManager, activePool, zusdToken);\n LocalVariables_openTrove memory vars;\n\n vars.price = priceFeed.fetchPrice();\n bool isRecoveryMode = _checkRecoveryMode(vars.price);\n\n _requireValidMaxFeePercentage(_maxFeePercentage, isRecoveryMode);\n _requireTroveisNotActive(contractsCache.troveManager, msg.sender);\n\n vars.ZUSDFee;\n vars.netDebt = _ZUSDAmount;\n\n if (!isRecoveryMode) {\n vars.ZUSDFee = _triggerBorrowingFee(\n contractsCache.troveManager,\n contractsCache.zusdToken,\n _ZUSDAmount,\n _maxFeePercentage\n );\n vars.netDebt = vars.netDebt.add(vars.ZUSDFee);\n }\n _requireAtLeastMinNetDebt(vars.netDebt);\n\n // ICR is based on the composite debt, i.e. the requested ZUSD amount + ZUSD borrowing fee + ZUSD gas comp.\n vars.compositeDebt = _getCompositeDebt(vars.netDebt);\n assert(vars.compositeDebt > 0);\n\n vars.ICR = LiquityMath._computeCR(msg.value, vars.compositeDebt, vars.price);\n vars.NICR = LiquityMath._computeNominalCR(msg.value, vars.compositeDebt);\n\n if (isRecoveryMode) {\n _requireICRisAboveCCR(vars.ICR);\n } else {\n _requireICRisAboveMCR(vars.ICR);\n uint256 newTCR = _getNewTCRFromTroveChange(\n msg.value,\n true,\n vars.compositeDebt,\n true,\n vars.price\n ); // bools: coll increase, debt increase\n _requireNewTCRisAboveCCR(newTCR);\n }\n\n // Set the trove struct's properties\n contractsCache.troveManager.setTroveStatus(msg.sender, 1);\n contractsCache.troveManager.increaseTroveColl(msg.sender, msg.value);\n contractsCache.troveManager.increaseTroveDebt(msg.sender, vars.compositeDebt);\n\n contractsCache.troveManager.updateTroveRewardSnapshots(msg.sender);\n vars.stake = contractsCache.troveManager.updateStakeAndTotalStakes(msg.sender);\n\n sortedTroves.insert(msg.sender, vars.NICR, _upperHint, _lowerHint);\n vars.arrayIndex = contractsCache.troveManager.addTroveOwnerToArray(msg.sender);\n emit TroveCreated(msg.sender, vars.arrayIndex);\n\n // Move the ether to the Active Pool, and mint the ZUSDAmount to the borrower\n _activePoolAddColl(contractsCache.activePool, msg.value);\n _mintZusdAndIncreaseActivePoolDebt(\n contractsCache.activePool,\n contractsCache.zusdToken,\n _tokensRecipient,\n _ZUSDAmount,\n vars.netDebt\n );\n // Move the ZUSD gas compensation to the Gas Pool\n _mintZusdAndIncreaseActivePoolDebt(\n contractsCache.activePool,\n contractsCache.zusdToken,\n gasPoolAddress,\n ZUSD_GAS_COMPENSATION,\n ZUSD_GAS_COMPENSATION\n );\n\n emit TroveUpdated(\n msg.sender,\n vars.compositeDebt,\n msg.value,\n vars.stake,\n BorrowerOperation.openTrove\n );\n emit ZUSDBorrowingFeePaid(msg.sender, vars.ZUSDFee);\n }\n\n /// Send ETH as collateral to a trove\n function addColl(address _upperHint, address _lowerHint) external payable override {\n _adjustTrove(msg.sender, 0, 0, false, _upperHint, _lowerHint, 0);\n }\n\n /// Send ETH as collateral to a trove. Called by only the Stability Pool.\n function moveETHGainToTrove(\n address _borrower,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n _requireCallerIsStabilityPool();\n _adjustTrove(_borrower, 0, 0, false, _upperHint, _lowerHint, 0);\n }\n\n /// Withdraw ETH collateral from a trove\n function withdrawColl(\n uint256 _collWithdrawal,\n address _upperHint,\n address _lowerHint\n ) external override {\n _adjustTrove(msg.sender, _collWithdrawal, 0, false, _upperHint, _lowerHint, 0);\n }\n\n /// Withdraw ZUSD tokens from a trove: mint new ZUSD tokens to the owner, and increase the trove's debt accordingly\n function withdrawZUSD(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external override {\n _adjustTrove(msg.sender, 0, _ZUSDAmount, true, _upperHint, _lowerHint, _maxFeePercentage);\n }\n\n /// Borrow (withdraw) ZUSD tokens from a trove: mint new ZUSD tokens to the owner and convert it to DLLR in one transaction\n /// Zero Line of Credit owner can borrow a specified amount of ZUSD and convert it to DLLR via Sovryn Mynt\n ///@return DLLR amount minted\n function withdrawZusdAndConvertToDLLR(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external override returns (uint256) {\n address thisAddress = address(this);\n uint256 balanceBefore = zusdToken.balanceOf(thisAddress);\n\n _withdrawZusdTo(\n msg.sender,\n thisAddress,\n _ZUSDAmount,\n _upperHint,\n _lowerHint,\n _maxFeePercentage\n );\n\n require(\n zusdToken.balanceOf(thisAddress) == balanceBefore.add(_ZUSDAmount),\n \"ZUSD is not borrowed correctly\"\n );\n require(\n zusdToken.approve(address(massetManager), _ZUSDAmount),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n return massetManager.mintTo(address(zusdToken), _ZUSDAmount, msg.sender);\n }\n\n /// Repay ZUSD tokens to a Trove: Burn the repaid ZUSD tokens, and reduce the trove's debt accordingly\n function repayZUSD(\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external override {\n _adjustTrove(msg.sender, 0, _ZUSDAmount, false, _upperHint, _lowerHint, 0);\n }\n\n /// Repay ZUSD tokens to a Trove by DLLR: convert DLLR to ZUSD tokens, and then reduce the trove's debt accordingly\n function repayZusdFromDLLR(\n uint256 _dllrAmount,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external override {\n _adjustNueTrove(0, 0, _dllrAmount, false, _upperHint, _lowerHint, _permitParams);\n }\n\n function adjustTrove(\n uint256 _maxFeePercentage,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n _adjustTrove(\n msg.sender,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFeePercentage\n );\n }\n\n // in case of _isDebtIncrease = false MassetManager contract must have an approval of NUE tokens\n function adjustNueTrove(\n uint256 _maxFeePercentage,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external payable override {\n _adjustNueTrove(\n _maxFeePercentage,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _permitParams\n );\n }\n\n // in case of _isDebtIncrease = false Masset Manager contract must have an approval of NUE tokens\n function _adjustNueTrove(\n uint256 _maxFeePercentage,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) internal {\n require(address(massetManager) != address(0), \"Masset address not set\");\n\n if (!_isDebtIncrease && _ZUSDChange > 0) {\n MyntLib.redeemZusdFromDllrWithPermit(\n massetManager,\n _ZUSDChange,\n address(zusdToken),\n _permitParams\n );\n }\n _adjustSenderTrove(\n msg.sender,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFeePercentage,\n address(this)\n );\n if (_isDebtIncrease && _ZUSDChange > 0) {\n require(\n zusdToken.approve(address(massetManager), _ZUSDChange),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n massetManager.mintTo(address(zusdToken), _ZUSDChange, msg.sender);\n }\n }\n\n function _adjustTrove(\n address _borrower,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n uint256 _maxFeePercentage\n ) internal {\n _adjustSenderTrove(\n _borrower,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFeePercentage,\n msg.sender\n );\n }\n\n // _withdrawZusd: _adjustTrove(msg.sender, 0, _ZUSDAmount, true, _upperHint, _lowerHint, _maxFeePercentage);\n function _withdrawZusdTo(\n address _borrower,\n address _receiver,\n uint256 _ZUSDChange,\n address _upperHint,\n address _lowerHint,\n uint256 _maxFeePercentage\n ) internal {\n _adjustSenderTrove(\n _borrower,\n 0,\n _ZUSDChange,\n true,\n _upperHint,\n _lowerHint,\n _maxFeePercentage,\n _receiver\n );\n }\n\n /**\n * _adjustSenderTrove(): Alongside a debt change, this function can perform either a collateral top-up or a collateral withdrawal.\n *\n * It therefore expects either a positive msg.value, or a positive _collWithdrawal argument.\n *\n * If both are positive, it will revert.\n */\n function _adjustSenderTrove(\n address _borrower,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n uint256 _maxFeePercentage,\n address _tokensRecipient\n ) internal {\n ContractsCache memory contractsCache = ContractsCache(troveManager, activePool, zusdToken);\n LocalVariables_adjustTrove memory vars;\n\n vars.price = priceFeed.fetchPrice();\n vars.isRecoveryMode = _checkRecoveryMode(vars.price);\n\n if (_isDebtIncrease) {\n _requireValidMaxFeePercentage(_maxFeePercentage, vars.isRecoveryMode);\n _requireNonZeroDebtChange(_ZUSDChange);\n }\n _requireSingularCollChange(_collWithdrawal);\n _requireNonZeroAdjustment(_collWithdrawal, _ZUSDChange);\n _requireTroveisActive(contractsCache.troveManager, _borrower);\n\n // Confirm the operation is either a borrower adjusting their own trove, or a pure ETH transfer from the Stability Pool to a trove\n assert(\n msg.sender == _borrower ||\n (msg.sender == stabilityPoolAddress && msg.value > 0 && _ZUSDChange == 0)\n );\n\n contractsCache.troveManager.applyPendingRewards(_borrower);\n\n // Get the collChange based on whether or not ETH was sent in the transaction\n (vars.collChange, vars.isCollIncrease) = _getCollChange(msg.value, _collWithdrawal);\n\n vars.netDebtChange = _ZUSDChange;\n\n // If the adjustment incorporates a debt increase and system is in Normal Mode, then trigger a borrowing fee\n if (_isDebtIncrease && !vars.isRecoveryMode) {\n vars.ZUSDFee = _triggerBorrowingFee(\n contractsCache.troveManager,\n contractsCache.zusdToken,\n _ZUSDChange,\n _maxFeePercentage\n );\n vars.netDebtChange = vars.netDebtChange.add(vars.ZUSDFee); // The raw debt change includes the fee\n }\n\n vars.debt = contractsCache.troveManager.getTroveDebt(_borrower);\n vars.coll = contractsCache.troveManager.getTroveColl(_borrower);\n\n // Get the trove's old ICR before the adjustment, and what its new ICR will be after the adjustment\n vars.oldICR = LiquityMath._computeCR(vars.coll, vars.debt, vars.price);\n vars.newICR = _getNewICRFromTroveChange(\n vars.coll,\n vars.debt,\n vars.collChange,\n vars.isCollIncrease,\n vars.netDebtChange,\n _isDebtIncrease,\n vars.price\n );\n assert(_collWithdrawal <= vars.coll);\n\n // Check the adjustment satisfies all conditions for the current system mode\n _requireValidAdjustmentInCurrentMode(\n vars.isRecoveryMode,\n _collWithdrawal,\n _isDebtIncrease,\n vars\n );\n\n // When the adjustment is a debt repayment, check it's a valid amount and that the caller has enough ZUSD\n if (!_isDebtIncrease && _ZUSDChange > 0) {\n _requireAtLeastMinNetDebt(_getNetDebt(vars.debt).sub(vars.netDebtChange));\n _requireValidZUSDRepayment(vars.debt, vars.netDebtChange);\n _requireSufficientZUSDBalance(contractsCache.zusdToken, _borrower, vars.netDebtChange);\n }\n\n (vars.newColl, vars.newDebt) = _updateTroveFromAdjustment(\n contractsCache.troveManager,\n _borrower,\n vars.collChange,\n vars.isCollIncrease,\n vars.netDebtChange,\n _isDebtIncrease\n );\n vars.stake = contractsCache.troveManager.updateStakeAndTotalStakes(_borrower);\n\n // Re-insert trove in to the sorted list\n vars.newNICR = _getNewNominalICRFromTroveChange(\n vars.coll,\n vars.debt,\n vars.collChange,\n vars.isCollIncrease,\n vars.netDebtChange,\n _isDebtIncrease\n );\n sortedTroves.reInsert(_borrower, vars.newNICR, _upperHint, _lowerHint);\n\n emit TroveUpdated(\n _borrower,\n vars.newDebt,\n vars.newColl,\n vars.stake,\n BorrowerOperation.adjustTrove\n );\n emit ZUSDBorrowingFeePaid(msg.sender, vars.ZUSDFee);\n\n // Use the unmodified _ZUSDChange here, as we don't send the fee to the user\n _moveTokensAndETHfromAdjustment(\n contractsCache.activePool,\n contractsCache.zusdToken,\n msg.sender,\n vars.collChange,\n vars.isCollIncrease,\n _ZUSDChange,\n _isDebtIncrease,\n vars.netDebtChange,\n _tokensRecipient\n );\n }\n\n function closeTrove() external override {\n _closeTrove();\n }\n\n function closeNueTrove(IMassetManager.PermitParams calldata _permitParams) external override {\n require(address(massetManager) != address(0), \"Masset address not set\");\n\n uint256 debt = troveManager.getTroveDebt(msg.sender);\n\n MyntLib.redeemZusdFromDllrWithPermit(\n massetManager,\n debt.sub(ZUSD_GAS_COMPENSATION),\n address(zusdToken),\n _permitParams\n );\n _closeTrove();\n }\n\n function _closeTrove() internal {\n ITroveManager troveManagerCached = troveManager;\n IActivePool activePoolCached = activePool;\n IZUSDToken zusdTokenCached = zusdToken;\n\n _requireTroveisActive(troveManagerCached, msg.sender);\n uint256 price = priceFeed.fetchPrice();\n _requireNotInRecoveryMode(price);\n\n troveManagerCached.applyPendingRewards(msg.sender);\n\n uint256 coll = troveManagerCached.getTroveColl(msg.sender);\n uint256 debt = troveManagerCached.getTroveDebt(msg.sender);\n\n _requireSufficientZUSDBalance(\n zusdTokenCached,\n msg.sender,\n debt.sub(ZUSD_GAS_COMPENSATION)\n );\n\n uint256 newTCR = _getNewTCRFromTroveChange(coll, false, debt, false, price);\n _requireNewTCRisAboveCCR(newTCR);\n\n troveManagerCached.removeStake(msg.sender);\n troveManagerCached.closeTrove(msg.sender);\n\n emit TroveUpdated(msg.sender, 0, 0, 0, BorrowerOperation.closeTrove);\n\n // Burn the repaid ZUSD from the user's balance and the gas compensation from the Gas Pool\n _burnZusdAndDecreaseActivePoolDebt(\n activePoolCached,\n zusdTokenCached,\n msg.sender,\n debt.sub(ZUSD_GAS_COMPENSATION)\n );\n _burnZusdAndDecreaseActivePoolDebt(\n activePoolCached,\n zusdTokenCached,\n gasPoolAddress,\n ZUSD_GAS_COMPENSATION\n );\n\n // Send the collateral back to the user\n activePoolCached.sendETH(msg.sender, coll);\n }\n\n /**\n * Claim remaining collateral from a redemption or from a liquidation with ICR > MCR in Recovery Mode\n */\n function claimCollateral() external override {\n // send ETH from CollSurplus Pool to owner\n collSurplusPool.claimColl(msg.sender);\n }\n\n // --- Helper functions ---\n\n function _triggerBorrowingFee(\n ITroveManager _troveManager,\n IZUSDToken _zusdToken,\n uint256 _ZUSDAmount,\n uint256 _maxFeePercentage\n ) internal returns (uint256) {\n _troveManager.decayBaseRateFromBorrowing(); // decay the baseRate state variable\n uint256 ZUSDFee = _troveManager.getBorrowingFee(_ZUSDAmount);\n\n _requireUserAcceptsFee(ZUSDFee, _ZUSDAmount, _maxFeePercentage);\n _zusdToken.mint(address(feeDistributor), ZUSDFee);\n feeDistributor.distributeFees();\n\n return ZUSDFee;\n }\n\n function _getUSDValue(uint256 _coll, uint256 _price) internal pure returns (uint256) {\n uint256 usdValue = _price.mul(_coll).div(DECIMAL_PRECISION);\n\n return usdValue;\n }\n\n function _getCollChange(uint256 _collReceived, uint256 _requestedCollWithdrawal)\n internal\n pure\n returns (uint256 collChange, bool isCollIncrease)\n {\n if (_collReceived != 0) {\n collChange = _collReceived;\n isCollIncrease = true;\n } else {\n collChange = _requestedCollWithdrawal;\n }\n }\n\n /// Update trove's coll and debt based on whether they increase or decrease\n function _updateTroveFromAdjustment(\n ITroveManager _troveManager,\n address _borrower,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease\n ) internal returns (uint256, uint256) {\n uint256 newColl = (_isCollIncrease)\n ? _troveManager.increaseTroveColl(_borrower, _collChange)\n : _troveManager.decreaseTroveColl(_borrower, _collChange);\n uint256 newDebt = (_isDebtIncrease)\n ? _troveManager.increaseTroveDebt(_borrower, _debtChange)\n : _troveManager.decreaseTroveDebt(_borrower, _debtChange);\n\n return (newColl, newDebt);\n }\n\n function _moveTokensAndETHfromAdjustment(\n IActivePool _activePool,\n IZUSDToken _zusdToken,\n address _borrower,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n uint256 _netDebtChange,\n address _tokensRecipient\n ) internal {\n if (_isDebtIncrease) {\n _mintZusdAndIncreaseActivePoolDebt(\n _activePool,\n _zusdToken,\n _tokensRecipient,\n _ZUSDChange,\n _netDebtChange\n );\n } else {\n _burnZusdAndDecreaseActivePoolDebt(_activePool, _zusdToken, _borrower, _ZUSDChange);\n }\n\n if (_isCollIncrease) {\n _activePoolAddColl(_activePool, _collChange);\n } else {\n _activePool.sendETH(_borrower, _collChange);\n }\n }\n\n /// Send ETH to Active Pool and increase its recorded ETH balance\n function _activePoolAddColl(IActivePool _activePool, uint256 _amount) internal {\n (bool success, ) = address(_activePool).call{ value: _amount }(\"\");\n require(success, \"BorrowerOps: Sending ETH to ActivePool failed\");\n }\n\n /// Issue the specified amount of ZUSD to _account and increases the total active debt (_netDebtIncrease potentially includes a ZUSDFee)\n function _mintZusdAndIncreaseActivePoolDebt(\n IActivePool _activePool,\n IZUSDToken _zusdToken,\n address _account,\n uint256 _ZUSDAmount,\n uint256 _netDebtIncrease\n ) internal {\n _activePool.increaseZUSDDebt(_netDebtIncrease);\n _zusdToken.mint(_account, _ZUSDAmount);\n }\n\n /// Burn the specified amount of ZUSD from _account and decreases the total active debt\n function _burnZusdAndDecreaseActivePoolDebt(\n IActivePool _activePool,\n IZUSDToken _zusdToken,\n address _account,\n uint256 _ZUSD\n ) internal {\n _activePool.decreaseZUSDDebt(_ZUSD);\n _zusdToken.burn(_account, _ZUSD);\n }\n\n // --- 'Require' wrapper functions ---\n\n function _requireSingularCollChange(uint256 _collWithdrawal) internal view {\n require(\n msg.value == 0 || _collWithdrawal == 0,\n \"BorrowerOperations: Cannot withdraw and add coll\"\n );\n }\n\n function _requireCallerIsBorrower(address _borrower) internal view {\n require(\n msg.sender == _borrower,\n \"BorrowerOps: Caller must be the borrower for a withdrawal\"\n );\n }\n\n function _requireNonZeroAdjustment(uint256 _collWithdrawal, uint256 _ZUSDChange)\n internal\n view\n {\n require(\n msg.value != 0 || _collWithdrawal != 0 || _ZUSDChange != 0,\n \"BorrowerOps: There must be either a collateral change or a debt change\"\n );\n }\n\n function _requireTroveisActive(ITroveManager _troveManager, address _borrower) internal view {\n uint256 status = _troveManager.getTroveStatus(_borrower);\n require(status == 1, \"BorrowerOps: Trove does not exist or is closed\");\n }\n\n function _requireTroveisNotActive(ITroveManager _troveManager, address _borrower)\n internal\n view\n {\n uint256 status = _troveManager.getTroveStatus(_borrower);\n require(status != 1, \"BorrowerOps: Trove is active\");\n }\n\n function _requireNonZeroDebtChange(uint256 _ZUSDChange) internal pure {\n require(_ZUSDChange > 0, \"BorrowerOps: Debt increase requires non-zero debtChange\");\n }\n\n function _requireNotInRecoveryMode(uint256 _price) internal view {\n require(\n !_checkRecoveryMode(_price),\n \"BorrowerOps: Operation not permitted during Recovery Mode\"\n );\n }\n\n function _requireNoCollWithdrawal(uint256 _collWithdrawal) internal pure {\n require(\n _collWithdrawal == 0,\n \"BorrowerOps: Collateral withdrawal not permitted Recovery Mode\"\n );\n }\n\n function _requireValidAdjustmentInCurrentMode(\n bool _isRecoveryMode,\n uint256 _collWithdrawal,\n bool _isDebtIncrease,\n LocalVariables_adjustTrove memory _vars\n ) internal view {\n /*\n *In Recovery Mode, only allow:\n *\n * - Pure collateral top-up\n * - Pure debt repayment\n * - Collateral top-up with debt repayment\n * - A debt increase combined with a collateral top-up which makes the ICR >= 150% and improves the ICR (and by extension improves the TCR).\n *\n * In Normal Mode, ensure:\n *\n * - The new ICR is above MCR\n * - The adjustment won't pull the TCR below CCR\n */\n if (_isRecoveryMode) {\n _requireNoCollWithdrawal(_collWithdrawal);\n if (_isDebtIncrease) {\n _requireICRisAboveCCR(_vars.newICR);\n _requireNewICRisAboveOldICR(_vars.newICR, _vars.oldICR);\n }\n } else {\n // if Normal Mode\n _requireICRisAboveMCR(_vars.newICR);\n _vars.newTCR = _getNewTCRFromTroveChange(\n _vars.collChange,\n _vars.isCollIncrease,\n _vars.netDebtChange,\n _isDebtIncrease,\n _vars.price\n );\n _requireNewTCRisAboveCCR(_vars.newTCR);\n }\n }\n\n function _requireICRisAboveMCR(uint256 _newICR) internal view {\n require(\n _newICR >= liquityBaseParams.MCR(),\n \"BorrowerOps: An operation that would result in ICR < MCR is not permitted\"\n );\n }\n\n function _requireICRisAboveCCR(uint256 _newICR) internal view {\n require(\n _newICR >= liquityBaseParams.CCR(),\n \"BorrowerOps: Operation must leave trove with ICR >= CCR\"\n );\n }\n\n function _requireNewICRisAboveOldICR(uint256 _newICR, uint256 _oldICR) internal pure {\n require(\n _newICR >= _oldICR,\n \"BorrowerOps: Cannot decrease your Trove's ICR in Recovery Mode\"\n );\n }\n\n function _requireNewTCRisAboveCCR(uint256 _newTCR) internal view {\n require(\n _newTCR >= liquityBaseParams.CCR(),\n \"BorrowerOps: An operation that would result in TCR < CCR is not permitted\"\n );\n }\n\n function _requireAtLeastMinNetDebt(uint256 _netDebt) internal pure {\n require(\n _netDebt >= MIN_NET_DEBT,\n \"BorrowerOps: Trove's net debt must be greater than minimum\"\n );\n }\n\n function _requireValidZUSDRepayment(uint256 _currentDebt, uint256 _debtRepayment)\n internal\n pure\n {\n require(\n _debtRepayment <= _currentDebt.sub(ZUSD_GAS_COMPENSATION),\n \"BorrowerOps: Amount repaid must not be larger than the Trove's debt\"\n );\n }\n\n function _requireCallerIsStabilityPool() internal view {\n require(msg.sender == stabilityPoolAddress, \"BorrowerOps: Caller is not Stability Pool\");\n }\n\n function _requireSufficientZUSDBalance(\n IZUSDToken _zusdToken,\n address _borrower,\n uint256 _debtRepayment\n ) internal view {\n require(\n _zusdToken.balanceOf(_borrower) >= _debtRepayment,\n \"BorrowerOps: Caller doesnt have enough ZUSD to make repayment\"\n );\n }\n\n function _requireValidMaxFeePercentage(uint256 _maxFeePercentage, bool _isRecoveryMode)\n internal\n view\n {\n if (_isRecoveryMode) {\n require(\n _maxFeePercentage <= DECIMAL_PRECISION,\n \"Max fee percentage must less than or equal to 100%\"\n );\n } else {\n require(\n _maxFeePercentage >= liquityBaseParams.BORROWING_FEE_FLOOR() &&\n _maxFeePercentage <= DECIMAL_PRECISION,\n \"Max fee percentage must be between 0.5% and 100%\"\n );\n }\n }\n\n // --- ICR and TCR getters ---\n\n /// Compute the new collateral ratio, considering the change in coll and debt. Assumes 0 pending rewards.\n function _getNewNominalICRFromTroveChange(\n uint256 _coll,\n uint256 _debt,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease\n ) internal pure returns (uint256) {\n (uint256 newColl, uint256 newDebt) = _getNewTroveAmounts(\n _coll,\n _debt,\n _collChange,\n _isCollIncrease,\n _debtChange,\n _isDebtIncrease\n );\n\n uint256 newNICR = LiquityMath._computeNominalCR(newColl, newDebt);\n return newNICR;\n }\n\n /// Compute the new collateral ratio, considering the change in coll and debt. Assumes 0 pending rewards.\n function _getNewICRFromTroveChange(\n uint256 _coll,\n uint256 _debt,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease,\n uint256 _price\n ) internal pure returns (uint256) {\n (uint256 newColl, uint256 newDebt) = _getNewTroveAmounts(\n _coll,\n _debt,\n _collChange,\n _isCollIncrease,\n _debtChange,\n _isDebtIncrease\n );\n\n uint256 newICR = LiquityMath._computeCR(newColl, newDebt, _price);\n return newICR;\n }\n\n function _getNewTroveAmounts(\n uint256 _coll,\n uint256 _debt,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease\n ) internal pure returns (uint256, uint256) {\n uint256 newColl = _coll;\n uint256 newDebt = _debt;\n\n newColl = _isCollIncrease ? _coll.add(_collChange) : _coll.sub(_collChange);\n newDebt = _isDebtIncrease ? _debt.add(_debtChange) : _debt.sub(_debtChange);\n\n return (newColl, newDebt);\n }\n\n function _getNewTCRFromTroveChange(\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease,\n uint256 _price\n ) internal view returns (uint256) {\n uint256 totalColl = getEntireSystemColl();\n uint256 totalDebt = getEntireSystemDebt();\n\n totalColl = _isCollIncrease ? totalColl.add(_collChange) : totalColl.sub(_collChange);\n totalDebt = _isDebtIncrease ? totalDebt.add(_debtChange) : totalDebt.sub(_debtChange);\n\n uint256 newTCR = LiquityMath._computeCR(totalColl, totalDebt, _price);\n return newTCR;\n }\n\n function getCompositeDebt(uint256 _debt) external view override returns (uint256) {\n return _getCompositeDebt(_debt);\n }\n\n function BORROWING_FEE_FLOOR() external view override returns (uint256) {\n return liquityBaseParams.BORROWING_FEE_FLOOR();\n }\n\n function getMassetManager() external view override returns (IMassetManager) {\n return massetManager;\n }\n}\n" + }, + "contracts/BorrowerOperationsStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IActivePool.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/Mynt/IMassetManager.sol\";\n\ncontract BorrowerOperationsStorage is Ownable {\n string public constant NAME = \"BorrowerOperations\";\n\n // --- Connected contract declarations ---\n\n ITroveManager public troveManager;\n\n address stabilityPoolAddress;\n\n address gasPoolAddress;\n\n ICollSurplusPool collSurplusPool;\n\n IZEROStaking public zeroStaking;\n address public zeroStakingAddress;\n\n IZUSDToken public zusdToken;\n\n // A doubly linked list of Troves, sorted by their collateral ratios\n ISortedTroves public sortedTroves;\n\n IMassetManager public massetManager;\n IFeeDistributor public feeDistributor;\n}\n" + }, + "contracts/CollSurplusPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./CollSurplusPoolStorage.sol\";\n\ncontract CollSurplusPool is CollSurplusPoolStorage, CheckContract, ICollSurplusPool {\n using SafeMath for uint256;\n // --- Events ---\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n\n event CollBalanceUpdated(address indexed _account, uint256 _newBalance);\n event EtherSent(address _to, uint256 _amount);\n\n // --- Contract setters ---\n\n function setAddresses(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress\n ) external override onlyOwner {\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n\n borrowerOperationsAddress = _borrowerOperationsAddress;\n troveManagerAddress = _troveManagerAddress;\n activePoolAddress = _activePoolAddress;\n\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n }\n\n /** Returns the ETH state variable at ActivePool address.\n Not necessarily equal to the raw ether balance - ether can be forcibly sent to contracts. */\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n function getCollateral(address _account) external view override returns (uint256) {\n return balances[_account];\n }\n\n // --- Pool functionality ---\n\n function accountSurplus(address _account, uint256 _amount) external override {\n _requireCallerIsTroveManager();\n\n uint256 newAmount = balances[_account].add(_amount);\n balances[_account] = newAmount;\n\n emit CollBalanceUpdated(_account, newAmount);\n }\n\n function claimColl(address _account) external override {\n _requireCallerIsBorrowerOperations();\n uint256 claimableColl = balances[_account];\n require(claimableColl > 0, \"CollSurplusPool: No collateral available to claim\");\n\n balances[_account] = 0;\n emit CollBalanceUpdated(_account, 0);\n\n ETH = ETH.sub(claimableColl);\n emit EtherSent(_account, claimableColl);\n\n (bool success, ) = _account.call{ value: claimableColl }(\"\");\n require(success, \"CollSurplusPool: sending ETH failed\");\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsBorrowerOperations() internal view {\n require(\n msg.sender == borrowerOperationsAddress,\n \"CollSurplusPool: Caller is not Borrower Operations\"\n );\n }\n\n function _requireCallerIsTroveManager() internal view {\n require(msg.sender == troveManagerAddress, \"CollSurplusPool: Caller is not TroveManager\");\n }\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"CollSurplusPool: Caller is not Active Pool\");\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsActivePool();\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/CollSurplusPoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Dependencies/Ownable.sol\";\n\ncontract CollSurplusPoolStorage is Ownable {\n string public constant NAME = \"CollSurplusPool\";\n\n address public borrowerOperationsAddress;\n address public troveManagerAddress;\n address public activePoolAddress;\n\n // deposited ether tracker\n uint256 internal ETH;\n // Collateral surplus claimable by trove owners\n mapping(address => uint256) internal balances;\n}\n" + }, + "contracts/DefaultPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IDefaultPool.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./DefaultPoolStorage.sol\";\n\n/**\n * The Default Pool holds the ETH and ZUSD debt (but not ZUSD tokens) from liquidations that have been redistributed\n * to active troves but not yet \"applied\", i.e. not yet recorded on a recipient active trove's struct.\n *\n * When a trove makes an operation that applies its pending ETH and ZUSD debt, its pending ETH and ZUSD debt is moved\n * from the Default Pool to the Active Pool.\n */\ncontract DefaultPool is DefaultPoolStorage, CheckContract, IDefaultPool {\n using SafeMath for uint256;\n\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event DefaultPoolZUSDDebtUpdated(uint256 _ZUSDDebt);\n event DefaultPoolETHBalanceUpdated(uint256 _ETH);\n\n // --- Dependency setters ---\n\n function setAddresses(address _troveManagerAddress, address _activePoolAddress)\n external\n onlyOwner\n {\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n\n troveManagerAddress = _troveManagerAddress;\n activePoolAddress = _activePoolAddress;\n\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n }\n\n // --- Getters for public variables. Required by IPool interface ---\n\n /**\n * @return the ETH state variable.\n *\n * Not necessarily equal to the the contract's raw ETH balance - ether can be forcibly sent to contracts.\n */\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n function getZUSDDebt() external view override returns (uint256) {\n return ZUSDDebt;\n }\n\n // --- Pool functionality ---\n\n function sendETHToActivePool(uint256 _amount) external override {\n _requireCallerIsTroveManager();\n address activePool = activePoolAddress; // cache to save an SLOAD\n ETH = ETH.sub(_amount);\n emit DefaultPoolETHBalanceUpdated(ETH);\n emit EtherSent(activePool, _amount);\n\n (bool success, ) = activePool.call{ value: _amount }(\"\");\n require(success, \"DefaultPool: sending ETH failed\");\n }\n\n function increaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsTroveManager();\n ZUSDDebt = ZUSDDebt.add(_amount);\n emit DefaultPoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n function decreaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsTroveManager();\n ZUSDDebt = ZUSDDebt.sub(_amount);\n emit DefaultPoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"DefaultPool: Caller is not the ActivePool\");\n }\n\n function _requireCallerIsTroveManager() internal view {\n require(msg.sender == troveManagerAddress, \"DefaultPool: Caller is not the TroveManager\");\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsActivePool();\n ETH = ETH.add(msg.value);\n emit DefaultPoolETHBalanceUpdated(ETH);\n }\n}\n" + }, + "contracts/DefaultPoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract DefaultPoolStorage is Ownable {\n string public constant NAME = \"DefaultPool\";\n\n address public troveManagerAddress;\n address public activePoolAddress;\n uint256 internal ETH; // deposited ETH tracker\n uint256 internal ZUSDDebt; // debt\n}\n" + }, + "contracts/Dependencies/BaseMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\n\ncontract BaseMath {\n uint constant public DECIMAL_PRECISION = 1e18;\n}\n" + }, + "contracts/Dependencies/CheckContract.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n\ncontract CheckContract {\n /**\n * @dev Check that the account is an already deployed non-destroyed contract.\n * See: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L12\n */\n function checkContract(address _account) internal view {\n require(_account != address(0), \"Account cannot be zero address\");\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(_account) }\n require(size > 0, \"Account code size cannot be zero\");\n }\n}\n" + }, + "contracts/Dependencies/console.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// Buidler's helper contract for console logging\nlibrary console {\n\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n\tfunction log() internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log()\"));\n\t\tignored;\n\t}\tfunction logInt(int p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(int)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logUint(uint p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logString(string memory p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBool(bool p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logAddress(address p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes(bytes memory p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logByte(byte p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(byte)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes1(bytes1 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes1)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes2(bytes2 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes2)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes3(bytes3 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes3)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes4(bytes4 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes4)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes5(bytes5 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes5)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes6(bytes6 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes6)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes7(bytes7 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes7)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes8(bytes8 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes8)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes9(bytes9 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes9)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes10(bytes10 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes10)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes11(bytes11 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes11)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes12(bytes12 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes12)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes13(bytes13 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes13)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes14(bytes14 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes14)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes15(bytes15 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes15)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes16(bytes16 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes16)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes17(bytes17 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes17)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes18(bytes18 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes18)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes19(bytes19 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes19)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes20(bytes20 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes20)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes21(bytes21 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes21)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes22(bytes22 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes22)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes23(bytes23 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes23)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes24(bytes24 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes24)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes25(bytes25 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes25)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes26(bytes26 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes26)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes27(bytes27 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes27)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes28(bytes28 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes28)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes29(bytes29 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes29)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes30(bytes30 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes30)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes31(bytes31 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes31)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes32(bytes32 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes32)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(address p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n}\n" + }, + "contracts/Dependencies/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * Based on the OpenZeppelin IER20 interface:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol\n *\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n function increaseAllowance(address spender, uint256 addedValue) external returns (bool);\n function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n function name() external view returns (string memory);\n function symbol() external view returns (string memory);\n function decimals() external view returns (uint8);\n \n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}" + }, + "contracts/Dependencies/IERC2612.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * @dev Interface of the ERC2612 standard as defined in the EIP.\n *\n * Adds the {permit} method, which can be used to change one's\n * {IERC20-allowance} without having to send a transaction, by signing a\n * message. This allows users to spend tokens without having to hold Ether.\n *\n * See https://eips.ethereum.org/EIPS/eip-2612.\n * \n * Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\n */\ninterface IERC2612 {\n /**\n * @dev Sets `amount` as the allowance of `spender` over `owner`'s tokens,\n * given `owner`'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(address owner, address spender, uint256 amount, \n uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n \n /**\n * @dev Returns the current ERC2612 nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases `owner`'s nonce by one. This\n * prevents a signature from being used multiple times.\n *\n * `owner` can limit the time a Permit is valid for by setting `deadline` to \n * a value in the near future. The deadline argument can be set to uint(-1) to \n * create Permits that effectively never expire.\n */\n function nonces(address owner) external view returns (uint256);\n \n function version() external view returns (string memory);\n function permitTypeHash() external view returns (bytes32);\n function domainSeparator() external view returns (bytes32);\n}\n" + }, + "contracts/Dependencies/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * @title Initializable\n *\n * Based on OpenZeppelin's Initializable contract:\n * https://github.com/OpenZeppelin/openzeppelin-upgrades/blob/master/packages/core/contracts/Initializable.sol\n * \n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(\n initializing || isConstructor() || !initialized,\n \"Contract instance has already been initialized\"\n );\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n /// @dev Returns true if and only if the function is running in the constructor\n function isConstructor() private view returns (bool) {\n // extcodesize checks the size of the code stored in an address, and\n // address returns the current address. Since the code is still not\n // deployed when running a constructor, any checks on its code size will\n // yield zero, making it an effective way to detect if a contract is\n // under construction or not.\n address self = address(this);\n uint256 cs;\n assembly {\n cs := extcodesize(self)\n }\n return cs == 0;\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}\n" + }, + "contracts/Dependencies/LiquityBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./BaseMath.sol\";\nimport \"./LiquityMath.sol\";\nimport \"../Interfaces/IActivePool.sol\";\nimport \"../Interfaces/IDefaultPool.sol\";\nimport \"../Interfaces/IPriceFeed.sol\";\nimport \"../Interfaces/ILiquityBase.sol\";\nimport \"../Interfaces/ILiquityBaseParams.sol\";\n\n/**\n * Base contract for TroveManager, BorrowerOperations and StabilityPool. Contains global system constants and\n * common functions.\n */\ncontract LiquityBase is BaseMath, ILiquityBase {\n using SafeMath for uint256;\n\n uint256 public constant _100pct = 1000000000000000000; // 1e18 == 100%\n\n /// Amount of ZUSD to be locked in gas pool on opening troves\n uint256 public constant ZUSD_GAS_COMPENSATION = 20e18;\n\n /// Minimum amount of net ZUSD debt a trove must have\n uint256 public constant MIN_NET_DEBT = 180e18;\n\n IActivePool public activePool;\n\n IDefaultPool public defaultPool;\n\n IPriceFeed public override priceFeed;\n\n ILiquityBaseParams public override liquityBaseParams;\n\n // --- Gas compensation functions ---\n\n // Returns the composite debt (drawn debt + gas compensation) of a trove, for the purpose of ICR calculation\n function _getCompositeDebt(uint256 _debt) internal pure returns (uint256) {\n return _debt.add(ZUSD_GAS_COMPENSATION);\n }\n\n function _getNetDebt(uint256 _debt) internal pure returns (uint256) {\n return _debt.sub(ZUSD_GAS_COMPENSATION);\n }\n\n /// Return the amount of ETH to be drawn from a trove's collateral and sent as gas compensation.\n function _getCollGasCompensation(uint256 _entireColl) internal view returns (uint256) {\n return _entireColl / liquityBaseParams.PERCENT_DIVISOR();\n }\n\n function getEntireSystemColl() public view returns (uint256 entireSystemColl) {\n uint256 activeColl = activePool.getETH();\n uint256 liquidatedColl = defaultPool.getETH();\n\n return activeColl.add(liquidatedColl);\n }\n\n function getEntireSystemDebt() public view returns (uint256 entireSystemDebt) {\n uint256 activeDebt = activePool.getZUSDDebt();\n uint256 closedDebt = defaultPool.getZUSDDebt();\n\n return activeDebt.add(closedDebt);\n }\n\n function _getTCR(uint256 _price) internal view returns (uint256 TCR) {\n uint256 entireSystemColl = getEntireSystemColl();\n uint256 entireSystemDebt = getEntireSystemDebt();\n\n TCR = LiquityMath._computeCR(entireSystemColl, entireSystemDebt, _price);\n\n return TCR;\n }\n\n function _checkRecoveryMode(uint256 _price) internal view returns (bool) {\n uint256 TCR = _getTCR(_price);\n\n return TCR < liquityBaseParams.CCR();\n }\n\n function _requireUserAcceptsFee(\n uint256 _fee,\n uint256 _amount,\n uint256 _maxFeePercentage\n ) internal pure {\n uint256 feePercentage = _fee.mul(DECIMAL_PRECISION).div(_amount);\n require(feePercentage <= _maxFeePercentage, \"Fee exceeded provided maximum\");\n }\n}\n" + }, + "contracts/Dependencies/LiquityMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./SafeMath.sol\";\nimport \"./console.sol\";\n\nlibrary LiquityMath {\n using SafeMath for uint;\n\n uint internal constant DECIMAL_PRECISION = 1e18;\n\n /* Precision for Nominal ICR (independent of price). Rationale for the value:\n *\n * - Making it “too high” could lead to overflows.\n * - Making it “too low” could lead to an ICR equal to zero, due to truncation from Solidity floor division. \n *\n * This value of 1e20 is chosen for safety: the NICR will only overflow for numerator > ~1e39 ETH,\n * and will only truncate to 0 if the denominator is at least 1e20 times greater than the numerator.\n *\n */\n uint internal constant NICR_PRECISION = 1e20;\n\n function _min(uint _a, uint _b) internal pure returns (uint) {\n return (_a < _b) ? _a : _b;\n }\n\n function _max(uint _a, uint _b) internal pure returns (uint) {\n return (_a >= _b) ? _a : _b;\n }\n\n /* \n * Multiply two decimal numbers and use normal rounding rules:\n * -round product up if 19'th mantissa digit >= 5\n * -round product down if 19'th mantissa digit < 5\n *\n * Used only inside the exponentiation, _decPow().\n */\n function decMul(uint x, uint y) internal pure returns (uint decProd) {\n uint prod_xy = x.mul(y);\n\n decProd = prod_xy.add(DECIMAL_PRECISION / 2).div(DECIMAL_PRECISION);\n }\n\n /* \n * _decPow: Exponentiation function for 18-digit decimal base, and integer exponent n.\n * \n * Uses the efficient \"exponentiation by squaring\" algorithm. O(log(n)) complexity. \n * \n * Called by two functions that represent time in units of minutes:\n * 1) TroveManager._calcDecayedBaseRate\n * 2) CommunityIssuance._getCumulativeIssuanceFraction \n * \n * The exponent is capped to avoid reverting due to overflow. The cap 525600000 equals\n * \"minutes in 1000 years\": 60 * 24 * 365 * 1000\n * \n * If a period of > 1000 years is ever used as an exponent in either of the above functions, the result will be\n * negligibly different from just passing the cap, since: \n *\n * In function 1), the decayed base rate will be 0 for 1000 years or > 1000 years\n * In function 2), the difference in tokens issued at 1000 years and any time > 1000 years, will be negligible\n */\n function _decPow(uint _base, uint _minutes) internal pure returns (uint) {\n \n if (_minutes > 525600000) {_minutes = 525600000;} // cap to avoid overflow\n \n if (_minutes == 0) {return DECIMAL_PRECISION;}\n\n uint y = DECIMAL_PRECISION;\n uint x = _base;\n uint n = _minutes;\n\n // Exponentiation-by-squaring\n while (n > 1) {\n if (n % 2 == 0) {\n x = decMul(x, x);\n n = n.div(2);\n } else { // if (n % 2 != 0)\n y = decMul(x, y);\n x = decMul(x, x);\n n = (n.sub(1)).div(2);\n }\n }\n\n return decMul(x, y);\n }\n\n function _getAbsoluteDifference(uint _a, uint _b) internal pure returns (uint) {\n return (_a >= _b) ? _a.sub(_b) : _b.sub(_a);\n }\n\n function _computeNominalCR(uint _coll, uint _debt) internal pure returns (uint) {\n if (_debt > 0) {\n return _coll.mul(NICR_PRECISION).div(_debt);\n }\n // Return the maximal value for uint256 if the Trove has a debt of 0. Represents \"infinite\" CR.\n else { // if (_debt == 0)\n return 2**256 - 1;\n }\n }\n\n function _computeCR(uint _coll, uint _debt, uint _price) internal pure returns (uint) {\n if (_debt > 0) {\n uint newCollRatio = _coll.mul(_price).div(_debt);\n\n return newCollRatio;\n }\n // Return the maximal value for uint256 if the Trove has a debt of 0. Represents \"infinite\" CR.\n else { // if (_debt == 0)\n return 2**256 - 1; \n }\n }\n}\n" + }, + "contracts/Dependencies/LiquitySafeMath128.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// uint128 addition and subtraction, with overflow protection.\n\nlibrary LiquitySafeMath128 {\n function add(uint128 a, uint128 b) internal pure returns (uint128) {\n uint128 c = a + b;\n require(c >= a, \"LiquitySafeMath128: addition overflow\");\n\n return c;\n }\n \n function sub(uint128 a, uint128 b) internal pure returns (uint128) {\n require(b <= a, \"LiquitySafeMath128: subtraction overflow\");\n uint128 c = a - b;\n\n return c;\n }\n}" + }, + "contracts/Dependencies/Mynt/IDLLR.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\nimport \"../IERC20.sol\";\n\n/// Public interface for Sovryn Dollar DLLR (Meta Asset Token of Sovryn Mynt) exposing specific functions\ninterface IDLLR is IERC20 {\n /**\n * @notice Only owner can transfer the token.\n * @notice destination cannot be:\n * - zero (0x0) address.\n *\n * @param _recipient Recipient of the token.\n * @param _amount The amount of token that will be transferred.\n *\n * @return true / false.\n */\n function transfer(address _recipient, uint256 _amount) external override returns (bool);\n\n /**\n * @notice Only owner who can transfer the token.\n * @notice destination cannot be:\n * - zero (0x0) address.\n *\n * @param _from Sender of the token.\n * @param _to Recipient of the token.\n * @param _amount The amount of token that will be transferred.\n *\n * @return true / false.\n */\n function transferFrom(\n address _from,\n address _to,\n uint256 _amount\n ) external override returns (bool);\n\n /**\n * @notice transfer utilizing EIP-2612, to reduce the additional sending transaction for doing the approval to the spender.\n *\n * @notice destination cannot be:\n * - zero (0x0) address.\n *\n * @dev By calling this function, the allowance will be overwritten by the total amount.\n *\n * @param _from Sender of the token.\n * @param _to Recipient of the token.\n * @param _amount The amount of the token that will be transferred.\n * @param _deadline Expiration time of the signature.\n * @param _v Last 1 byte of ECDSA signature.\n * @param _r First 32 bytes of ECDSA signature.\n * @param _s 32 bytes after _r in ECDSA signature.\n */\n function transferWithPermit(\n address _from,\n address _to,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external;\n\n /**\n * @notice Approves and then calls the receiving contract.\n * Useful to encapsulate sending tokens to a contract in one call.\n * Solidity has no native way to send tokens to contracts.\n * ERC-20 tokens require approval to be spent by third parties, such as a contract in this case.\n * @param _spender The contract address to spend the tokens.\n * @param _amount The amount of tokens to be sent.\n * @param _data Parameters for the contract call, such as endpoint signature.\n */\n function approveAndCall(address _spender, uint256 _amount, bytes calldata _data) external;\n}\n" + }, + "contracts/Dependencies/Mynt/IMassetManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IMassetManager {\n struct PermitParams {\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n function mintTo(\n address _bAsset,\n uint256 _bAssetQuantity,\n address _recipient\n ) external returns (uint256);\n\n function getToken() external view returns (address);\n\n /**\n * @dev Credits a recipient with a certain quantity of selected bAsset, in exchange for burning the\n * relative mAsset quantity from the sender. Sender also incurs a small fee, if any.\n * @param _bAsset Address of the bAsset to redeem.\n * @param _massetQuantity Units of the masset to redeem.\n * @param _recipient Address to credit with withdrawn bAssets.\n * @return massetRedeemed Relative number of mAsset units burned to pay for the bAssets.\n */\n function redeemTo(\n address _bAsset,\n uint256 _massetQuantity,\n address _recipient\n ) external returns (uint256 massetRedeemed);\n}\n" + }, + "contracts/Dependencies/Mynt/MyntLib.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IMassetManager.sol\";\nimport \"./IDLLR.sol\";\nimport \"../SafeMath.sol\";\n\nlibrary MyntLib {\n using SafeMath for uint256;\n\n /**\n * @notice Convert DLLR _dllrAmount to _toToken utilizing EIP-2612 permit\n * to reduce the additional sending transaction for doing the approval to the spender.\n *\n * @param _myntMassetManager Mynt protocol MassetManager contract address - needed for integration\n * @param _dllrAmount The amount of the DLLR (mAsset) token that will be burned in exchange for _toToken\n * @param _toToken bAsset token address to wothdraw from DLLR\n * @param _permitParams EIP-2612 permit params:\n * _deadline Expiration time of the signature.\n * _v Last 1 byte of ECDSA signature.\n * _r First 32 bytes of ECDSA signature.\n * _s 32 bytes after _r in ECDSA signature.\n * @return redeemed ZUSD amount\n */\n function redeemZusdFromDllrWithPermit(\n IMassetManager _myntMassetManager,\n uint256 _dllrAmount,\n address _toToken,\n IMassetManager.PermitParams calldata _permitParams\n ) internal returns (uint256) {\n IDLLR dllr = IDLLR(_myntMassetManager.getToken());\n uint256 thisBalanceBefore = dllr.balanceOf(address(this));\n address thisAddress = address(this);\n dllr.transferWithPermit(\n msg.sender,\n thisAddress,\n _dllrAmount,\n _permitParams.deadline,\n _permitParams.v,\n _permitParams.r,\n _permitParams.s\n );\n require(\n dllr.balanceOf(thisAddress).sub(thisBalanceBefore) == _dllrAmount,\n \"DLLR transferred amount validation failed\"\n );\n return _myntMassetManager.redeemTo(_toToken, _dllrAmount, msg.sender);\n }\n}\n" + }, + "contracts/Dependencies/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * Based on OpenZeppelin's Ownable contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n *\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\ncontract Ownable {\n bytes32 private constant KEY_OWNER = keccak256(\"key.ownable.owner\");\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () internal {\n _setOwner(msg.sender);\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(msg.sender == getOwner(), \"Ownable:: access denied\");\n _;\n }\n\n /**\n * @notice Set address of the owner.\n * @param _owner Address of the owner.\n * */\n function _setOwner(address _owner) internal {\n require(_owner != address(0), \"Ownable::setOwner: invalid address\");\n emit OwnershipTransferred(getOwner(), _owner);\n\n bytes32 key = KEY_OWNER;\n assembly {\n sstore(key, _owner)\n }\n }\n\n /**\n * @notice Set address of the owner (only owner can call this function)\n * @param _owner Address of the owner.\n * */\n function setOwner(address _owner) public onlyOwner {\n _setOwner(_owner);\n }\n\n /**\n * @notice Return address of the owner.\n * @return _owner Address of the owner.\n * */\n function getOwner() public view returns (address _owner) {\n bytes32 key = KEY_OWNER;\n assembly {\n _owner := sload(key)\n }\n }\n}\n" + }, + "contracts/Dependencies/PriceFeed/IExternalPriceFeed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/// @title A generic interface for external price providers \ninterface IExternalPriceFeed {\n /// @dev The returned price should be 18-decimal value\n /// @return the prive value and a boolean stating if the query was successful\n function latestAnswer() external view returns (uint256, bool);\n}\n" + }, + "contracts/Dependencies/PriceFeed/MocMedianizer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./IExternalPriceFeed.sol\";\n\ninterface IMoCBaseOracle {\n function peek() external view returns (bytes32, bool);\n}\n\ncontract MoCMedianizer is IExternalPriceFeed {\n IMoCBaseOracle medianizer;\n\n constructor(address _medianizer) public {\n medianizer = IMoCBaseOracle(_medianizer);\n }\n\n function latestAnswer() external view override returns (uint256, bool) {\n (bytes32 price, bool success) = medianizer.peek();\n return (uint256(price), success);\n }\n}\n" + }, + "contracts/Dependencies/PriceFeed/RskOracle.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./IExternalPriceFeed.sol\";\n\ninterface IRSKOracle {\n function getPricing() external view returns (uint256, uint256);\n}\n\ncontract RskOracle is IExternalPriceFeed {\n \n IRSKOracle rskOracle;\n\n constructor(address _address) public {\n rskOracle = IRSKOracle(_address);\n }\n\n function latestAnswer() external view override returns (uint256, bool) {\n (uint256 price, ) = rskOracle.getPricing();\n return (price, true);\n }\n}\n" + }, + "contracts/Dependencies/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * Based on OpenZeppelin's SafeMath:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol\n *\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "contracts/Dependencies/TroveManagerBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IActivePool.sol\";\nimport \"../Interfaces/IDefaultPool.sol\";\nimport \"../Interfaces/IZUSDToken.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\nimport \"../Interfaces/ISortedTroves.sol\";\nimport \"../Interfaces/ICollSurplusPool.sol\";\nimport \"../TroveManagerStorage.sol\";\nimport \"./LiquityBase.sol\";\n\ncontract TroveManagerBase is LiquityBase, TroveManagerStorage {\n uint256 public constant SECONDS_IN_ONE_MINUTE = 60;\n\n uint256 public constant MINUTE_DECAY_FACTOR = 999037758833783000;\n\n /// During bootsrap period redemptions are not allowed\n uint256 public immutable BOOTSTRAP_PERIOD;\n\n /**\n BETA: 18 digit decimal. Parameter by which to divide the redeemed fraction, in order to calc the new base rate from a redemption.\n Corresponds to (1 / ALPHA) in the white paper.\n */\n uint256 public constant BETA = 2;\n\n /**\n --- Variable container structs for liquidations ---\n \n These structs are used to hold, return and assign variables inside the liquidation functions,\n in order to avoid the error: \"CompilerError: Stack too deep\".\n */\n\n struct LocalVariables_OuterLiquidationFunction {\n uint256 price;\n uint256 ZUSDInStabPool;\n bool recoveryModeAtStart;\n uint256 liquidatedDebt;\n uint256 liquidatedColl;\n }\n\n struct LocalVariables_InnerSingleLiquidateFunction {\n uint256 collToLiquidate;\n uint256 pendingDebtReward;\n uint256 pendingCollReward;\n }\n\n struct LocalVariables_LiquidationSequence {\n uint256 remainingZUSDInStabPool;\n uint256 i;\n uint256 ICR;\n address user;\n bool backToNormalMode;\n uint256 entireSystemDebt;\n uint256 entireSystemColl;\n }\n\n struct LiquidationValues {\n uint256 entireTroveDebt;\n uint256 entireTroveColl;\n uint256 collGasCompensation;\n uint256 ZUSDGasCompensation;\n uint256 debtToOffset;\n uint256 collToSendToSP;\n uint256 debtToRedistribute;\n uint256 collToRedistribute;\n uint256 collSurplus;\n }\n\n struct LiquidationTotals {\n uint256 totalCollInSequence;\n uint256 totalDebtInSequence;\n uint256 totalCollGasCompensation;\n uint256 totalZUSDGasCompensation;\n uint256 totalDebtToOffset;\n uint256 totalCollToSendToSP;\n uint256 totalDebtToRedistribute;\n uint256 totalCollToRedistribute;\n uint256 totalCollSurplus;\n }\n\n struct ContractsCache {\n IActivePool activePool;\n IDefaultPool defaultPool;\n IZUSDToken zusdToken;\n IZEROStaking zeroStaking;\n ISortedTroves sortedTroves;\n ICollSurplusPool collSurplusPool;\n address gasPoolAddress;\n }\n // --- Variable container structs for redemptions ---\n\n struct RedemptionTotals {\n uint256 remainingZUSD;\n uint256 totalZUSDToRedeem;\n uint256 totalETHDrawn;\n uint256 ETHFee;\n uint256 ETHToSendToRedeemer;\n uint256 decayedBaseRate;\n uint256 price;\n uint256 totalZUSDSupplyAtStart;\n }\n\n struct SingleRedemptionValues {\n uint256 ZUSDLot;\n uint256 ETHLot;\n bool cancelledPartial;\n }\n\n // --- Events ---\n\n event Liquidation(\n uint256 _liquidatedDebt,\n uint256 _liquidatedColl,\n uint256 _collGasCompensation,\n uint256 _ZUSDGasCompensation\n );\n event Redemption(\n uint256 _attemptedZUSDAmount,\n uint256 _actualZUSDAmount,\n uint256 _ETHSent,\n uint256 _ETHFee\n );\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 _stake,\n TroveManagerOperation _operation\n );\n event TroveLiquidated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n TroveManagerOperation _operation\n );\n event BaseRateUpdated(uint256 _baseRate);\n event LastFeeOpTimeUpdated(uint256 _lastFeeOpTime);\n event TotalStakesUpdated(uint256 _newTotalStakes);\n event SystemSnapshotsUpdated(uint256 _totalStakesSnapshot, uint256 _totalCollateralSnapshot);\n event LTermsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveSnapshotsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveIndexUpdated(address _borrower, uint256 _newIndex);\n\n enum TroveManagerOperation {\n applyPendingRewards,\n liquidateInNormalMode,\n liquidateInRecoveryMode,\n redeemCollateral\n }\n\n constructor(uint256 _bootstrapPeriod) public {\n BOOTSTRAP_PERIOD = _bootstrapPeriod;\n }\n\n /// Return the current collateral ratio (ICR) of a given Trove. Takes a trove's pending coll and debt rewards from redistributions into account.\n function _getCurrentICR(address _borrower, uint256 _price) public view returns (uint256) {\n (uint256 currentETH, uint256 currentZUSDDebt) = _getCurrentTroveAmounts(_borrower);\n\n uint256 ICR = LiquityMath._computeCR(currentETH, currentZUSDDebt, _price);\n return ICR;\n }\n\n function _getCurrentTroveAmounts(address _borrower) internal view returns (uint256, uint256) {\n uint256 pendingETHReward = _getPendingETHReward(_borrower);\n uint256 pendingZUSDDebtReward = _getPendingZUSDDebtReward(_borrower);\n\n uint256 currentETH = Troves[_borrower].coll.add(pendingETHReward);\n uint256 currentZUSDDebt = Troves[_borrower].debt.add(pendingZUSDDebtReward);\n\n return (currentETH, currentZUSDDebt);\n }\n\n /// Get the borrower's pending accumulated ETH reward, earned by their stake\n function _getPendingETHReward(address _borrower) public view returns (uint256) {\n uint256 snapshotETH = rewardSnapshots[_borrower].ETH;\n uint256 rewardPerUnitStaked = L_ETH.sub(snapshotETH);\n\n if (rewardPerUnitStaked == 0 || Troves[_borrower].status != Status.active) {\n return 0;\n }\n\n uint256 stake = Troves[_borrower].stake;\n\n uint256 pendingETHReward = stake.mul(rewardPerUnitStaked).div(DECIMAL_PRECISION);\n\n return pendingETHReward;\n }\n\n /// Get the borrower's pending accumulated ZUSD reward, earned by their stake\n function _getPendingZUSDDebtReward(address _borrower) public view returns (uint256) {\n uint256 snapshotZUSDDebt = rewardSnapshots[_borrower].ZUSDDebt;\n uint256 rewardPerUnitStaked = L_ZUSDDebt.sub(snapshotZUSDDebt);\n\n if (rewardPerUnitStaked == 0 || Troves[_borrower].status != Status.active) {\n return 0;\n }\n\n uint256 stake = Troves[_borrower].stake;\n\n uint256 pendingZUSDDebtReward = stake.mul(rewardPerUnitStaked).div(DECIMAL_PRECISION);\n\n return pendingZUSDDebtReward;\n }\n\n /// Add the borrowers's coll and debt rewards earned from redistributions, to their Trove\n function _applyPendingRewards(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n address _borrower\n ) internal {\n if (_hasPendingRewards(_borrower)) {\n _requireTroveIsActive(_borrower);\n\n // Compute pending rewards\n uint256 pendingETHReward = _getPendingETHReward(_borrower);\n uint256 pendingZUSDDebtReward = _getPendingZUSDDebtReward(_borrower);\n\n // Apply pending rewards to trove's state\n Troves[_borrower].coll = Troves[_borrower].coll.add(pendingETHReward);\n Troves[_borrower].debt = Troves[_borrower].debt.add(pendingZUSDDebtReward);\n\n _updateTroveRewardSnapshots(_borrower);\n\n // Transfer from DefaultPool to ActivePool\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n pendingZUSDDebtReward,\n pendingETHReward\n );\n\n emit TroveUpdated(\n _borrower,\n Troves[_borrower].debt,\n Troves[_borrower].coll,\n Troves[_borrower].stake,\n TroveManagerOperation.applyPendingRewards\n );\n }\n }\n\n function _hasPendingRewards(address _borrower) public view returns (bool) {\n /*\n * A Trove has pending rewards if its snapshot is less than the current rewards per-unit-staked sum:\n * this indicates that rewards have occured since the snapshot was made, and the user therefore has\n * pending rewards\n */\n if (Troves[_borrower].status != Status.active) {\n return false;\n }\n\n return (rewardSnapshots[_borrower].ETH < L_ETH);\n }\n\n function _updateTroveRewardSnapshots(address _borrower) internal {\n rewardSnapshots[_borrower].ETH = L_ETH;\n rewardSnapshots[_borrower].ZUSDDebt = L_ZUSDDebt;\n emit TroveSnapshotsUpdated(L_ETH, L_ZUSDDebt);\n }\n\n /// Move a Trove's pending debt and collateral rewards from distributions, from the Default Pool to the Active Pool\n function _movePendingTroveRewardsToActivePool(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _ZUSD,\n uint256 _ETH\n ) internal {\n _defaultPool.decreaseZUSDDebt(_ZUSD);\n _activePool.increaseZUSDDebt(_ZUSD);\n _defaultPool.sendETHToActivePool(_ETH);\n }\n\n /// Remove borrower's stake from the totalStakes sum, and set their stake to 0\n function _removeStake(address _borrower) internal {\n uint256 stake = Troves[_borrower].stake;\n totalStakes = totalStakes.sub(stake);\n Troves[_borrower].stake = 0;\n }\n\n function _closeTrove(address _borrower, Status closedStatus) internal {\n assert(closedStatus != Status.nonExistent && closedStatus != Status.active);\n\n uint256 TroveOwnersArrayLength = TroveOwners.length;\n _requireMoreThanOneTroveInSystem(TroveOwnersArrayLength);\n\n Troves[_borrower].status = closedStatus;\n Troves[_borrower].coll = 0;\n Troves[_borrower].debt = 0;\n\n rewardSnapshots[_borrower].ETH = 0;\n rewardSnapshots[_borrower].ZUSDDebt = 0;\n\n _removeTroveOwner(_borrower, TroveOwnersArrayLength);\n sortedTroves.remove(_borrower);\n }\n\n /// Update borrower's stake based on their latest collateral value\n function _updateStakeAndTotalStakes(address _borrower) internal returns (uint256) {\n uint256 newStake = _computeNewStake(Troves[_borrower].coll);\n uint256 oldStake = Troves[_borrower].stake;\n Troves[_borrower].stake = newStake;\n\n totalStakes = totalStakes.sub(oldStake).add(newStake);\n emit TotalStakesUpdated(totalStakes);\n\n return newStake;\n }\n\n // Calculate a new stake based on the snapshots of the totalStakes and totalCollateral taken at the last liquidation\n function _computeNewStake(uint256 _coll) internal view returns (uint256) {\n uint256 stake;\n if (totalCollateralSnapshot == 0) {\n stake = _coll;\n } else {\n /*\n * The following assert() holds true because:\n * - The system always contains >= 1 trove\n * - When we close or liquidate a trove, we redistribute the pending rewards, so if all troves were closed/liquidated,\n * rewards would’ve been emptied and totalCollateralSnapshot would be zero too.\n */\n assert(totalStakesSnapshot > 0);\n stake = _coll.mul(totalStakesSnapshot).div(totalCollateralSnapshot);\n }\n return stake;\n }\n\n function _calcDecayedBaseRate() internal view returns (uint256) {\n uint256 minutesPassed = _minutesPassedSinceLastFeeOp();\n uint256 decayFactor = LiquityMath._decPow(MINUTE_DECAY_FACTOR, minutesPassed);\n\n return baseRate.mul(decayFactor).div(DECIMAL_PRECISION);\n }\n\n function _minutesPassedSinceLastFeeOp() internal view returns (uint256) {\n return (block.timestamp.sub(lastFeeOperationTime)).div(SECONDS_IN_ONE_MINUTE);\n }\n\n // Update the last fee operation time only if time passed >= decay interval. This prevents base rate griefing.\n function _updateLastFeeOpTime() internal {\n uint256 timePassed = block.timestamp.sub(lastFeeOperationTime);\n\n if (timePassed >= SECONDS_IN_ONE_MINUTE) {\n lastFeeOperationTime = block.timestamp;\n emit LastFeeOpTimeUpdated(block.timestamp);\n }\n }\n\n function _calcRedemptionFee(\n uint256 _redemptionRate,\n uint256 _ETHDrawn\n ) internal pure returns (uint256) {\n uint256 redemptionFee = _redemptionRate.mul(_ETHDrawn).div(DECIMAL_PRECISION);\n require(\n redemptionFee < _ETHDrawn,\n \"TroveManager: Fee would eat up all returned collateral\"\n );\n return redemptionFee;\n }\n\n function _getRedemptionRate() public view returns (uint256) {\n return _calcRedemptionRate(baseRate);\n }\n\n function _getRedemptionFee(uint256 _ETHDrawn) internal view returns (uint256) {\n return _calcRedemptionFee(_getRedemptionRate(), _ETHDrawn);\n }\n\n function _calcRedemptionRate(uint256 _baseRate) internal view returns (uint256) {\n return\n LiquityMath._min(\n liquityBaseParams.REDEMPTION_FEE_FLOOR().add(_baseRate),\n DECIMAL_PRECISION // cap at a maximum of 100%\n );\n }\n\n /**\n Remove a Trove owner from the TroveOwners array, not preserving array order. Removing owner 'B' does the following:\n [A B C D E] => [A E C D], and updates E's Trove struct to point to its new array index.\n */\n function _removeTroveOwner(address _borrower, uint256 TroveOwnersArrayLength) internal {\n Status troveStatus = Troves[_borrower].status;\n // It’s set in caller function `_closeTrove`\n assert(troveStatus != Status.nonExistent && troveStatus != Status.active);\n\n uint128 index = Troves[_borrower].arrayIndex;\n uint256 length = TroveOwnersArrayLength;\n uint256 idxLast = length.sub(1);\n\n assert(index <= idxLast);\n\n address addressToMove = TroveOwners[idxLast];\n\n TroveOwners[index] = addressToMove;\n Troves[addressToMove].arrayIndex = index;\n emit TroveIndexUpdated(addressToMove, index);\n\n TroveOwners.pop();\n }\n\n // --- 'require' wrapper functions ---\n\n function _requireCallerIsBorrowerOperations() internal view {\n require(\n msg.sender == borrowerOperationsAddress,\n \"TroveManager: Caller is not the BorrowerOperations contract\"\n );\n }\n\n function _requireTroveIsActive(address _borrower) internal view {\n require(\n Troves[_borrower].status == Status.active,\n \"TroveManager: Trove does not exist or is closed\"\n );\n }\n\n function _requireZUSDBalanceCoversRedemption(\n IZUSDToken _zusdToken,\n address _redeemer,\n uint256 _amount\n ) internal view {\n require(\n _zusdToken.balanceOf(_redeemer) >= _amount,\n \"TroveManager: Requested redemption amount must be <= user's ZUSD token balance\"\n );\n }\n\n function _requireMoreThanOneTroveInSystem(uint256 TroveOwnersArrayLength) internal view {\n require(\n TroveOwnersArrayLength > 1 && sortedTroves.getSize() > 1,\n \"TroveManager: Only one trove in the system\"\n );\n }\n\n function _requireAmountGreaterThanZero(uint256 _amount) internal pure {\n require(_amount > 0, \"TroveManager: Amount must be greater than zero\");\n }\n\n function _requireTCRoverMCR(uint256 _price) internal view {\n require(\n _getTCR(_price) >= liquityBaseParams.MCR(),\n \"TroveManager: Cannot redeem when TCR < MCR\"\n );\n }\n\n function _requireAfterBootstrapPeriod() internal view {\n uint256 systemDeploymentTime = _zeroToken.getDeploymentStartTime();\n require(\n block.timestamp >= systemDeploymentTime.add(BOOTSTRAP_PERIOD),\n \"TroveManager: Redemptions are not allowed during bootstrap phase\"\n );\n }\n\n function _requireValidMaxFeePercentage(uint256 _maxFeePercentage) internal view {\n require(\n _maxFeePercentage >= liquityBaseParams.REDEMPTION_FEE_FLOOR() &&\n _maxFeePercentage <= DECIMAL_PRECISION,\n \"Max fee percentage must be between 0.5% and 100%\"\n );\n }\n}\n" + }, + "contracts/Dependencies/TroveManagerRedeemOps.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../Dependencies/Mynt/MyntLib.sol\";\nimport \"../Interfaces/IBorrowerOperations.sol\";\nimport \"./TroveManagerBase.sol\";\n\n/// This contract is designed to be used via delegatecall from the TroveManager contract\n/// TroveManagerBase constructor param is bootsrap period when redemptions are not allowed\ncontract TroveManagerRedeemOps is TroveManagerBase {\n /** Send _ZUSDamount ZUSD to the system and redeem the corresponding amount of collateral from as many Troves as are needed to fill the redemption\n request. Applies pending rewards to a Trove before reducing its debt and coll.\n \n Note that if _amount is very large, this function can run out of gas, specially if traversed troves are small. This can be easily avoided by\n splitting the total _amount in appropriate chunks and calling the function multiple times.\n \n Param `_maxIterations` can also be provided, so the loop through Troves is capped (if it’s zero, it will be ignored).This makes it easier to\n avoid OOG for the frontend, as only knowing approximately the average cost of an iteration is enough, without needing to know the “topology”\n of the trove list. It also avoids the need to set the cap in stone in the contract, nor doing gas calculations, as both gas price and opcode\n costs can vary.\n \n All Troves that are redeemed from -- with the likely exception of the last one -- will end up with no debt left, therefore they will be closed.\n If the last Trove does have some remaining debt, it has a finite ICR, and the reinsertion could be anywhere in the list, therefore it requires a hint.\n A frontend should use getRedemptionHints() to calculate what the ICR of this Trove will be after redemption, and pass a hint for its position\n in the sortedTroves list along with the ICR value that the hint was found for.\n \n If another transaction modifies the list between calling getRedemptionHints() and passing the hints to redeemCollateral(), it\n is very likely that the last (partially) redeemed Trove would end up with a different ICR than what the hint is for. In this case the\n redemption will stop after the last completely redeemed Trove and the sender will keep the remaining ZUSD amount, which they can attempt\n to redeem later.\n */\n\n constructor(uint256 _bootstrapPeriod) public TroveManagerBase(_bootstrapPeriod) {}\n\n function redeemCollateral(\n uint256 _ZUSDamount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage\n ) external {\n _redeemCollateral(\n _ZUSDamount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n _maxIterations,\n _maxFeePercentage\n );\n }\n\n function _redeemCollateral(\n uint256 _ZUSDamount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage\n ) internal {\n ContractsCache memory contractsCache = ContractsCache(\n activePool,\n defaultPool,\n _zusdToken,\n _zeroStaking,\n sortedTroves,\n collSurplusPool,\n gasPoolAddress\n );\n RedemptionTotals memory totals;\n\n _requireValidMaxFeePercentage(_maxFeePercentage);\n _requireAfterBootstrapPeriod();\n totals.price = priceFeed.fetchPrice();\n _requireTCRoverMCR(totals.price);\n _requireAmountGreaterThanZero(_ZUSDamount);\n _requireZUSDBalanceCoversRedemption(contractsCache.zusdToken, msg.sender, _ZUSDamount);\n\n totals.totalZUSDSupplyAtStart = getEntireSystemDebt();\n // Confirm redeemer's balance is less than total ZUSD supply\n assert(contractsCache.zusdToken.balanceOf(msg.sender) <= totals.totalZUSDSupplyAtStart);\n\n totals.remainingZUSD = _ZUSDamount;\n address currentBorrower;\n\n if (\n _isValidFirstRedemptionHint(\n contractsCache.sortedTroves,\n _firstRedemptionHint,\n totals.price\n )\n ) {\n currentBorrower = _firstRedemptionHint;\n } else {\n currentBorrower = contractsCache.sortedTroves.getLast();\n // Find the first trove with ICR >= MCR\n while (\n currentBorrower != address(0) &&\n _getCurrentICR(currentBorrower, totals.price) < liquityBaseParams.MCR()\n ) {\n currentBorrower = contractsCache.sortedTroves.getPrev(currentBorrower);\n }\n }\n\n // Loop through the Troves starting from the one with lowest collateral ratio until _amount of ZUSD is exchanged for collateral\n if (_maxIterations == 0) {\n _maxIterations = uint256(-1);\n }\n while (currentBorrower != address(0) && totals.remainingZUSD > 0 && _maxIterations > 0) {\n _maxIterations--;\n // Save the address of the Trove preceding the current one, before potentially modifying the list\n address nextUserToCheck = contractsCache.sortedTroves.getPrev(currentBorrower);\n\n _applyPendingRewards(\n contractsCache.activePool,\n contractsCache.defaultPool,\n currentBorrower\n );\n\n SingleRedemptionValues memory singleRedemption = _redeemCollateralFromTrove(\n contractsCache,\n currentBorrower,\n totals.remainingZUSD,\n totals.price,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR\n );\n\n if (singleRedemption.cancelledPartial) break; // Partial redemption was cancelled (out-of-date hint, or new net debt < minimum), therefore we could not redeem from the last Trove\n\n totals.totalZUSDToRedeem = totals.totalZUSDToRedeem.add(singleRedemption.ZUSDLot);\n totals.totalETHDrawn = totals.totalETHDrawn.add(singleRedemption.ETHLot);\n\n totals.remainingZUSD = totals.remainingZUSD.sub(singleRedemption.ZUSDLot);\n currentBorrower = nextUserToCheck;\n }\n require(totals.totalETHDrawn > 0, \"TroveManager: Unable to redeem any amount\");\n\n // Decay the baseRate due to time passed, and then increase it according to the size of this redemption.\n // Use the saved total ZUSD supply value, from before it was reduced by the redemption.\n _updateBaseRateFromRedemption(\n totals.totalETHDrawn,\n totals.price,\n totals.totalZUSDSupplyAtStart\n );\n\n // Calculate the ETH fee\n totals.ETHFee = _getRedemptionFee(totals.totalETHDrawn);\n\n _requireUserAcceptsFee(totals.ETHFee, totals.totalETHDrawn, _maxFeePercentage);\n\n // Send the ETH fee to the feeDistributorContract address\n contractsCache.activePool.sendETH(address(feeDistributor), totals.ETHFee);\n feeDistributor.distributeFees();\n\n totals.ETHToSendToRedeemer = totals.totalETHDrawn.sub(totals.ETHFee);\n\n emit Redemption(\n _ZUSDamount,\n totals.totalZUSDToRedeem,\n totals.totalETHDrawn,\n totals.ETHFee\n );\n\n // Burn the total ZUSD that is cancelled with debt, and send the redeemed ETH to msg.sender\n contractsCache.zusdToken.burn(msg.sender, totals.totalZUSDToRedeem);\n // Update Active Pool ZUSD, and send ETH to account\n contractsCache.activePool.decreaseZUSDDebt(totals.totalZUSDToRedeem);\n contractsCache.activePool.sendETH(msg.sender, totals.ETHToSendToRedeemer);\n }\n\n ///DLLR _owner can use Sovryn Mynt to convert DLLR to ZUSD, then use the Zero redemption mechanism to redeem ZUSD for RBTC, all in a single transaction\n function redeemCollateralViaDLLR(\n uint256 _dllrAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage,\n IMassetManager.PermitParams calldata _permitParams\n ) external {\n uint256 _zusdAmount = MyntLib.redeemZusdFromDllrWithPermit(\n IBorrowerOperations(borrowerOperationsAddress).getMassetManager(),\n _dllrAmount,\n address(_zusdToken),\n _permitParams\n );\n _redeemCollateral(\n _zusdAmount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n _maxIterations,\n _maxFeePercentage\n );\n }\n\n function _isValidFirstRedemptionHint(\n ISortedTroves _sortedTroves,\n address _firstRedemptionHint,\n uint256 _price\n ) internal view returns (bool) {\n if (\n _firstRedemptionHint == address(0) ||\n !_sortedTroves.contains(_firstRedemptionHint) ||\n _getCurrentICR(_firstRedemptionHint, _price) < liquityBaseParams.MCR()\n ) {\n return false;\n }\n\n address nextTrove = _sortedTroves.getNext(_firstRedemptionHint);\n return\n nextTrove == address(0) || _getCurrentICR(nextTrove, _price) < liquityBaseParams.MCR();\n }\n\n /// Redeem as much collateral as possible from _borrower's Trove in exchange for ZUSD up to _maxZUSDamount\n function _redeemCollateralFromTrove(\n ContractsCache memory _contractsCache,\n address _borrower,\n uint256 _maxZUSDamount,\n uint256 _price,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR\n ) internal returns (SingleRedemptionValues memory singleRedemption) {\n // Determine the remaining amount (lot) to be redeemed, capped by the entire debt of the Trove minus the liquidation reserve\n singleRedemption.ZUSDLot = LiquityMath._min(\n _maxZUSDamount,\n Troves[_borrower].debt.sub(ZUSD_GAS_COMPENSATION)\n );\n\n // Get the ETHLot of equivalent value in USD\n singleRedemption.ETHLot = singleRedemption.ZUSDLot.mul(DECIMAL_PRECISION).div(_price);\n\n // Decrease the debt and collateral of the current Trove according to the ZUSD lot and corresponding ETH to send\n uint256 newDebt = (Troves[_borrower].debt).sub(singleRedemption.ZUSDLot);\n uint256 newColl = (Troves[_borrower].coll).sub(singleRedemption.ETHLot);\n\n if (newDebt == ZUSD_GAS_COMPENSATION) {\n // No debt left in the Trove (except for the liquidation reserve), therefore the trove gets closed\n _removeStake(_borrower);\n _closeTrove(_borrower, Status.closedByRedemption);\n _redeemCloseTrove(_contractsCache, _borrower, ZUSD_GAS_COMPENSATION, newColl);\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.redeemCollateral);\n } else {\n uint256 newNICR = LiquityMath._computeNominalCR(newColl, newDebt);\n\n /*\n * If the provided hint is out of date, we bail since trying to reinsert without a good hint will almost\n * certainly result in running out of gas.\n *\n * If the resultant net debt of the partial is less than the minimum, net debt we bail.\n */\n if (newNICR != _partialRedemptionHintNICR || _getNetDebt(newDebt) < MIN_NET_DEBT) {\n singleRedemption.cancelledPartial = true;\n return singleRedemption;\n }\n\n _contractsCache.sortedTroves.reInsert(\n _borrower,\n newNICR,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint\n );\n\n Troves[_borrower].debt = newDebt;\n Troves[_borrower].coll = newColl;\n _updateStakeAndTotalStakes(_borrower);\n\n emit TroveUpdated(\n _borrower,\n newDebt,\n newColl,\n Troves[_borrower].stake,\n TroveManagerOperation.redeemCollateral\n );\n }\n\n return singleRedemption;\n }\n\n /**\n This function has two impacts on the baseRate state variable:\n 1) decays the baseRate based on time passed since last redemption or ZUSD borrowing operation.\n then,\n 2) increases the baseRate based on the amount redeemed, as a proportion of total supply\n */\n function _updateBaseRateFromRedemption(\n uint256 _ETHDrawn,\n uint256 _price,\n uint256 _totalZUSDSupply\n ) internal returns (uint256) {\n uint256 decayedBaseRate = _calcDecayedBaseRate();\n\n /* Convert the drawn ETH back to ZUSD at face value rate (1 ZUSD:1 USD), in order to get\n * the fraction of total supply that was redeemed at face value. */\n uint256 redeemedZUSDFraction = _ETHDrawn.mul(_price).div(_totalZUSDSupply);\n\n uint256 newBaseRate = decayedBaseRate.add(redeemedZUSDFraction.div(BETA));\n newBaseRate = LiquityMath._min(newBaseRate, DECIMAL_PRECISION); // cap baseRate at a maximum of 100%\n //assert(newBaseRate <= DECIMAL_PRECISION); // This is already enforced in the line above\n assert(newBaseRate > 0); // Base rate is always non-zero after redemption\n\n // Update the baseRate state variable\n baseRate = newBaseRate;\n emit BaseRateUpdated(newBaseRate);\n\n _updateLastFeeOpTime();\n\n return newBaseRate;\n }\n\n /**\n Called when a full redemption occurs, and closes the trove.\n The redeemer swaps (debt - liquidation reserve) ZUSD for (debt - liquidation reserve) worth of ETH, so the ZUSD liquidation reserve left corresponds to the remaining debt.\n In order to close the trove, the ZUSD liquidation reserve is burned, and the corresponding debt is removed from the active pool.\n The debt recorded on the trove's struct is zero'd elswhere, in _closeTrove.\n Any surplus ETH left in the trove, is sent to the Coll surplus pool, and can be later claimed by the borrower.\n */\n function _redeemCloseTrove(\n ContractsCache memory _contractsCache,\n address _borrower,\n uint256 _ZUSD,\n uint256 _ETH\n ) internal {\n _contractsCache.zusdToken.burn(gasPoolAddress, _ZUSD);\n // Update Active Pool ZUSD, and send ETH to account\n _contractsCache.activePool.decreaseZUSDDebt(_ZUSD);\n\n // send ETH from Active Pool to CollSurplus Pool\n _contractsCache.collSurplusPool.accountSurplus(_borrower, _ETH);\n _contractsCache.activePool.sendETH(address(_contractsCache.collSurplusPool), _ETH);\n }\n}\n" + }, + "contracts/FeeDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/LiquityMath.sol\";\nimport \"./FeeDistributorStorage.sol\";\nimport \"./Dependencies/SafeMath.sol\";\n\ncontract FeeDistributor is CheckContract, FeeDistributorStorage, IFeeDistributor {\n using SafeMath for uint256;\n // --- Events ---\n\n event FeeSharingCollectorAddressChanged(address _feeSharingCollectorAddress);\n event ZeroStakingAddressChanged(address _zeroStakingAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event WrbtcAddressChanged(address _wrbtcAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event ZUSDDistributed(uint256 _zusdDistributedAmount);\n event RBTCistributed(uint256 _rbtcDistributedAmount);\n\n // --- Dependency setters ---\n\n function setAddresses(\n address _feeSharingCollectorAddress,\n address _zeroStakingAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _wrbtcAddress,\n address _zusdTokenAddress,\n address _activePoolAddress\n ) external override onlyOwner {\n checkContract(_feeSharingCollectorAddress);\n checkContract(_zeroStakingAddress);\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_wrbtcAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_activePoolAddress);\n\n feeSharingCollector = IFeeSharingCollector(_feeSharingCollectorAddress);\n zeroStaking = IZEROStaking(_zeroStakingAddress);\n borrowerOperations = IBorrowerOperations(_borrowerOperationsAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n wrbtc = IWrbtc(_wrbtcAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n activePoolAddress = _activePoolAddress;\n\n // Not entirely removing this as per request from @light\n FEE_TO_FEE_SHARING_COLLECTOR = LiquityMath.DECIMAL_PRECISION; // 100%\n\n emit FeeSharingCollectorAddressChanged(_feeSharingCollectorAddress);\n emit ZeroStakingAddressChanged(_zeroStakingAddress);\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit WrbtcAddressChanged(_wrbtcAddress);\n emit ZUSDTokenAddressChanged(_zusdTokenAddress);\n emit ActivePoolAddressSet(_activePoolAddress);\n }\n\n function setFeeToFeeSharingCollector(uint256 FEE_TO_FEE_SHARING_COLLECTOR_) public onlyOwner {\n FEE_TO_FEE_SHARING_COLLECTOR = FEE_TO_FEE_SHARING_COLLECTOR_;\n }\n\n function distributeFees() public override {\n require(\n msg.sender == address(borrowerOperations) || msg.sender == address(troveManager),\n \"FeeDistributor: invalid caller\"\n );\n uint256 zusdtoDistribute = zusdToken.balanceOf(address(this));\n uint256 rbtcToDistribute = address(this).balance;\n if (zusdtoDistribute != 0) {\n _distributeZUSD(zusdtoDistribute);\n }\n if (rbtcToDistribute != 0) {\n _distributeRBTC(rbtcToDistribute);\n }\n }\n\n function _distributeZUSD(uint256 toDistribute) internal {\n // Send fee to the FeeSharingCollector address\n uint256 feeToFeeSharingCollector = toDistribute.mul(FEE_TO_FEE_SHARING_COLLECTOR).div(\n LiquityMath.DECIMAL_PRECISION\n );\n zusdToken.approve(address(feeSharingCollector), feeToFeeSharingCollector);\n\n feeSharingCollector.transferTokens(address(zusdToken), uint96(feeToFeeSharingCollector));\n // Send fee to ZERO staking contract\n uint256 feeToZeroStaking = toDistribute.sub(feeToFeeSharingCollector);\n if (feeToZeroStaking != 0) {\n require(\n zusdToken.transfer(address(zeroStaking), feeToZeroStaking),\n \"Coudn't execute ZUSD transfer\"\n );\n zeroStaking.increaseF_ZUSD(feeToZeroStaking);\n }\n emit ZUSDDistributed(toDistribute);\n }\n\n function _distributeRBTC(uint256 toDistribute) internal {\n // Send fee to the feeSharingCollector address\n uint256 feeToFeeSharingCollector = toDistribute.mul(FEE_TO_FEE_SHARING_COLLECTOR).div(\n LiquityMath.DECIMAL_PRECISION\n );\n\n feeSharingCollector.transferRBTC{ value: feeToFeeSharingCollector }();\n\n // Send the ETH fee to the ZERO staking contract\n uint256 feeToZeroStaking = toDistribute.sub(feeToFeeSharingCollector);\n if (feeToZeroStaking != 0) {\n (bool success, ) = address(zeroStaking).call{ value: feeToZeroStaking }(\"\");\n require(success, \"FeeDistributor: sending ETH failed\");\n zeroStaking.increaseF_ETH(feeToZeroStaking);\n }\n emit RBTCistributed(toDistribute);\n }\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"FeeDistributor: caller is not ActivePool\");\n }\n\n receive() external payable {\n _requireCallerIsActivePool();\n }\n}\n" + }, + "contracts/FeeDistributorStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IFeeSharingCollector.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IWrbtc.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract FeeDistributorStorage is Ownable {\n string public constant NAME = \"FeeDistributor\";\n\n // --- Connected contract declarations ---\n\n IFeeSharingCollector public feeSharingCollector;\n\n IZEROStaking public zeroStaking;\n\n IBorrowerOperations public borrowerOperations;\n\n ITroveManager public troveManager;\n\n IWrbtc public wrbtc;\n\n IZUSDToken public zusdToken;\n\n address public activePoolAddress;\n\n //pct of fees sent to feeSharingCollector address\n uint256 public FEE_TO_FEE_SHARING_COLLECTOR;\n}\n" + }, + "contracts/GasPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * The purpose of this contract is to hold ZUSD tokens for gas compensation:\n * https://github.com/DistributedCollective/zero#gas-compensation\n * When a borrower opens a trove, an additional 50 ZUSD debt is issued,\n * and 50 ZUSD is minted and sent to this contract.\n * When a borrower closes their active trove, this gas compensation is refunded:\n * 50 ZUSD is burned from the this contract's balance, and the corresponding\n * 50 ZUSD debt on the trove is cancelled.\n * See this issue for more context: https://github.com/liquity/dev/issues/186\n */\ncontract GasPool {\n // do nothing, as the core contracts have permission to send to and burn from this address\n}\n" + }, + "contracts/HintHelpers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./HintHelpersStorage.sol\";\n\ncontract HintHelpers is LiquityBase, HintHelpersStorage, CheckContract {\n // --- Events ---\n\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event TroveManagerAddressChanged(address _troveManagerAddress);\n\n // --- Dependency setters ---\n\n function setAddresses(\n address _liquityBaseParamsAddress,\n address _sortedTrovesAddress,\n address _troveManagerAddress\n ) external onlyOwner {\n checkContract(_liquityBaseParamsAddress);\n checkContract(_sortedTrovesAddress);\n checkContract(_troveManagerAddress);\n\n liquityBaseParams = ILiquityBaseParams(_liquityBaseParamsAddress);\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n\n emit SortedTrovesAddressChanged(_sortedTrovesAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n }\n\n // --- Functions ---\n\n /** getRedemptionHints() - Helper function for finding the right hints to pass to redeemCollateral().\n *\n * It simulates a redemption of `_ZUSDamount` to figure out where the redemption sequence will start and what state the final Trove\n * of the sequence will end up in.\n *\n * Returns three hints:\n * - `firstRedemptionHint` is the address of the first Trove with ICR >= MCR (i.e. the first Trove that will be redeemed).\n * - `partialRedemptionHintNICR` is the final nominal ICR of the last Trove of the sequence after being hit by partial redemption,\n * or zero in case of no partial redemption.\n * - `truncatedZUSDamount` is the maximum amount that can be redeemed out of the the provided `_ZUSDamount`. This can be lower than\n * `_ZUSDamount` when redeeming the full amount would leave the last Trove of the redemption sequence with less net debt than the\n * minimum allowed value (i.e. MIN_NET_DEBT).\n *\n * The number of Troves to consider for redemption can be capped by passing a non-zero value as `_maxIterations`, while passing zero\n * will leave it uncapped.\n */\n\n function getRedemptionHints(\n uint256 _ZUSDamount,\n uint256 _price,\n uint256 _maxIterations\n )\n external\n view\n returns (\n address firstRedemptionHint,\n uint256 partialRedemptionHintNICR,\n uint256 truncatedZUSDamount\n )\n {\n ISortedTroves sortedTrovesCached = sortedTroves;\n\n uint256 remainingZUSD = _ZUSDamount;\n address currentTroveuser = sortedTrovesCached.getLast();\n\n while (\n currentTroveuser != address(0) &&\n troveManager.getCurrentICR(currentTroveuser, _price) < liquityBaseParams.MCR()\n ) {\n currentTroveuser = sortedTrovesCached.getPrev(currentTroveuser);\n }\n\n firstRedemptionHint = currentTroveuser;\n\n if (_maxIterations == 0) {\n _maxIterations = uint256(-1);\n }\n\n while (currentTroveuser != address(0) && remainingZUSD > 0 && _maxIterations-- > 0) {\n uint256 netZUSDDebt = _getNetDebt(troveManager.getTroveDebt(currentTroveuser)).add(\n troveManager.getPendingZUSDDebtReward(currentTroveuser)\n );\n\n if (netZUSDDebt > remainingZUSD) {\n if (netZUSDDebt > MIN_NET_DEBT) {\n uint256 maxRedeemableZUSD = LiquityMath._min(\n remainingZUSD,\n netZUSDDebt.sub(MIN_NET_DEBT)\n );\n\n uint256 ETH = troveManager.getTroveColl(currentTroveuser).add(\n troveManager.getPendingETHReward(currentTroveuser)\n );\n\n uint256 newColl = ETH.sub(\n maxRedeemableZUSD.mul(DECIMAL_PRECISION).div(_price)\n );\n uint256 newDebt = netZUSDDebt.sub(maxRedeemableZUSD);\n\n uint256 compositeDebt = _getCompositeDebt(newDebt);\n partialRedemptionHintNICR = LiquityMath._computeNominalCR(\n newColl,\n compositeDebt\n );\n\n remainingZUSD = remainingZUSD.sub(maxRedeemableZUSD);\n }\n break;\n } else {\n remainingZUSD = remainingZUSD.sub(netZUSDDebt);\n }\n\n currentTroveuser = sortedTrovesCached.getPrev(currentTroveuser);\n }\n\n truncatedZUSDamount = _ZUSDamount.sub(remainingZUSD);\n }\n\n /** getApproxHint() - return address of a Trove that is, on average, (length / numTrials) positions away in the \n sortedTroves list from the correct insert position of the Trove to be inserted. \n \n Note: The output address is worst-case O(n) positions away from the correct insert position, however, the function \n is probabilistic. Input can be tuned to guarantee results to a high degree of confidence, e.g:\n\n Submitting numTrials = k * sqrt(length), with k = 15 makes it very, very likely that the ouput address will \n be <= sqrt(length) positions away from the correct insert position.\n */\n function getApproxHint(\n uint256 _CR,\n uint256 _numTrials,\n uint256 _inputRandomSeed\n )\n external\n view\n returns (\n address hintAddress,\n uint256 diff,\n uint256 latestRandomSeed\n )\n {\n uint256 arrayLength = troveManager.getTroveOwnersCount();\n\n if (arrayLength == 0) {\n return (address(0), 0, _inputRandomSeed);\n }\n\n hintAddress = sortedTroves.getLast();\n diff = LiquityMath._getAbsoluteDifference(_CR, troveManager.getNominalICR(hintAddress));\n latestRandomSeed = _inputRandomSeed;\n\n uint256 i = 1;\n\n while (i < _numTrials) {\n latestRandomSeed = uint256(keccak256(abi.encodePacked(latestRandomSeed)));\n\n uint256 arrayIndex = latestRandomSeed % arrayLength;\n address currentAddress = troveManager.getTroveFromTroveOwnersArray(arrayIndex);\n uint256 currentNICR = troveManager.getNominalICR(currentAddress);\n\n // check if abs(current - CR) > abs(closest - CR), and update closest if current is closer\n uint256 currentDiff = LiquityMath._getAbsoluteDifference(currentNICR, _CR);\n\n if (currentDiff < diff) {\n diff = currentDiff;\n hintAddress = currentAddress;\n }\n i++;\n }\n }\n\n function computeNominalCR(uint256 _coll, uint256 _debt) external pure returns (uint256) {\n return LiquityMath._computeNominalCR(_coll, _debt);\n }\n\n function computeCR(\n uint256 _coll,\n uint256 _debt,\n uint256 _price\n ) external pure returns (uint256) {\n return LiquityMath._computeCR(_coll, _debt, _price);\n }\n}\n" + }, + "contracts/HintHelpersStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract HintHelpersStorage is Ownable {\n string public constant NAME = \"HintHelpers\";\n\n ISortedTroves public sortedTroves;\n ITroveManager public troveManager;\n}\n" + }, + "contracts/Interfaces/IActivePool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IPool.sol\";\n\n/**\n * The Active Pool holds the ETH collateral and ZUSD debt (but not ZUSD tokens) for all active troves.\n *\n * When a trove is liquidated, it's ETH and ZUSD debt are transferred from the Active Pool, to either the\n * Stability Pool, the Default Pool, or both, depending on the liquidation conditions.\n *\n */\ninterface IActivePool is IPool {\n // --- Events ---\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolZUSDDebtUpdated(uint _ZUSDDebt);\n event ActivePoolETHBalanceUpdated(uint _ETH);\n\n // --- Functions ---\n\n /// @notice Send ETH amount to given account. Updates ActivePool balance. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _account account to receive the ETH amount\n /// @param _amount ETH amount to send\n function sendETH(address _account, uint _amount) external;\n}\n" + }, + "contracts/Interfaces/IBalanceRedirectPresale.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IBalanceRedirectPresale {\n\n function isClosed() external view returns (bool);\n}" + }, + "contracts/Interfaces/IBorrowerOperations.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../Dependencies/Mynt/IMassetManager.sol\";\n\n/// Common interface for the Trove Manager.\ninterface IBorrowerOperations {\n // --- Events ---\n\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n\n event TroveCreated(address indexed _borrower, uint256 arrayIndex);\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 stake,\n uint8 operation\n );\n event ZUSDBorrowingFeePaid(address indexed _borrower, uint256 _ZUSDFee);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _feeDistributorAddress feeDistributor contract address\n * @param _liquityBaseParamsAddress LiquidityBaseParams contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _activePoolAddress ActivePool contract address\n * @param _defaultPoolAddress DefaultPool contract address\n * @param _stabilityPoolAddress StabilityPool contract address\n * @param _gasPoolAddress GasPool contract address\n * @param _collSurplusPoolAddress CollSurplusPool contract address\n * @param _priceFeedAddress PrideFeed contract address\n * @param _sortedTrovesAddress SortedTroves contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _zeroStakingAddress ZEROStaking contract address\n */\n function setAddresses(\n address _feeDistributorAddress,\n address _liquityBaseParamsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _defaultPoolAddress,\n address _stabilityPoolAddress,\n address _gasPoolAddress,\n address _collSurplusPoolAddress,\n address _priceFeedAddress,\n address _sortedTrovesAddress,\n address _zusdTokenAddress,\n address _zeroStakingAddress\n ) external;\n\n /**\n * @notice payable function that creates a Trove for the caller with the requested debt, and the Ether received as collateral.\n * Successful execution is conditional mainly on the resulting collateralization ratio which must exceed the minimum (110% in Normal Mode, 150% in Recovery Mode).\n * In addition to the requested debt, extra debt is issued to pay the issuance fee, and cover the gas compensation.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _ZUSDAmount ZUSD requested debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function openTrove(\n uint256 _maxFee,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /**\n * @notice payable function that creates a Trove for the caller with the requested debt, and the Ether received as collateral.\n * Successful execution is conditional mainly on the resulting collateralization ratio which must exceed the minimum (110% in Normal Mode, 150% in Recovery Mode).\n * In addition to the requested debt, extra debt is issued to pay the issuance fee, and cover the gas compensation.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * This method is identical to `openTrove()`, but operates on NUE tokens instead of ZUSD.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _ZUSDAmount ZUSD requested debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function openNueTrove(\n uint256 _maxFee,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /// @notice payable function that adds the received Ether to the caller's active Trove.\n /// @param _upperHint upper trove id hint\n /// @param _lowerHint lower trove id hint\n function addColl(address _upperHint, address _lowerHint) external payable;\n\n /// @notice send ETH as collateral to a trove. Called by only the Stability Pool.\n /// @param _user user trove address\n /// @param _upperHint upper trove id hint\n /// @param _lowerHint lower trove id hint\n function moveETHGainToTrove(\n address _user,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /**\n * @notice withdraws `_amount` of collateral from the caller’s Trove.\n * Executes only if the user has an active Trove, the withdrawal would not pull the user’s Trove below the minimum collateralization ratio,\n * and the resulting total collateralization ratio of the system is above 150%.\n * @param _amount collateral amount to withdraw\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function withdrawColl(uint256 _amount, address _upperHint, address _lowerHint) external;\n\n /**\n * @notice issues `_amount` of ZUSD from the caller’s Trove to the caller.\n * Executes only if the Trove's collateralization ratio would remain above the minimum, and the resulting total collateralization ratio is above 150%.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _amount ZUSD amount to withdraw\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function withdrawZUSD(\n uint256 _maxFee,\n uint256 _amount,\n address _upperHint,\n address _lowerHint\n ) external;\n\n /// Borrow (withdraw) ZUSD tokens from a trove: mint new ZUSD tokens to the owner and convert it to DLLR in one transaction\n function withdrawZusdAndConvertToDLLR(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external returns (uint256);\n\n /// @notice repay `_amount` of ZUSD to the caller’s Trove, subject to leaving 50 debt in the Trove (which corresponds to the 50 ZUSD gas compensation).\n /// @param _amount ZUSD amount to repay\n /// @param _upperHint upper trove id hint\n /// @param _lowerHint lower trove id hint\n function repayZUSD(uint256 _amount, address _upperHint, address _lowerHint) external;\n\n /// Repay ZUSD tokens to a Trove: Burn the repaid ZUSD tokens, and reduce the trove's debt accordingly\n function repayZusdFromDLLR(\n uint256 _dllrAmount,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external;\n\n /**\n * @notice allows a borrower to repay all debt, withdraw all their collateral, and close their Trove.\n * Requires the borrower have a ZUSD balance sufficient to repay their trove's debt, excluding gas compensation - i.e. `(debt - 50)` ZUSD.\n */\n function closeTrove() external;\n\n /**\n * @notice allows a borrower to repay all debt, withdraw all their collateral, and close their Trove.\n * Requires the borrower have a NUE balance sufficient to repay their trove's debt, excluding gas compensation - i.e. `(debt - 50)` NUE.\n * This method is identical to `closeTrove()`, but operates on NUE tokens instead of ZUSD.\n */\n function closeNueTrove(IMassetManager.PermitParams calldata _permitParams) external;\n\n /**\n * @notice enables a borrower to simultaneously change both their collateral and debt, subject to all the restrictions that apply to individual increases/decreases of each quantity with the following particularity:\n * if the adjustment reduces the collateralization ratio of the Trove, the function only executes if the resulting total collateralization ratio is above 150%.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * The parameter is ignored if the debt is not increased with the transaction.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _collWithdrawal collateral amount to withdraw\n * @param _debtChange ZUSD amount to change\n * @param isDebtIncrease indicates if increases debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function adjustTrove(\n uint256 _maxFee,\n uint256 _collWithdrawal,\n uint256 _debtChange,\n bool isDebtIncrease,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /**\n * @notice enables a borrower to simultaneously change both their collateral and debt, subject to all the restrictions that apply to individual increases/decreases of each quantity with the following particularity:\n * if the adjustment reduces the collateralization ratio of the Trove, the function only executes if the resulting total collateralization ratio is above 150%.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * The parameter is ignored if the debt is not increased with the transaction.\n * This method is identical to `adjustTrove()`, but operates on NUE tokens instead of ZUSD.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _collWithdrawal collateral amount to withdraw\n * @param _debtChange ZUSD amount to change\n * @param isDebtIncrease indicates if increases debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function adjustNueTrove(\n uint256 _maxFee,\n uint256 _collWithdrawal,\n uint256 _debtChange,\n bool isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external payable;\n\n /**\n * @notice when a borrower’s Trove has been fully redeemed from and closed, or liquidated in Recovery Mode with a collateralization ratio above 110%,\n * this function allows the borrower to claim their ETH collateral surplus that remains in the system (collateral - debt upon redemption; collateral - 110% of the debt upon liquidation).\n */\n function claimCollateral() external;\n\n function getCompositeDebt(uint256 _debt) external view returns (uint256);\n\n function BORROWING_FEE_FLOOR() external view returns (uint256);\n\n function getMassetManager() external view returns (IMassetManager);\n}\n" + }, + "contracts/Interfaces/ICollSurplusPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface ICollSurplusPool {\n // --- Events ---\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n\n event CollBalanceUpdated(address indexed _account, uint256 _newBalance);\n event EtherSent(address _to, uint256 _amount);\n\n // --- Contract setters ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _borrowerOperationsAddress BorrowerOperations contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _activePoolAddress ActivePool contract address\n */\n function setAddresses(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress\n ) external;\n\n /// @notice Not necessarily equal to the raw ether balance - ether can be forcibly sent to contracts.\n /// @return ETH state variable\n function getETH() external view returns (uint256);\n\n /// @param _account account to retrieve collateral\n /// @return collateral\n function getCollateral(address _account) external view returns (uint256);\n\n /// @notice adds amount to current account balance. Only callable by TroveManager.\n /// @param _account account to add amount\n /// @param _amount amount to add\n function accountSurplus(address _account, uint256 _amount) external;\n\n /// @notice claims collateral for given account. Only callable by BorrowerOperations.\n /// @param _account account to send claimable collateral\n function claimColl(address _account) external;\n}\n" + }, + "contracts/Interfaces/ICommunityIssuance.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface ICommunityIssuance { \n \n // --- Events ---\n \n event SOVTokenAddressSet(address _zeroTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event StabilityPoolAddressSet(address _stabilityPoolAddress);\n event PriceFeedAddressSet(address _priceFeed);\n event RewardManagerAddressSet(address _rewardManagerAddress);\n event APRSet(uint256 _APR);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other contracts. Callable only by owner.\n * @dev initializer function, checks addresses are contracts\n * @param _zeroTokenAddress ZEROToken contract address\n * @param _communityPotAddress CommunityPot contract address\n */\n function initialize\n (\n address _zeroTokenAddress, \n address _communityPotAddress,\n address _fundingWalletAddress\n ) external;\n\n /**\n * @dev setter function to set the APR value in basis points.\n * can only be called by reward manager.\n * @param _APR apr value in basis points.\n */\n function setAPR(uint256 _APR) external;\n\n /**\n * @dev setter function to set the price feed.\n * can only be called by the owner.\n * @param _priceFeedAddress price feed address.\n */\n function setPriceFeed(address _priceFeedAddress) external;\n\n /**\n * @dev setter function to set reward manager.\n * can only be called by the owner.\n * @param _rewardManagerAddress reward manager address.\n */\n function setRewardManager(address _rewardManagerAddress) external;\n\n /// @notice issues SOV tokens based on total zusd is deposited.\n /// @return SOV tokens issuance \n function issueSOV(uint256 _totalZUSDDeposits) external returns (uint256);\n\n /// @notice sends ZERO tokens to given account\n /// @param _account account to receive the tokens\n /// @param _ZEROamount amount of tokens to transfer\n function sendSOV(address _account, uint _ZEROamount) external;\n}\n" + }, + "contracts/Interfaces/IDefaultPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IPool.sol\";\n\ninterface IDefaultPool is IPool {\n // --- Events ---\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event DefaultPoolZUSDDebtUpdated(uint256 _ZUSDDebt);\n event DefaultPoolETHBalanceUpdated(uint256 _ETH);\n\n // --- Functions ---\n\n /// @notice Send ETH to Active Pool\n /// @param _amount ETH to send\n function sendETHToActivePool(uint256 _amount) external;\n}\n" + }, + "contracts/Interfaces/IFeeDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/// Common interface for Fee Distributor.\ninterface IFeeDistributor {\n // --- Events ---\n\n event FeeSharingCollectorAddressChanged(address _feeSharingCollectorAddress);\n event ZeroStakingAddressChanged(address _zeroStakingAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event WrbtcAddressChanged(address _wrbtcAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event ZUSDDistributed(uint256 _zusdDistributedAmount);\n event RBTCistributed(uint256 _rbtcDistributedAmount);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _feeSharingCollectorAddress FeeSharingCollector address\n * @param _zeroStakingAddress ZEROStaking contract address\n * @param _borrowerOperationsAddress borrowerOperations contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _wrbtcAddress wrbtc ERC20 contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _activePoolAddress ActivePool contract address\n */\n function setAddresses(\n address _feeSharingCollectorAddress,\n address _zeroStakingAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _wrbtcAddress,\n address _zusdTokenAddress,\n address _activePoolAddress\n ) external;\n\n function distributeFees() external;\n}\n" + }, + "contracts/Interfaces/IFeeSharingCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\n/**\n * @title Interface for Sovryn protocol fee sharing collector.\n * @dev Interfaces are used to cast a contract address into a callable instance.\n * */\ninterface IFeeSharingCollector {\n\tfunction withdrawFees(address _token) external;\n\n\tfunction transferTokens(address _token, uint96 _amount) external;\n\n\tfunction withdraw(\n\t\taddress _loanPoolToken,\n\t\tuint32 _maxCheckpoints,\n\t\taddress _receiver\n\t) external;\n\n\tfunction transferRBTC() external payable;\n}\n" + }, + "contracts/Interfaces/ILiquityBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IPriceFeed.sol\";\nimport \"./ILiquityBaseParams.sol\";\n\ninterface ILiquityBase {\n /// @return PriceFeed contract\n function priceFeed() external view returns (IPriceFeed);\n\n /// @return LiquityBaseParams contract\n function liquityBaseParams() external view returns (ILiquityBaseParams);\n}\n" + }, + "contracts/Interfaces/ILiquityBaseParams.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface ILiquityBaseParams {\n\n /// Minimum collateral ratio for individual troves\n function MCR() external view returns (uint);\n\n /// Critical system collateral ratio. If the system's total collateral ratio (TCR) falls below the CCR, Recovery Mode is triggered.\n function CCR() external view returns (uint);\n\n function PERCENT_DIVISOR() external view returns (uint);\n\n function BORROWING_FEE_FLOOR() external view returns (uint);\n\n /**\n * Half-life of 12h. 12h = 720 min\n * (1/2) = d^720 => d = (1/2)^(1/720)\n */\n function REDEMPTION_FEE_FLOOR() external view returns (uint);\n\n function MAX_BORROWING_FEE() external view returns (uint);\n\n}" + }, + "contracts/Interfaces/IPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// Common interface for the Pools.\ninterface IPool {\n // --- Events ---\n\n event ETHBalanceUpdated(uint _newBalance);\n event ZUSDBalanceUpdated(uint _newBalance);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n event DefaultPoolAddressChanged(address _newDefaultPoolAddress);\n event StabilityPoolAddressChanged(address _newStabilityPoolAddress);\n event EtherSent(address _to, uint _amount);\n\n // --- Functions ---\n\n /// @notice Not necessarily equal to the raw ether balance - ether can be forcibly sent to contracts.\n /// @return ETH pool balance\n function getETH() external view returns (uint);\n\n /// @return ZUSD debt pool balance\n function getZUSDDebt() external view returns (uint);\n\n /// @notice Increases ZUSD debt of the pool.\n /// @param _amount ZUSD amount to add to the pool debt\n function increaseZUSDDebt(uint _amount) external;\n\n /// @notice Decreases ZUSD debt of the pool.\n /// @param _amount ZUSD amount to subtract to the pool debt\n function decreaseZUSDDebt(uint _amount) external;\n}\n" + }, + "contracts/Interfaces/IPriceFeed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IPriceFeed {\n // --- Events ---\n event LastGoodPriceUpdated(uint256 _lastGoodPrice);\n\n // --- Function ---\n\n /// @notice Returns the latest price obtained from the Oracle. Called by Zero functions that require a current price.\n /// It uses the main price feed and fallback to the backup one in case of an error. If both fail return the last\n /// good price seen.\n /// @dev It's also callable by anyone externally\n /// @return The price\n function fetchPrice() external returns (uint256);\n}\n" + }, + "contracts/Interfaces/IPriceFeedSovryn.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IPriceFeedSovryn {\n function queryRate(address sourceToken, address destToken)\n external\n view\n returns (uint256 rate, uint256 precision);\n\n function queryPrecision(address sourceToken, address destToken)\n external\n view\n returns (uint256 precision);\n\n function queryReturn(\n address sourceToken,\n address destToken,\n uint256 sourceAmount\n ) external view returns (uint256 destAmount);\n\n function checkPriceDisagreement(\n address sourceToken,\n address destToken,\n uint256 sourceAmount,\n uint256 destAmount,\n uint256 maxSlippage\n ) external view returns (uint256 sourceToDestSwapRate);\n\n function amountInEth(address Token, uint256 amount) external view returns (uint256 ethAmount);\n\n function getMaxDrawdown(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount,\n uint256 maintenanceMargin\n ) external view returns (uint256);\n\n function getCurrentMarginAndCollateralSize(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount\n ) external view returns (uint256 currentMargin, uint256 collateralInEthAmount);\n\n function getCurrentMargin(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount\n ) external view returns (uint256 currentMargin, uint256 collateralToLoanRate);\n\n function shouldLiquidate(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount,\n uint256 maintenanceMargin\n ) external view returns (bool);\n\n function getFastGasPrice(address payToken) external view returns (uint256);\n}\n" + }, + "contracts/Interfaces/ISortedTroves.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// Common interface for the SortedTroves Doubly Linked List.\ninterface ISortedTroves {\n // --- Events ---\n\n event SortedTrovesAddressChanged(address _sortedDoublyLLAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event NodeAdded(address _id, uint256 _NICR);\n event NodeRemoved(address _id);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts and size. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _size max size of troves list\n * @param _TroveManagerAddress TroveManager contract address\n * @param _borrowerOperationsAddress BorrowerOperations contract address\n */\n function setParams(\n uint256 _size,\n address _TroveManagerAddress,\n address _borrowerOperationsAddress\n ) external;\n\n /**\n * @dev Add a node to the list\n * @param _id Node's id\n * @param _ICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function insert(\n address _id,\n uint256 _ICR,\n address _prevId,\n address _nextId\n ) external;\n\n /**\n * @dev Remove a node from the list\n * @param _id Node's id\n */\n function remove(address _id) external;\n\n /**\n * @dev Re-insert the node at a new position, based on its new NICR\n * @param _id Node's id\n * @param _newICR Node's new NICR\n * @param _prevId Id of previous node for the new insert position\n * @param _nextId Id of next node for the new insert position\n */\n function reInsert(\n address _id,\n uint256 _newICR,\n address _prevId,\n address _nextId\n ) external;\n\n /**\n * @dev Checks if the list contains a node\n * @param _id Node's id\n * @return true if list contains a node with given id\n */\n function contains(address _id) external view returns (bool);\n\n /**\n * @dev Checks if the list is full\n * @return true if list is full\n */\n function isFull() external view returns (bool);\n\n /**\n * @dev Checks if the list is empty\n * @return true if list is empty\n */\n function isEmpty() external view returns (bool);\n\n /**\n * @return list current size\n */\n function getSize() external view returns (uint256);\n\n /**\n * @return list max size\n */\n function getMaxSize() external view returns (uint256);\n\n /**\n * @return the first node in the list (node with the largest NICR)\n */\n function getFirst() external view returns (address);\n\n /**\n * @return the last node in the list (node with the smallest NICR)\n */\n function getLast() external view returns (address);\n\n /**\n * @param _id Node's id\n * @return the next node (with a smaller NICR) in the list for a given node\n */\n function getNext(address _id) external view returns (address);\n\n /**\n * @param _id Node's id\n * @return the previous node (with a larger NICR) in the list for a given node\n */\n function getPrev(address _id) external view returns (address);\n\n /**\n * @notice Check if a pair of nodes is a valid insertion point for a new node with the given NICR\n * @param _ICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function validInsertPosition(\n uint256 _ICR,\n address _prevId,\n address _nextId\n ) external view returns (bool);\n\n /**\n * @notice Find the insert position for a new node with the given NICR\n * @param _ICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function findInsertPosition(\n uint256 _ICR,\n address _prevId,\n address _nextId\n ) external view returns (address, address);\n}\n" + }, + "contracts/Interfaces/IStabilityPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../Dependencies/Mynt/IMassetManager.sol\";\n\n/*\n * The Stability Pool holds ZUSD tokens deposited by Stability Pool depositors.\n *\n * When a trove is liquidated, then depending on system conditions, some of its ZUSD debt gets offset with\n * ZUSD in the Stability Pool: that is, the offset debt evaporates, and an equal amount of ZUSD tokens in the Stability Pool is burned.\n *\n * Thus, a liquidation causes each depositor to receive a ZUSD loss, in proportion to their deposit as a share of total deposits.\n * They also receive an ETH gain, as the ETH collateral of the liquidated trove is distributed among Stability depositors,\n * in the same proportion.\n *\n * When a liquidation occurs, it depletes every deposit by the same fraction: for example, a liquidation that depletes 40%\n * of the total ZUSD in the Stability Pool, depletes 40% of each deposit.\n *\n * A deposit that has experienced a series of liquidations is termed a \"compounded deposit\": each liquidation depletes the deposit,\n * multiplying it by some factor in range ]0,1[\n *\n * Please see the implementation spec in the proof document, which closely follows on from the compounded deposit / ETH gain derivations:\n * https://github.com/liquity/liquity/blob/master/papers/Scalable_Reward_Distribution_with_Compounding_Stakes.pdf\n *\n * --- SOV ISSUANCE TO STABILITY POOL DEPOSITORS ---\n *\n * An SOV issuance event occurs at every deposit operation, and every liquidation.\n *\n * Each deposit is tagged with the address of the front end through which it was made.\n *\n * All deposits earn a share of the issued SOV in proportion to the deposit as a share of total deposits. The SOV earned\n * by a given deposit, is split between the depositor and the front end through which the deposit was made, based on the front end's kickbackRate.\n *\n * Please see the system Readme for an overview:\n * https://github.com/liquity/dev/blob/main/README.md#zero-issuance-to-stability-providers\n */\ninterface IStabilityPool {\n // --- Events ---\n\n event StabilityPoolETHBalanceUpdated(uint _newBalance);\n event StabilityPoolZUSDBalanceUpdated(uint _newBalance);\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n event DefaultPoolAddressChanged(address _newDefaultPoolAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event SortedTrovesAddressChanged(address _newSortedTrovesAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event CommunityIssuanceAddressChanged(address _newCommunityIssuanceAddress);\n\n event P_Updated(uint _P);\n event S_Updated(uint _S, uint128 _epoch, uint128 _scale);\n event G_Updated(uint _G, uint128 _epoch, uint128 _scale);\n event EpochUpdated(uint128 _currentEpoch);\n event ScaleUpdated(uint128 _currentScale);\n\n event FrontEndRegistered(address indexed _frontEnd, uint _kickbackRate);\n event FrontEndTagSet(address indexed _depositor, address indexed _frontEnd);\n\n event DepositSnapshotUpdated(address indexed _depositor, uint _P, uint _S, uint _G);\n event FrontEndSnapshotUpdated(address indexed _frontEnd, uint _P, uint _G);\n event UserDepositChanged(address indexed _depositor, uint _newDeposit);\n event FrontEndStakeChanged(\n address indexed _frontEnd,\n uint _newFrontEndStake,\n address _depositor\n );\n\n event ETHGainWithdrawn(address indexed _depositor, uint _ETH, uint _ZUSDLoss);\n event SOVPaidToDepositor(address indexed _depositor, uint _SOV);\n event SOVPaidToFrontEnd(address indexed _frontEnd, uint _SOV);\n event EtherSent(address _to, uint _amount);\n\n event WithdrawFromSpAndConvertToDLLR(\n address _depositor,\n uint256 _zusdAmountRequested,\n uint256 _dllrAmountReceived\n );\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Liquity contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _liquityBaseParamsAddress LiquidityBaseParams contract address\n * @param _borrowerOperationsAddress BorrowerOperations contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _activePoolAddress ActivePool contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _sortedTrovesAddress SortedTroves contract address\n * @param _priceFeedAddress PriceFeed contract address\n * @param _communityIssuanceAddress CommunityIssuanceAddress\n */\n function setAddresses(\n address _liquityBaseParamsAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _zusdTokenAddress,\n address _sortedTrovesAddress,\n address _priceFeedAddress,\n address _communityIssuanceAddress\n ) external;\n\n /**\n * @notice Initial checks:\n * - Frontend is registered or zero address\n * - Sender is not a registered frontend\n * - _amount is not zero\n * ---\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Tags the deposit with the provided front end tag param, if it's a new deposit\n * - Sends depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Increases deposit and tagged front end's stake, and takes new snapshots for each.\n * @param _amount amount to provide\n * @param _frontEndTag frontend address to receive accumulated SOV gains\n */\n function provideToSP(uint _amount, address _frontEndTag) external;\n\n /**\n * @notice Initial checks:\n * - _amount is zero or there are no under collateralized troves left in the system\n * - User has a non zero deposit\n * ---\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Removes the deposit's front end tag if it is a full withdrawal\n * - Sends all depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Decreases deposit and tagged front end's stake, and takes new snapshots for each.\n *\n * If _amount > userDeposit, the user withdraws all of their compounded deposit.\n * @param _amount amount to withdraw\n */\n function withdrawFromSP(uint _amount) external;\n\n /**\n * @notice Initial checks:\n * - User has a non zero deposit\n * - User has an open trove\n * - User has some ETH gain\n * ---\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Sends all depositor's SOV gain to depositor\n * - Sends all tagged front end's SOV gain to the tagged front end\n * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove\n * - Leaves their compounded deposit in the Stability Pool\n * - Updates snapshots for deposit and tagged front end stake\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external;\n\n /**\n * @notice Initial checks:\n * - Frontend (sender) not already registered\n * - User (sender) has no deposit\n * - _kickbackRate is in the range [0, 100%]\n * ---\n * Front end makes a one-time selection of kickback rate upon registering\n * @param _kickbackRate kickback rate selected by frontend\n */\n function registerFrontEnd(uint _kickbackRate) external;\n\n /**\n * @notice Initial checks:\n * - Caller is TroveManager\n * ---\n * Cancels out the specified debt against the ZUSD contained in the Stability Pool (as far as possible)\n * and transfers the Trove's ETH collateral from ActivePool to StabilityPool.\n * Only called by liquidation functions in the TroveManager.\n * @param _debt debt to cancel\n * @param _coll collateral to transfer\n */\n function offset(uint _debt, uint _coll) external;\n\n /**\n * @return the total amount of ETH held by the pool, accounted in an internal variable instead of `balance`,\n * to exclude edge cases like ETH received from a self-destruct.\n */\n function getETH() external view returns (uint);\n\n /**\n * @return ZUSD held in the pool. Changes when users deposit/withdraw, and when Trove debt is offset.\n */\n function getTotalZUSDDeposits() external view returns (uint);\n\n /**\n * @notice Calculates the ETH gain earned by the deposit since its last snapshots were taken.\n * @param _depositor address to calculate ETH gain\n * @return ETH gain from given depositor\n */\n function getDepositorETHGain(address _depositor) external view returns (uint);\n\n /**\n * @notice Calculate the SOV gain earned by a deposit since its last snapshots were taken.\n * If not tagged with a front end, the depositor gets a 100% cut of what their deposit earned.\n * Otherwise, their cut of the deposit's earnings is equal to the kickbackRate, set by the front end through\n * which they made their deposit.\n * @param _depositor address to calculate ETH gain\n * @return SOV gain from given depositor\n */\n function getDepositorSOVGain(address _depositor) external view returns (uint);\n\n /**\n * @param _frontEnd front end address\n * @return the SOV gain earned by the front end.\n */\n function getFrontEndSOVGain(address _frontEnd) external view returns (uint);\n\n /**\n * @param _depositor depositor address\n * @return the user's compounded deposit.\n */\n function getCompoundedZUSDDeposit(address _depositor) external view returns (uint);\n\n /**\n * @notice The front end's compounded stake is equal to the sum of its depositors' compounded deposits.\n * @param _frontEnd front end address\n * @return the front end's compounded stake.\n */\n function getCompoundedFrontEndStake(address _frontEnd) external view returns (uint);\n\n //DLLR _owner or _spender can convert a specified amount of DLLR into ZUSD via Sovryn Mynt and deposit the ZUSD into the SOV Stability Pool, all in a single transaction\n function provideToSpFromDLLR(\n uint _dllrAmount,\n IMassetManager.PermitParams calldata _permitParams\n ) external;\n\n /// Stability Pool depositor can withdraw a specified amount of ZUSD from the SOV Stability Pool and optionally convert the ZUSD to DLLR via Sovryn Mynt, all in a single transaction\n function withdrawFromSpAndConvertToDLLR(uint256 _zusdAmount) external;\n\n /**\n * Fallback function\n * Only callable by Active Pool, it just accounts for ETH received\n * receive() external payable;\n */\n}\n" + }, + "contracts/Interfaces/ITroveManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./ILiquityBase.sol\";\nimport \"./IStabilityPool.sol\";\nimport \"./IZUSDToken.sol\";\nimport \"./IZEROToken.sol\";\nimport \"./IZEROStaking.sol\";\nimport \"../Dependencies/Mynt/IMassetManager.sol\";\n\n/// Common interface for the Trove Manager.\ninterface ITroveManager is ILiquityBase {\n // --- Events ---\n\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerRedeemOpsAddressChanged(address _troveManagerRedeemOps);\n event LiquityBaseParamsAddressChanges(address _borrowerOperationsAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZEROTokenAddressChanged(address _zeroTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n\n event Liquidation(\n uint256 _liquidatedDebt,\n uint256 _liquidatedColl,\n uint256 _collGasCompensation,\n uint256 _ZUSDGasCompensation\n );\n event Redemption(\n uint256 _attemptedZUSDAmount,\n uint256 _actualZUSDAmount,\n uint256 _ETHSent,\n uint256 _ETHFee\n );\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 stake,\n uint8 operation\n );\n event TroveLiquidated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint8 operation\n );\n event BaseRateUpdated(uint256 _baseRate);\n event LastFeeOpTimeUpdated(uint256 _lastFeeOpTime);\n event TotalStakesUpdated(uint256 _newTotalStakes);\n event SystemSnapshotsUpdated(uint256 _totalStakesSnapshot, uint256 _totalCollateralSnapshot);\n event LTermsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveSnapshotsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveIndexUpdated(address _borrower, uint256 _newIndex);\n\n struct TroveManagerInitAddressesParams {\n address _feeDistributorAddress;\n address _troveManagerRedeemOps;\n address _liquityBaseParamsAddress;\n address _borrowerOperationsAddress;\n address _activePoolAddress;\n address _defaultPoolAddress;\n address _stabilityPoolAddress;\n address _gasPoolAddress;\n address _collSurplusPoolAddress;\n address _priceFeedAddress;\n address _zusdTokenAddress;\n address _sortedTrovesAddress;\n address _zeroTokenAddress;\n address _zeroStakingAddress;\n }\n\n // --- Functions ---\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _troveManagerInitAddresses addresses list to intialize TroveManager with _\n * _feeDistributorAddress feeDistributor contract address\n * _troveManagerRedeemOps TroveManagerRedeemOps contract address\n * _liquityBaseParamsAddress LiquityBaseParams contract address\n * _borrowerOperationsAddress BorrowerOperations contract address\n * _activePoolAddress ActivePool contract address\n * _defaultPoolAddress DefaultPool contract address\n * _stabilityPoolAddress StabilityPool contract address\n * _gasPoolAddress GasPool contract address\n * _collSurplusPoolAddress CollSurplusPool contract address\n * _priceFeedAddress PriceFeed contract address\n * _zusdTokenAddress ZUSDToken contract address\n * _sortedTrovesAddress SortedTroves contract address\n * _zeroTokenAddress ZEROToken contract address\n * _zeroStakingAddress ZEROStaking contract address\n */\n function setAddresses(\n TroveManagerInitAddressesParams memory _troveManagerInitAddresses\n ) external;\n\n function setTroveManagerRedeemOps(address _troveManagerRedeemOps) external;\n\n /// @return Trove owners count\n function getTroveOwnersCount() external view returns (uint256);\n\n /// @param _index Trove owner index\n /// @return Trove from TroveOwners array in given index\n function getTroveFromTroveOwnersArray(uint256 _index) external view returns (address);\n\n /// @param _borrower borrower address\n /// @return the nominal collateral ratio (ICR) of a given Trove, without the price. Takes a trove's pending coll and debt rewards from redistributions into account.\n function getNominalICR(address _borrower) external view returns (uint256);\n\n /// @notice computes the user’s individual collateralization ratio (ICR) based on their total collateral and total ZUSD debt. Returns 2^256 -1 if they have 0 debt.\n /// @param _borrower borrower address\n /// @param _price ETH price\n /// @return the current collateral ratio (ICR) of a given Trove. Takes a trove's pending coll and debt rewards from redistributions into account.\n function getCurrentICR(address _borrower, uint256 _price) external view returns (uint256);\n\n /// @notice Closes the trove if its ICR is lower than the minimum collateral ratio.\n /// @param _borrower borrower address\n function liquidate(address _borrower) external;\n\n /**\n * @notice Liquidate a sequence of troves. Closes a maximum number of n under-collateralized Troves,\n * starting from the one with the lowest collateral ratio in the system, and moving upwards\n * @param _n max number of under-collateralized Troves to liquidate\n */\n function liquidateTroves(uint256 _n) external;\n\n /**\n * @notice Attempt to liquidate a custom list of troves provided by the caller.\n * @param _troveArray list of trove addresses\n */\n function batchLiquidateTroves(address[] calldata _troveArray) external;\n\n /**\n * @notice Send _ZUSDamount ZUSD to the system and redeem the corresponding amount of collateral from as many Troves as are needed to fill the redemption\n * request. Applies pending rewards to a Trove before reducing its debt and coll.\n *\n * Note that if _amount is very large, this function can run out of gas, specially if traversed troves are small. This can be easily avoided by\n * splitting the total _amount in appropriate chunks and calling the function multiple times.\n *\n * Param `_maxIterations` can also be provided, so the loop through Troves is capped (if it’s zero, it will be ignored).This makes it easier to\n * avoid OOG for the frontend, as only knowing approximately the average cost of an iteration is enough, without needing to know the “topology”\n * of the trove list. It also avoids the need to set the cap in stone in the contract, nor doing gas calculations, as both gas price and opcode\n * costs can vary.\n *\n * All Troves that are redeemed from -- with the likely exception of the last one -- will end up with no debt left, therefore they will be closed.\n * If the last Trove does have some remaining debt, it has a finite ICR, and the reinsertion could be anywhere in the list, therefore it requires a hint.\n * A frontend should use getRedemptionHints() to calculate what the ICR of this Trove will be after redemption, and pass a hint for its position\n * in the sortedTroves list along with the ICR value that the hint was found for.\n *\n * If another transaction modifies the list between calling getRedemptionHints() and passing the hints to redeemCollateral(), it\n * is very likely that the last (partially) redeemed Trove would end up with a different ICR than what the hint is for. In this case the\n * redemption will stop after the last completely redeemed Trove and the sender will keep the remaining ZUSD amount, which they can attempt\n * to redeem later.\n *\n * @param _ZUSDAmount ZUSD amount to send to the system\n * @param _firstRedemptionHint calculated ICR hint of first trove after redemption\n * @param _maxIterations max Troves iterations (can be 0)\n * @param _maxFee max fee percentage to accept\n */\n function redeemCollateral(\n uint256 _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFee\n ) external;\n\n function redeemCollateralViaDLLR(\n uint256 _dllrAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage,\n IMassetManager.PermitParams calldata _permitParams\n ) external;\n\n /// @notice Update borrower's stake based on their latest collateral value\n /// @param _borrower borrower address\n function updateStakeAndTotalStakes(address _borrower) external returns (uint256);\n\n /// @notice Update borrower's snapshots of L_ETH and L_ZUSDDebt to reflect the current values\n /// @param _borrower borrower address\n function updateTroveRewardSnapshots(address _borrower) external;\n\n /// @notice Push the owner's address to the Trove owners list, and record the corresponding array index on the Trove struct\n /// @param _borrower borrower address\n /// @return index where Trove was inserted\n function addTroveOwnerToArray(address _borrower) external returns (uint256 index);\n\n /// @notice Add the borrowers's coll and debt rewards earned from redistributions, to their Trove\n /// @param _borrower borrower address\n function applyPendingRewards(address _borrower) external;\n\n /// @param _borrower borrower address\n /// @return the borrower's pending accumulated ETH reward, earned by their stake\n function getPendingETHReward(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return the borrower's pending accumulated ZUSD reward, earned by their stake\n function getPendingZUSDDebtReward(address _borrower) external view returns (uint256);\n\n /*\n * @notice A Trove has pending rewards if its snapshot is less than the current rewards per-unit-staked sum:\n * this indicates that rewards have occured since the snapshot was made, and the user therefore has\n * pending rewards\n *\n * @param _borrower borrower address\n * @return true if has pending rewards\n */\n function hasPendingRewards(address _borrower) external view returns (bool);\n\n /// @notice returns the Troves entire debt and coll, including pending rewards from redistributions.\n /// @param _borrower borrower address\n function getEntireDebtAndColl(\n address _borrower\n )\n external\n view\n returns (\n uint256 debt,\n uint256 coll,\n uint256 pendingZUSDDebtReward,\n uint256 pendingETHReward\n );\n\n /// @notice Close given trove. Called by BorrowerOperations.\n /// @param _borrower borrower address\n function closeTrove(address _borrower) external;\n\n /// @notice Remove borrower's stake from the totalStakes sum, and set their stake to 0\n /// @param _borrower borrower address\n function removeStake(address _borrower) external;\n\n /// @return calculated redemption rate using baseRate\n function getRedemptionRate() external view returns (uint256);\n\n /// @return calculated redemption rate using calculated decayed as base rate\n function getRedemptionRateWithDecay() external view returns (uint256);\n\n /// @notice The redemption fee is taken as a cut of the total ETH drawn from the system in a redemption. It is based on the current redemption rate.\n /// @param _ETHDrawn ETH drawn\n function getRedemptionFeeWithDecay(uint256 _ETHDrawn) external view returns (uint256);\n\n /// @return borrowing rate\n function getBorrowingRate() external view returns (uint256);\n\n /// @return borrowing rate calculated using decayed as base rate\n function getBorrowingRateWithDecay() external view returns (uint256);\n\n /// @param ZUSDDebt ZUSD debt amount to calculate fee\n /// @return borrowing fee using borrowing rate\n function getBorrowingFee(uint256 ZUSDDebt) external view returns (uint256);\n\n /// @param _ZUSDDebt ZUSD debt amount to calculate fee\n /// @return borrowing fee using borrowing rate with decay\n function getBorrowingFeeWithDecay(uint256 _ZUSDDebt) external view returns (uint256);\n\n /// @notice Updates the baseRate state variable based on time elapsed since the last redemption or ZUSD borrowing operation.\n function decayBaseRateFromBorrowing() external;\n\n /// @param _borrower borrower address\n /// @return Trove status from given trove\n function getTroveStatus(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return Trove stake from given trove\n function getTroveStake(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return Trove debt from given trove\n function getTroveDebt(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return Trove collateral from given trove\n function getTroveColl(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @param num status to set\n function setTroveStatus(address _borrower, uint256 num) external;\n\n /// @param _borrower borrower address\n /// @param _collIncrease amount of collateral to increase\n /// @return new trove collateral\n function increaseTroveColl(\n address _borrower,\n uint256 _collIncrease\n ) external returns (uint256);\n\n /// @param _borrower borrower address\n /// @param _collDecrease amount of collateral to decrease\n /// @return new trove collateral\n function decreaseTroveColl(\n address _borrower,\n uint256 _collDecrease\n ) external returns (uint256);\n\n /// @param _borrower borrower address\n /// @param _debtIncrease amount of debt to increase\n /// @return new trove debt\n function increaseTroveDebt(\n address _borrower,\n uint256 _debtIncrease\n ) external returns (uint256);\n\n /// @param _borrower borrower address\n /// @param _debtDecrease amount of debt to decrease\n /// @return new trove debt\n function decreaseTroveDebt(\n address _borrower,\n uint256 _debtDecrease\n ) external returns (uint256);\n\n /**\n * @param _price ETH price\n * @return the total collateralization ratio (TCR) of the system.\n * The TCR is based on the the entire system debt and collateral (including pending rewards).\n */\n function getTCR(uint256 _price) external view returns (uint256);\n\n function MCR() external view returns (uint256);\n\n function CCR() external view returns (uint256);\n\n /// @notice reveals whether or not the system is in Recovery Mode (i.e. whether the Total Collateralization Ratio (TCR) is below the Critical Collateralization Ratio (CCR)).\n function checkRecoveryMode(uint256 _price) external view returns (bool);\n}\n" + }, + "contracts/Interfaces/IWrbtc.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Dependencies/IERC20.sol\";\n\ninterface IWrbtc is IERC20 {\n\t\n\tfunction deposit() external payable;\n\n\tfunction withdraw(uint256 wad) external;\n\n}\n" + }, + "contracts/Interfaces/IZEROStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IZEROStaking {\n // --- Events --\n\n event ZEROTokenAddressSet(address _zeroTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event FeeDistributorAddressAddressSet(address _feeDistributorAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event StakeChanged(address indexed staker, uint256 newStake);\n event StakingGainsWithdrawn(address indexed staker, uint256 ZUSDGain, uint256 ETHGain);\n event F_ETHUpdated(uint256 _F_ETH);\n event F_ZUSDUpdated(uint256 _F_ZUSD);\n event TotalZEROStakedUpdated(uint256 _totalZEROStaked);\n event EtherSent(address _account, uint256 _amount);\n event StakerSnapshotsUpdated(address _staker, uint256 _F_ETH, uint256 _F_ZUSD);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _zeroTokenAddress ZEROToken contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _feeDistributorAddress FeeDistributorAddress contract address\n * @param _activePoolAddress ActivePool contract address\n */\n function setAddresses(\n address _zeroTokenAddress,\n address _zusdTokenAddress,\n address _feeDistributorAddress,\n address _activePoolAddress\n ) external;\n\n /// @notice If caller has a pre-existing stake, send any accumulated ETH and ZUSD gains to them.\n /// @param _ZEROamount ZERO tokens to stake\n function stake(uint256 _ZEROamount) external;\n\n /**\n * @notice Unstake the ZERO and send the it back to the caller, along with their accumulated ZUSD & ETH gains.\n * If requested amount > stake, send their entire stake.\n * @param _ZEROamount ZERO tokens to unstake\n */\n function unstake(uint256 _ZEROamount) external;\n\n /// @param _ETHFee ETH fee\n /// @notice increase ETH fee\n function increaseF_ETH(uint256 _ETHFee) external;\n\n /// @param _ZEROFee ZUSD fee\n /// @notice increase ZUSD fee\n function increaseF_ZUSD(uint256 _ZEROFee) external;\n\n /// @param _user user address\n /// @return pending ETH gain of given user\n function getPendingETHGain(address _user) external view returns (uint256);\n\n /// @param _user user address\n /// @return pending ZUSD gain of given user\n function getPendingZUSDGain(address _user) external view returns (uint256);\n}\n" + }, + "contracts/Interfaces/IZEROToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Dependencies/IERC2612.sol\";\n\ninterface IZEROToken is IERC20, IERC2612 { \n\n // --- Functions ---\n\n /// @notice send zero tokens to ZEROStaking contract\n /// @param _sender sender address\n /// @param _amount amount to send\n function sendToZEROStaking(address _sender, uint256 _amount) external;\n\n /// @return deployment start time\n function getDeploymentStartTime() external view returns (uint256);\n\n}\n" + }, + "contracts/Interfaces/IZUSDToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Dependencies/IERC2612.sol\";\n\ninterface IZUSDToken is IERC20, IERC2612 { \n \n // --- Events ---\n\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event StabilityPoolAddressChanged(address _newStabilityPoolAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n\n event ZUSDTokenBalanceUpdated(address _user, uint _amount);\n\n // --- Functions ---\n\n function mint(address _account, uint256 _amount) external;\n\n function burn(address _account, uint256 _amount) external;\n\n function sendToPool(address _sender, address poolAddress, uint256 _amount) external;\n\n function returnFromPool(address poolAddress, address user, uint256 _amount ) external;\n}\n" + }, + "contracts/LiquityBaseParams.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ILiquityBaseParams.sol\";\nimport \"./Dependencies/BaseMath.sol\";\nimport \"./Dependencies/LiquityMath.sol\";\n\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/Initializable.sol\";\n\ncontract LiquityBaseParams is ILiquityBaseParams, Ownable, Initializable, BaseMath {\n using SafeMath for uint256;\n\n /// Minimum collateral ratio for individual troves\n uint256 public override MCR;\n\n /// Critical system collateral ratio. If the system's total collateral ratio (TCR) falls below the CCR, Recovery Mode is triggered.\n uint256 public override CCR;\n\n uint256 public override PERCENT_DIVISOR;\n\n uint256 public override BORROWING_FEE_FLOOR;\n\n /**\n * Half-life of 12h. 12h = 720 min\n * (1/2) = d^720 => d = (1/2)^(1/720)\n */\n uint256 public override REDEMPTION_FEE_FLOOR;\n\n uint256 public override MAX_BORROWING_FEE;\n\n function initialize() public initializer onlyOwner {\n MCR = 1100000000000000000; // 110%\n CCR = 1500000000000000000; // 150%\n PERCENT_DIVISOR = 200; // dividing by 200 yields 0.5%\n BORROWING_FEE_FLOOR = (DECIMAL_PRECISION / 1000) * 5; // 0.5%\n REDEMPTION_FEE_FLOOR = (DECIMAL_PRECISION / 1000) * 5; // 0.5%\n MAX_BORROWING_FEE = (DECIMAL_PRECISION / 100) * 5; // 5%\n }\n\n function setMCR(uint256 MCR_) public onlyOwner {\n MCR = MCR_;\n }\n\n function setCCR(uint256 CCR_) public onlyOwner {\n CCR = CCR_;\n }\n\n function setPercentDivisor(uint256 PERCENT_DIVISOR_) public onlyOwner {\n PERCENT_DIVISOR = PERCENT_DIVISOR_;\n }\n\n function setBorrowingFeeFloor(uint256 BORROWING_FEE_FLOOR_) public onlyOwner {\n BORROWING_FEE_FLOOR = BORROWING_FEE_FLOOR_;\n }\n\n function setRedemptionFeeFloor(uint256 REDEMPTION_FEE_FLOOR_) public onlyOwner {\n REDEMPTION_FEE_FLOOR = REDEMPTION_FEE_FLOOR_;\n }\n\n function setMaxBorrowingFee(uint256 MAX_BORROWING_FEE_) public onlyOwner {\n MAX_BORROWING_FEE = MAX_BORROWING_FEE_;\n }\n}\n" + }, + "contracts/MultiTroveGetter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./TroveManager.sol\";\nimport \"./SortedTroves.sol\";\nimport \"./MultiTroveGetterStorage.sol\";\n\n/** Helper contract for grabbing Trove data for the front end. Not part of the core Zero system. */\ncontract MultiTroveGetter is MultiTroveGetterStorage {\n struct CombinedTroveData {\n address owner;\n uint256 debt;\n uint256 coll;\n uint256 stake;\n uint256 snapshotETH;\n uint256 snapshotZUSDDebt;\n }\n\n function setAddresses(TroveManager _troveManager, ISortedTroves _sortedTroves)\n public\n onlyOwner\n {\n troveManager = _troveManager;\n sortedTroves = _sortedTroves;\n }\n\n function getMultipleSortedTroves(int256 _startIdx, uint256 _count)\n external\n view\n returns (CombinedTroveData[] memory _troves)\n {\n uint256 startIdx;\n bool descend;\n\n if (_startIdx >= 0) {\n startIdx = uint256(_startIdx);\n descend = true;\n } else {\n startIdx = uint256(-(_startIdx + 1));\n descend = false;\n }\n\n uint256 sortedTrovesSize = sortedTroves.getSize();\n\n if (startIdx >= sortedTrovesSize) {\n _troves = new CombinedTroveData[](0);\n } else {\n uint256 maxCount = sortedTrovesSize - startIdx;\n\n if (_count > maxCount) {\n _count = maxCount;\n }\n\n if (descend) {\n _troves = _getMultipleSortedTrovesFromHead(startIdx, _count);\n } else {\n _troves = _getMultipleSortedTrovesFromTail(startIdx, _count);\n }\n }\n }\n\n function _getMultipleSortedTrovesFromHead(uint256 _startIdx, uint256 _count)\n internal\n view\n returns (CombinedTroveData[] memory _troves)\n {\n address currentTroveowner = sortedTroves.getFirst();\n\n for (uint256 idx = 0; idx < _startIdx; ++idx) {\n currentTroveowner = sortedTroves.getNext(currentTroveowner);\n }\n\n _troves = new CombinedTroveData[](_count);\n\n for (uint256 idx = 0; idx < _count; ++idx) {\n _troves[idx].owner = currentTroveowner;\n (\n _troves[idx].debt,\n _troves[idx].coll,\n _troves[idx].stake,\n /* status */\n /* arrayIndex */\n ,\n\n ) = troveManager.Troves(currentTroveowner);\n (_troves[idx].snapshotETH, _troves[idx].snapshotZUSDDebt) = troveManager\n .rewardSnapshots(currentTroveowner);\n\n currentTroveowner = sortedTroves.getNext(currentTroveowner);\n }\n }\n\n function _getMultipleSortedTrovesFromTail(uint256 _startIdx, uint256 _count)\n internal\n view\n returns (CombinedTroveData[] memory _troves)\n {\n address currentTroveowner = sortedTroves.getLast();\n\n for (uint256 idx = 0; idx < _startIdx; ++idx) {\n currentTroveowner = sortedTroves.getPrev(currentTroveowner);\n }\n\n _troves = new CombinedTroveData[](_count);\n\n for (uint256 idx = 0; idx < _count; ++idx) {\n _troves[idx].owner = currentTroveowner;\n (\n _troves[idx].debt,\n _troves[idx].coll,\n _troves[idx].stake,\n /* status */\n /* arrayIndex */\n ,\n\n ) = troveManager.Troves(currentTroveowner);\n (_troves[idx].snapshotETH, _troves[idx].snapshotZUSDDebt) = troveManager\n .rewardSnapshots(currentTroveowner);\n\n currentTroveowner = sortedTroves.getPrev(currentTroveowner);\n }\n }\n}\n" + }, + "contracts/MultiTroveGetterStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\nimport \"./TroveManager.sol\";\nimport \"./SortedTroves.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract MultiTroveGetterStorage is Ownable {\n TroveManager public troveManager; // XXX Troves missing from ITroveManager?\n ISortedTroves public sortedTroves;\n}\n" + }, + "contracts/PriceFeed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IPriceFeed.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./PriceFeedStorage.sol\";\n\n/// @title The system price feed adapter\n/// @notice The PriceFeed relies upon a main oracle and a secondary as a fallback in case of error\ncontract PriceFeed is PriceFeedStorage, IPriceFeed {\n event LastGoodPriceUpdated(uint256 _lastGoodPrice);\n event PriceFeedBroken(uint8 index, address priceFeedAddress);\n event PriceFeedUpdated(uint8 index, address newPriceFeedAddress);\n\n // --- Dependency setters ---\n\n function setAddresses(address _mainPriceFeed, address _backupPriceFeed) external onlyOwner {\n uint256 latestPrice = setAddress(0, _mainPriceFeed);\n setAddress(1, _backupPriceFeed);\n\n _storePrice(latestPrice);\n }\n\n // --- Functions ---\n\n /// @notice Returns the latest price obtained from the Oracle. Called by Zero functions that require a current price.\n /// It uses the main price feed and fallback to the backup one in case of an error. If both fail return the last\n /// good price seen.\n /// @dev It's also callable by anyone externally\n /// @return The price\n function fetchPrice() external override returns (uint256) {\n for (uint8 index = 0; index < 2; index++) {\n (uint256 price, bool success) = priceFeeds[index].latestAnswer();\n if (success) {\n _storePrice(price);\n return price;\n } else {\n emit PriceFeedBroken(index, address(priceFeeds[index]));\n }\n }\n return lastGoodPrice;\n }\n\n /// @notice Allows users to setup the main and the backup price feeds\n /// @param _index the oracle to be configured\n /// @param _newPriceFeed address where an IExternalPriceFeed implementation is located\n /// @return price the latest price of the inserted price feed\n function setAddress(uint8 _index, address _newPriceFeed) public onlyOwner returns (uint256) {\n require(_index < priceFeeds.length, \"Out of bounds when setting the price feed\");\n checkContract(_newPriceFeed);\n priceFeeds[_index] = IExternalPriceFeed(_newPriceFeed);\n (uint256 price, bool success) = priceFeeds[_index].latestAnswer();\n require(success, \"PriceFeed: Price feed must be working\");\n emit PriceFeedUpdated(_index, _newPriceFeed);\n return price;\n }\n\n // --- Helper functions ---\n function _storePrice(uint256 _currentPrice) internal {\n lastGoodPrice = _currentPrice;\n emit LastGoodPriceUpdated(_currentPrice);\n }\n}\n" + }, + "contracts/PriceFeedStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IPriceFeed.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/PriceFeed/IExternalPriceFeed.sol\";\nimport \"./Dependencies/CheckContract.sol\";\n\ncontract PriceFeedStorage is Ownable, CheckContract {\n string public constant NAME = \"PriceFeed\";\n\n IExternalPriceFeed[2] priceFeeds;\n\n // The last good price seen from an oracle by Zero\n uint256 public lastGoodPrice;\n}\n" + }, + "contracts/Proxy/BorrowerOperationsScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/IBorrowerOperations.sol\";\n\n\ncontract BorrowerOperationsScript is CheckContract {\n IBorrowerOperations immutable borrowerOperations;\n\n constructor(IBorrowerOperations _borrowerOperations) public {\n checkContract(address(_borrowerOperations));\n borrowerOperations = _borrowerOperations;\n }\n\n function openTrove(uint _maxFee, uint _ZUSDAmount, address _upperHint, address _lowerHint) external payable {\n borrowerOperations.openTrove{ value: msg.value }(_maxFee, _ZUSDAmount, _upperHint, _lowerHint);\n }\n\n function addColl(address _upperHint, address _lowerHint) external payable {\n borrowerOperations.addColl{ value: msg.value }(_upperHint, _lowerHint);\n }\n\n function withdrawColl(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.withdrawColl(_amount, _upperHint, _lowerHint);\n }\n\n function withdrawZUSD(uint _maxFee, uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.withdrawZUSD(_maxFee, _amount, _upperHint, _lowerHint);\n }\n\n function repayZUSD(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.repayZUSD(_amount, _upperHint, _lowerHint);\n }\n\n function closeTrove() external {\n borrowerOperations.closeTrove();\n }\n\n function adjustTrove(uint _maxFee, uint _collWithdrawal, uint _debtChange, bool isDebtIncrease, address _upperHint, address _lowerHint) external payable {\n borrowerOperations.adjustTrove{ value: msg.value }(_maxFee, _collWithdrawal, _debtChange, isDebtIncrease, _upperHint, _lowerHint);\n }\n\n function claimCollateral() external {\n borrowerOperations.claimCollateral();\n }\n}\n" + }, + "contracts/Proxy/BorrowerWrappersScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Interfaces/IBorrowerOperations.sol\";\nimport \"../Interfaces/ITroveManager.sol\";\nimport \"../Interfaces/IStabilityPool.sol\";\nimport \"../Interfaces/IPriceFeed.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\nimport \"./BorrowerOperationsScript.sol\";\nimport \"./ETHTransferScript.sol\";\nimport \"./ZEROStakingScript.sol\";\nimport \"../Dependencies/console.sol\";\n\n\ncontract BorrowerWrappersScript is BorrowerOperationsScript, ETHTransferScript, ZEROStakingScript {\n using SafeMath for uint;\n\n string constant public NAME = \"BorrowerWrappersScript\";\n\n ITroveManager immutable troveManager;\n IStabilityPool immutable stabilityPool;\n IPriceFeed immutable priceFeed;\n IERC20 immutable zusdToken;\n IERC20 immutable zeroToken;\n IZEROStaking immutable zeroStaking;\n\n constructor(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _zeroStakingAddress,\n address _stabilityPoolAddress,\n address _priceFeedAddress,\n address _zusdTokenAddress,\n address _zeroTokenAddress\n )\n BorrowerOperationsScript(IBorrowerOperations(_borrowerOperationsAddress))\n ZEROStakingScript(_zeroStakingAddress)\n public\n {\n checkContract(_troveManagerAddress);\n ITroveManager troveManagerCached = ITroveManager(_troveManagerAddress);\n troveManager = troveManagerCached;\n\n IStabilityPool stabilityPoolCached = IStabilityPool(_stabilityPoolAddress);\n checkContract(_stabilityPoolAddress);\n stabilityPool = stabilityPoolCached;\n\n IPriceFeed priceFeedCached = IPriceFeed(_priceFeedAddress); \n checkContract(_priceFeedAddress);\n priceFeed = priceFeedCached;\n\n checkContract(_zusdTokenAddress);\n zusdToken = IERC20(_zusdTokenAddress);\n\n checkContract(_zeroTokenAddress);\n zeroToken = IERC20(_zeroTokenAddress);\n\n IZEROStaking zeroStakingCached = IZEROStaking(_zeroStakingAddress);\n checkContract(_zeroStakingAddress);\n zeroStaking = zeroStakingCached;\n }\n\n function claimCollateralAndOpenTrove(uint _maxFee, uint _ZUSDAmount, address _upperHint, address _lowerHint) external payable {\n uint balanceBefore = address(this).balance;\n\n // Claim collateral\n borrowerOperations.claimCollateral();\n\n uint balanceAfter = address(this).balance;\n\n // already checked in CollSurplusPool\n assert(balanceAfter > balanceBefore);\n\n uint totalCollateral = balanceAfter.sub(balanceBefore).add(msg.value);\n\n // Open trove with obtained collateral, plus collateral sent by user\n borrowerOperations.openTrove{ value: totalCollateral }(_maxFee, _ZUSDAmount, _upperHint, _lowerHint);\n }\n\n function claimSPRewardsAndRecycle(uint _maxFee, address _upperHint, address _lowerHint) external {\n uint collBalanceBefore = address(this).balance;\n uint zeroBalanceBefore = zeroToken.balanceOf(address(this));\n\n // Claim rewards\n stabilityPool.withdrawFromSP(0);\n\n uint collBalanceAfter = address(this).balance;\n uint zeroBalanceAfter = zeroToken.balanceOf(address(this));\n uint claimedCollateral = collBalanceAfter.sub(collBalanceBefore);\n\n // Add claimed ETH to trove, get more ZUSD and stake it into the Stability Pool\n if (claimedCollateral > 0) {\n _requireUserHasTrove(address(this));\n uint ZUSDAmount = _getNetZUSDAmount(claimedCollateral);\n borrowerOperations.adjustTrove{ value: claimedCollateral }(_maxFee, 0, ZUSDAmount, true, _upperHint, _lowerHint);\n // Provide withdrawn ZUSD to Stability Pool\n if (ZUSDAmount > 0) {\n stabilityPool.provideToSP(ZUSDAmount, address(0));\n }\n }\n\n // Stake claimed ZERO\n uint claimedZERO = zeroBalanceAfter.sub(zeroBalanceBefore);\n if (claimedZERO > 0) {\n zeroStaking.stake(claimedZERO);\n }\n }\n\n function claimStakingGainsAndRecycle(uint _maxFee, address _upperHint, address _lowerHint) external {\n uint collBalanceBefore = address(this).balance;\n uint zusdBalanceBefore = zusdToken.balanceOf(address(this));\n uint zeroBalanceBefore = zeroToken.balanceOf(address(this));\n\n // Claim gains\n zeroStaking.unstake(0);\n\n uint gainedCollateral = address(this).balance.sub(collBalanceBefore); // stack too deep issues :'(\n uint gainedZUSD = zusdToken.balanceOf(address(this)).sub(zusdBalanceBefore);\n\n uint netZUSDAmount;\n // Top up trove and get more ZUSD, keeping ICR constant\n if (gainedCollateral > 0) {\n _requireUserHasTrove(address(this));\n netZUSDAmount = _getNetZUSDAmount(gainedCollateral);\n borrowerOperations.adjustTrove{ value: gainedCollateral }(_maxFee, 0, netZUSDAmount, true, _upperHint, _lowerHint);\n }\n\n uint totalZUSD = gainedZUSD.add(netZUSDAmount);\n if (totalZUSD > 0) {\n stabilityPool.provideToSP(totalZUSD, address(0));\n\n // Providing to Stability Pool also triggers ZERO claim, so stake it if any\n uint zeroBalanceAfter = zeroToken.balanceOf(address(this));\n uint claimedZERO = zeroBalanceAfter.sub(zeroBalanceBefore);\n if (claimedZERO > 0) {\n zeroStaking.stake(claimedZERO);\n }\n }\n\n }\n\n function _getNetZUSDAmount(uint _collateral) internal returns (uint) {\n uint price = priceFeed.fetchPrice();\n uint ICR = troveManager.getCurrentICR(address(this), price);\n\n uint ZUSDAmount = _collateral.mul(price).div(ICR);\n uint borrowingRate = troveManager.getBorrowingRateWithDecay();\n uint netDebt = ZUSDAmount.mul(LiquityMath.DECIMAL_PRECISION).div(LiquityMath.DECIMAL_PRECISION.add(borrowingRate));\n\n return netDebt;\n }\n\n function _requireUserHasTrove(address _depositor) internal view {\n require(troveManager.getTroveStatus(_depositor) == 1, \"BorrowerWrappersScript: caller must have an active trove\");\n }\n}\n" + }, + "contracts/Proxy/ETHTransferScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n\ncontract ETHTransferScript {\n function transferETH(address _recipient, uint256 _amount) external returns (bool) {\n (bool success, ) = _recipient.call{value: _amount}(\"\");\n return success;\n }\n}\n" + }, + "contracts/Proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Dependencies/Ownable.sol\";\n/**\n * @title Base Proxy contract.\n * \n * Adapted version of https://github.com/DistributedCollective/Sovryn-smart-contracts/blob/development/contracts/proxy/Proxy.sol \n *\n * @notice The proxy performs delegated calls to the contract implementation\n * it is pointing to. This way upgradable contracts are possible on blockchain.\n *\n * Delegating proxy contracts are widely used for both upgradeability and gas\n * savings. These proxies rely on a logic contract (also known as implementation\n * contract or master copy) that is called using delegatecall. This allows\n * proxies to keep a persistent state (storage and balance) while the code is\n * delegated to the logic contract.\n *\n * Proxy contract is meant to be inherited and its internal functions\n * _setImplementation and _setOwner to be called when upgrades become\n * neccessary.\n *\n * The loan token (iToken) contract as well as the protocol contract act as\n * proxies, delegating all calls to underlying contracts. Therefore, if you\n * want to interact with them using web3, you need to use the ABIs from the\n * contracts containing the actual logic or the interface contract.\n * ABI for LoanToken contracts: LoanTokenLogicStandard\n * ABI for Protocol contract: ISovryn\n *\n * @dev UpgradableProxy is the contract that inherits Proxy and wraps these\n * functions.\n * */\ncontract Proxy is Ownable {\n bytes32 private constant KEY_IMPLEMENTATION = keccak256(\"key.implementation\");\n\n event ImplementationChanged(\n address indexed _oldImplementation,\n address indexed _newImplementation\n );\n\n /**\n * @notice Set address of the implementation.\n * @param _implementation Address of the implementation.\n * */\n function _setImplementation(address _implementation) internal {\n require(_implementation != address(0), \"Proxy::setImplementation: invalid address\");\n emit ImplementationChanged(getImplementation(), _implementation);\n\n bytes32 key = KEY_IMPLEMENTATION;\n assembly {\n sstore(key, _implementation)\n }\n }\n\n /**\n * @notice Return address of the implementation.\n * @return _implementation Address of the implementation.\n * */\n function getImplementation() public view returns (address _implementation) {\n bytes32 key = KEY_IMPLEMENTATION;\n assembly {\n _implementation := sload(key)\n }\n }\n\n /**\n * @notice Fallback function performs a delegate call\n * to the actual implementation address is pointing this proxy.\n * Returns whatever the implementation call returns.\n * */\n fallback() external payable {\n delegate();\n }\n\n /**\n * @notice Fallback function performs a delegate call\n * to the actual implementation address is pointing this proxy.\n * Returns whatever the implementation call returns.\n * */\n receive() external payable {\n delegate();\n }\n\n function delegate() internal {\n address implementation = getImplementation();\n require(implementation != address(0), \"Proxy::(): implementation not found\");\n\n assembly {\n let pointer := mload(0x40)\n calldatacopy(pointer, 0, calldatasize())\n let result := delegatecall(gas(), implementation, pointer, calldatasize(), 0, 0)\n let size := returndatasize()\n returndatacopy(pointer, 0, size)\n\n switch result\n case 0 {\n revert(pointer, size)\n }\n default {\n return(pointer, size)\n }\n }\n }\n}\n" + }, + "contracts/Proxy/StabilityPoolScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/IStabilityPool.sol\";\n\n\ncontract StabilityPoolScript is CheckContract {\n string constant public NAME = \"StabilityPoolScript\";\n\n IStabilityPool immutable stabilityPool;\n\n constructor(IStabilityPool _stabilityPool) public {\n checkContract(address(_stabilityPool));\n stabilityPool = _stabilityPool;\n }\n\n function provideToSP(uint _amount, address _frontEndTag) external {\n stabilityPool.provideToSP(_amount, _frontEndTag);\n }\n\n function withdrawFromSP(uint _amount) external {\n stabilityPool.withdrawFromSP(_amount);\n }\n\n function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external {\n stabilityPool.withdrawETHGainToTrove(_upperHint, _lowerHint);\n }\n}\n" + }, + "contracts/Proxy/TokenScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/IERC20.sol\";\n\n\ncontract TokenScript is CheckContract {\n string constant public NAME = \"TokenScript\";\n\n IERC20 immutable token;\n\n constructor(address _tokenAddress) public {\n checkContract(_tokenAddress);\n token = IERC20(_tokenAddress);\n }\n\n function transfer(address recipient, uint256 amount) external returns (bool) {\n token.transfer(recipient, amount);\n }\n\n function allowance(address owner, address spender) external view returns (uint256) {\n token.allowance(owner, spender);\n }\n\n function approve(address spender, uint256 amount) external returns (bool) {\n token.approve(spender, amount);\n }\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {\n token.transferFrom(sender, recipient, amount);\n }\n\n function increaseAllowance(address spender, uint256 addedValue) external returns (bool) {\n token.increaseAllowance(spender, addedValue);\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool) {\n token.decreaseAllowance(spender, subtractedValue);\n }\n}\n" + }, + "contracts/Proxy/TroveManagerScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/ITroveManager.sol\";\n\n\ncontract TroveManagerScript is CheckContract {\n string constant public NAME = \"TroveManagerScript\";\n\n ITroveManager immutable troveManager;\n\n constructor(ITroveManager _troveManager) public {\n checkContract(address(_troveManager));\n troveManager = _troveManager;\n }\n\n function redeemCollateral(\n uint _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint _partialRedemptionHintNICR,\n uint _maxIterations,\n uint _maxFee\n ) external returns (uint) {\n troveManager.redeemCollateral(\n _ZUSDAmount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n _maxIterations,\n _maxFee\n );\n }\n}\n" + }, + "contracts/Proxy/UpgradableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Proxy.sol\";\n\n/**\n * @title Upgradable Proxy contract.\n *\n * Adapted version of https://github.com/DistributedCollective/Sovryn-smart-contracts/blob/development/contracts/proxy/UpgradableProxy.sol\n * \n * @notice A disadvantage of the immutable ledger is that nobody can change the\n * source code of a smart contract after it’s been deployed. In order to fix\n * bugs or introduce new features, smart contracts need to be upgradable somehow.\n *\n * Although it is not possible to upgrade the code of an already deployed smart\n * contract, it is possible to set-up a proxy contract architecture that will\n * allow to use new deployed contracts as if the main logic had been upgraded.\n *\n * A proxy architecture pattern is such that all message calls go through a\n * Proxy contract that will redirect them to the latest deployed contract logic.\n * To upgrade, a new version of the contract is deployed, and the Proxy is\n * updated to reference the new contract address.\n * */\ncontract UpgradableProxy is Proxy {\n /**\n * @notice Set address of the implementation.\n * @dev Wrapper for _setImplementation that exposes the function\n * as public for owner to be able to set a new version of the\n * contract as current pointing implementation.\n * @param _implementation Address of the implementation.\n * */\n function setImplementation(address _implementation) public onlyOwner {\n _setImplementation(_implementation);\n }\n\n}\n" + }, + "contracts/Proxy/ZEROStakingScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\n\n\ncontract ZEROStakingScript is CheckContract {\n IZEROStaking immutable ZEROStaking;\n\n constructor(address _zeroStakingAddress) public {\n checkContract(_zeroStakingAddress);\n ZEROStaking = IZEROStaking(_zeroStakingAddress);\n }\n\n function stake(uint _ZEROamount) external {\n ZEROStaking.stake(_ZEROamount);\n }\n}\n" + }, + "contracts/SortedTroves.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./SortedTrovesStorage.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\n\n/**\n * A sorted doubly linked list with nodes sorted in descending order.\n *\n * Nodes map to active Troves in the system - the ID property is the address of a Trove owner.\n * Nodes are ordered according to their current nominal individual collateral ratio (NICR),\n * which is like the ICR but without the price, i.e., just collateral / debt.\n *\n * The list optionally accepts insert position hints.\n *\n * NICRs are computed dynamically at runtime, and not stored on the Node. This is because NICRs of active Troves\n * change dynamically as liquidation events occur.\n *\n * The list relies on the fact that liquidation events preserve ordering: a liquidation decreases the NICRs of all active Troves,\n * but maintains their order. A node inserted based on current NICR will maintain the correct position,\n * relative to it's peers, as rewards accumulate, as long as it's raw collateral and debt have not changed.\n * Thus, Nodes remain sorted by current NICR.\n *\n * Nodes need only be re-inserted upon a Trove operation - when the owner adds or removes collateral or debt\n * to their position.\n *\n * The list is a modification of the following audited SortedDoublyLinkedList:\n * https://github.com/livepeer/protocol/blob/master/contracts/libraries/SortedDoublyLL.sol\n *\n *\n * Changes made in the Zero implementation:\n *\n * - Keys have been removed from nodes\n *\n * - Ordering checks for insertion are performed by comparing an NICR argument to the current NICR, calculated at runtime.\n * The list relies on the property that ordering by ICR is maintained as the ETH:USD price varies.\n *\n * - Public functions with parameters have been made internal to save gas, and given an external wrapper function for external access\n */\ncontract SortedTroves is SortedTrovesStorage, CheckContract, ISortedTroves {\n using SafeMath for uint256;\n\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event NodeAdded(address _id, uint256 _NICR);\n event NodeRemoved(address _id);\n\n // --- Dependency setters ---\n\n function setParams(\n uint256 _size,\n address _troveManagerAddress,\n address _borrowerOperationsAddress\n ) external override onlyOwner {\n require(_size > 0, \"SortedTroves: Size can’t be zero\");\n checkContract(_troveManagerAddress);\n checkContract(_borrowerOperationsAddress);\n\n data.maxSize = _size;\n\n troveManager = ITroveManager(_troveManagerAddress);\n borrowerOperationsAddress = _borrowerOperationsAddress;\n\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n }\n\n /**\n * @dev Add a node to the list\n * @param _id Node's id\n * @param _NICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n\n function insert(\n address _id,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external override {\n ITroveManager troveManagerCached = troveManager;\n\n _requireCallerIsBOorTroveM(troveManagerCached);\n _insert(troveManagerCached, _id, _NICR, _prevId, _nextId);\n }\n\n function _insert(\n ITroveManager _troveManager,\n address _id,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) internal {\n // List must not be full\n require(!isFull(), \"SortedTroves: List is full\");\n // List must not already contain node\n require(!contains(_id), \"SortedTroves: List already contains the node\");\n // Node id must not be null\n require(_id != address(0), \"SortedTroves: Id cannot be zero\");\n // NICR must be non-zero\n require(_NICR > 0, \"SortedTroves: NICR must be positive\");\n\n address prevId = _prevId;\n address nextId = _nextId;\n\n if (!_validInsertPosition(_troveManager, _NICR, prevId, nextId)) {\n // Sender's hint was not a valid insert position\n // Use sender's hint to find a valid insert position\n (prevId, nextId) = _findInsertPosition(_troveManager, _NICR, prevId, nextId);\n }\n\n data.nodes[_id].exists = true;\n\n if (prevId == address(0) && nextId == address(0)) {\n // Insert as head and tail\n data.head = _id;\n data.tail = _id;\n } else if (prevId == address(0)) {\n // Insert before `prevId` as the head\n data.nodes[_id].nextId = data.head;\n data.nodes[data.head].prevId = _id;\n data.head = _id;\n } else if (nextId == address(0)) {\n // Insert after `nextId` as the tail\n data.nodes[_id].prevId = data.tail;\n data.nodes[data.tail].nextId = _id;\n data.tail = _id;\n } else {\n // Insert at insert position between `prevId` and `nextId`\n data.nodes[_id].nextId = nextId;\n data.nodes[_id].prevId = prevId;\n data.nodes[prevId].nextId = _id;\n data.nodes[nextId].prevId = _id;\n }\n\n data.size = data.size.add(1);\n emit NodeAdded(_id, _NICR);\n }\n\n function remove(address _id) external override {\n _requireCallerIsTroveManager();\n _remove(_id);\n }\n\n /**\n * @dev Remove a node from the list\n * @param _id Node's id\n */\n function _remove(address _id) internal {\n // List must contain the node\n require(contains(_id), \"SortedTroves: List does not contain the id\");\n\n if (data.size > 1) {\n // List contains more than a single node\n if (_id == data.head) {\n // The removed node is the head\n // Set head to next node\n data.head = data.nodes[_id].nextId;\n // Set prev pointer of new head to null\n data.nodes[data.head].prevId = address(0);\n } else if (_id == data.tail) {\n // The removed node is the tail\n // Set tail to previous node\n data.tail = data.nodes[_id].prevId;\n // Set next pointer of new tail to null\n data.nodes[data.tail].nextId = address(0);\n } else {\n // The removed node is neither the head nor the tail\n // Set next pointer of previous node to the next node\n data.nodes[data.nodes[_id].prevId].nextId = data.nodes[_id].nextId;\n // Set prev pointer of next node to the previous node\n data.nodes[data.nodes[_id].nextId].prevId = data.nodes[_id].prevId;\n }\n } else {\n // List contains a single node\n // Set the head and tail to null\n data.head = address(0);\n data.tail = address(0);\n }\n\n delete data.nodes[_id];\n data.size = data.size.sub(1);\n NodeRemoved(_id);\n }\n\n /**\n * @dev Re-insert the node at a new position, based on its new NICR\n * @param _id Node's id\n * @param _newNICR Node's new NICR\n * @param _prevId Id of previous node for the new insert position\n * @param _nextId Id of next node for the new insert position\n */\n function reInsert(\n address _id,\n uint256 _newNICR,\n address _prevId,\n address _nextId\n ) external override {\n ITroveManager troveManagerCached = troveManager;\n\n _requireCallerIsBOorTroveM(troveManagerCached);\n // List must contain the node\n require(contains(_id), \"SortedTroves: List does not contain the id\");\n // NICR must be non-zero\n require(_newNICR > 0, \"SortedTroves: NICR must be positive\");\n\n // Remove node from the list\n _remove(_id);\n\n _insert(troveManagerCached, _id, _newNICR, _prevId, _nextId);\n }\n\n /**\n * @dev Checks if the list contains a node\n */\n function contains(address _id) public view override returns (bool) {\n return data.nodes[_id].exists;\n }\n\n /**\n * @dev Checks if the list is full\n */\n function isFull() public view override returns (bool) {\n return data.size == data.maxSize;\n }\n\n /**\n * @dev Checks if the list is empty\n */\n function isEmpty() public view override returns (bool) {\n return data.size == 0;\n }\n\n /**\n * @dev Returns the current size of the list\n */\n function getSize() external view override returns (uint256) {\n return data.size;\n }\n\n /**\n * @dev Returns the maximum size of the list\n */\n function getMaxSize() external view override returns (uint256) {\n return data.maxSize;\n }\n\n /**\n * @dev Returns the first node in the list (node with the largest NICR)\n */\n function getFirst() external view override returns (address) {\n return data.head;\n }\n\n /**\n * @dev Returns the last node in the list (node with the smallest NICR)\n */\n function getLast() external view override returns (address) {\n return data.tail;\n }\n\n /**\n * @dev Returns the next node (with a smaller NICR) in the list for a given node\n * @param _id Node's id\n */\n function getNext(address _id) external view override returns (address) {\n return data.nodes[_id].nextId;\n }\n\n /**\n * @dev Returns the previous node (with a larger NICR) in the list for a given node\n * @param _id Node's id\n */\n function getPrev(address _id) external view override returns (address) {\n return data.nodes[_id].prevId;\n }\n\n /**\n * @dev Check if a pair of nodes is a valid insertion point for a new node with the given NICR\n * @param _NICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function validInsertPosition(\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external view override returns (bool) {\n return _validInsertPosition(troveManager, _NICR, _prevId, _nextId);\n }\n\n function _validInsertPosition(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) internal view returns (bool) {\n if (_prevId == address(0) && _nextId == address(0)) {\n // `(null, null)` is a valid insert position if the list is empty\n return isEmpty();\n } else if (_prevId == address(0)) {\n // `(null, _nextId)` is a valid insert position if `_nextId` is the head of the list\n return data.head == _nextId && _NICR >= _troveManager.getNominalICR(_nextId);\n } else if (_nextId == address(0)) {\n // `(_prevId, null)` is a valid insert position if `_prevId` is the tail of the list\n return data.tail == _prevId && _NICR <= _troveManager.getNominalICR(_prevId);\n } else {\n // `(_prevId, _nextId)` is a valid insert position if they are adjacent nodes and `_NICR` falls between the two nodes' NICRs\n return\n data.nodes[_prevId].nextId == _nextId &&\n _troveManager.getNominalICR(_prevId) >= _NICR &&\n _NICR >= _troveManager.getNominalICR(_nextId);\n }\n }\n\n /**\n * @dev Descend the list (larger NICRs to smaller NICRs) to find a valid insert position\n * @param _troveManager TroveManager contract, passed in as param to save SLOAD’s\n * @param _NICR Node's NICR\n * @param _startId Id of node to start descending the list from\n */\n function _descendList(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _startId\n ) internal view returns (address, address) {\n // If `_startId` is the head, check if the insert position is before the head\n if (data.head == _startId && _NICR >= _troveManager.getNominalICR(_startId)) {\n return (address(0), _startId);\n }\n\n address prevId = _startId;\n address nextId = data.nodes[prevId].nextId;\n\n // Descend the list until we reach the end or until we find a valid insert position\n while (\n prevId != address(0) && !_validInsertPosition(_troveManager, _NICR, prevId, nextId)\n ) {\n prevId = data.nodes[prevId].nextId;\n nextId = data.nodes[prevId].nextId;\n }\n\n return (prevId, nextId);\n }\n\n /**\n * @dev Ascend the list (smaller NICRs to larger NICRs) to find a valid insert position\n * @param _troveManager TroveManager contract, passed in as param to save SLOAD’s\n * @param _NICR Node's NICR\n * @param _startId Id of node to start ascending the list from\n */\n function _ascendList(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _startId\n ) internal view returns (address, address) {\n // If `_startId` is the tail, check if the insert position is after the tail\n if (data.tail == _startId && _NICR <= _troveManager.getNominalICR(_startId)) {\n return (_startId, address(0));\n }\n\n address nextId = _startId;\n address prevId = data.nodes[nextId].prevId;\n\n // Ascend the list until we reach the end or until we find a valid insertion point\n while (\n nextId != address(0) && !_validInsertPosition(_troveManager, _NICR, prevId, nextId)\n ) {\n nextId = data.nodes[nextId].prevId;\n prevId = data.nodes[nextId].prevId;\n }\n\n return (prevId, nextId);\n }\n\n /**\n * @dev Find the insert position for a new node with the given NICR\n * @param _NICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function findInsertPosition(\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external view override returns (address, address) {\n return _findInsertPosition(troveManager, _NICR, _prevId, _nextId);\n }\n\n function _findInsertPosition(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) internal view returns (address, address) {\n address prevId = _prevId;\n address nextId = _nextId;\n\n if (prevId != address(0)) {\n if (!contains(prevId) || _NICR > _troveManager.getNominalICR(prevId)) {\n // `prevId` does not exist anymore or now has a smaller NICR than the given NICR\n prevId = address(0);\n }\n }\n\n if (nextId != address(0)) {\n if (!contains(nextId) || _NICR < _troveManager.getNominalICR(nextId)) {\n // `nextId` does not exist anymore or now has a larger NICR than the given NICR\n nextId = address(0);\n }\n }\n\n if (prevId == address(0) && nextId == address(0)) {\n // No hint - descend list starting from head\n return _descendList(_troveManager, _NICR, data.head);\n } else if (prevId == address(0)) {\n // No `prevId` for hint - ascend list starting from `nextId`\n return _ascendList(_troveManager, _NICR, nextId);\n } else if (nextId == address(0)) {\n // No `nextId` for hint - descend list starting from `prevId`\n return _descendList(_troveManager, _NICR, prevId);\n } else {\n // Descend list starting from `prevId`\n return _descendList(_troveManager, _NICR, prevId);\n }\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsTroveManager() internal view {\n require(\n msg.sender == address(troveManager),\n \"SortedTroves: Caller is not the TroveManager\"\n );\n }\n\n function _requireCallerIsBOorTroveM(ITroveManager _troveManager) internal view {\n require(\n msg.sender == borrowerOperationsAddress || msg.sender == address(_troveManager),\n \"SortedTroves: Caller is neither BO nor TroveM\"\n );\n }\n}\n" + }, + "contracts/SortedTrovesStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\n\ncontract SortedTrovesStorage is Ownable {\n string public constant NAME = \"SortedTroves\";\n\n address public borrowerOperationsAddress;\n\n ITroveManager public troveManager;\n\n // Information for a node in the list\n struct Node {\n bool exists;\n address nextId; // Id of next node (smaller NICR) in the list\n address prevId; // Id of previous node (larger NICR) in the list\n }\n\n // Information for the list\n struct Data {\n address head; // Head of the list. Also the node in the list with the largest NICR\n address tail; // Tail of the list. Also the node in the list with the smallest NICR\n uint256 maxSize; // Maximum size of the list\n uint256 size; // Current size of the list\n mapping(address => Node) nodes; // Track the corresponding ids for each node in the list\n }\n\n Data public data;\n}\n" + }, + "contracts/StabilityPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ICommunityIssuance.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/LiquitySafeMath128.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/Mynt/MyntLib.sol\";\nimport \"./StabilityPoolStorage.sol\";\n\n/**\n * The Stability Pool holds ZUSD tokens deposited by Stability Pool depositors.\n *\n * When a trove is liquidated, then depending on system conditions, some of its ZUSD debt gets offset with\n * ZUSD in the Stability Pool: that is, the offset debt evaporates, and an equal amount of ZUSD tokens in the Stability Pool is burned.\n *\n * Thus, a liquidation causes each depositor to receive a ZUSD loss, in proportion to their deposit as a share of total deposits.\n * They also receive an ETH gain, as the ETH collateral of the liquidated trove is distributed among Stability depositors,\n * in the same proportion.\n *\n * When a liquidation occurs, it depletes every deposit by the same fraction: for example, a liquidation that depletes 40%\n * of the total ZUSD in the Stability Pool, depletes 40% of each deposit.\n *\n * A deposit that has experienced a series of liquidations is termed a \"compounded deposit\": each liquidation depletes the deposit,\n * multiplying it by some factor in range ]0,1[\n *\n *\n * --- IMPLEMENTATION ---\n *\n * We use a highly scalable method of tracking deposits and ETH gains that has O(1) complexity.\n *\n * When a liquidation occurs, rather than updating each depositor's deposit and ETH gain, we simply update two state variables:\n * a product P, and a sum S.\n *\n * A mathematical manipulation allows us to factor out the initial deposit, and accurately track all depositors' compounded deposits\n * and accumulated ETH gains over time, as liquidations occur, using just these two variables P and S. When depositors join the\n * Stability Pool, they get a snapshot of the latest P and S: P_t and S_t, respectively.\n *\n * The formula for a depositor's accumulated ETH gain is derived here:\n * https://github.com/liquity/dev/blob/main/packages/contracts/mathProofs/Scalable%20Compounding%20Stability%20Pool%20Deposits.pdf\n *\n * For a given deposit d_t, the ratio P/P_t tells us the factor by which a deposit has decreased since it joined the Stability Pool,\n * and the term d_t * (S - S_t)/P_t gives us the deposit's total accumulated ETH gain.\n *\n * Each liquidation updates the product P and sum S. After a series of liquidations, a compounded deposit and corresponding ETH gain\n * can be calculated using the initial deposit, the depositor’s snapshots of P and S, and the latest values of P and S.\n *\n * Any time a depositor updates their deposit (withdrawal, top-up) their accumulated ETH gain is paid out, their new deposit is recorded\n * (based on their latest compounded deposit and modified by the withdrawal/top-up), and they receive new snapshots of the latest P and S.\n * Essentially, they make a fresh deposit that overwrites the old one.\n *\n *\n * --- SCALE FACTOR ---\n *\n * Since P is a running product in range ]0,1] that is always-decreasing, it should never reach 0 when multiplied by a number in range ]0,1[.\n * Unfortunately, Solidity floor division always reaches 0, sooner or later.\n *\n * A series of liquidations that nearly empty the Pool (and thus each multiply P by a very small number in range ]0,1[ ) may push P\n * to its 18 digit decimal limit, and round it to 0, when in fact the Pool hasn't been emptied: this would break deposit tracking.\n *\n * So, to track P accurately, we use a scale factor: if a liquidation would cause P to decrease to <1e-9 (and be rounded to 0 by Solidity),\n * we first multiply P by 1e9, and increment a currentScale factor by 1.\n *\n * The added benefit of using 1e9 for the scale factor (rather than 1e18) is that it ensures negligible precision loss close to the\n * scale boundary: when P is at its minimum value of 1e9, the relative precision loss in P due to floor division is only on the\n * order of 1e-9.\n *\n * --- EPOCHS ---\n *\n * Whenever a liquidation fully empties the Stability Pool, all deposits should become 0. However, setting P to 0 would make P be 0\n * forever, and break all future reward calculations.\n *\n * So, every time the Stability Pool is emptied by a liquidation, we reset P = 1 and currentScale = 0, and increment the currentEpoch by 1.\n *\n * --- TRACKING DEPOSIT OVER SCALE CHANGES AND EPOCHS ---\n *\n * When a deposit is made, it gets snapshots of the currentEpoch and the currentScale.\n *\n * When calculating a compounded deposit, we compare the current epoch to the deposit's epoch snapshot. If the current epoch is newer,\n * then the deposit was present during a pool-emptying liquidation, and necessarily has been depleted to 0.\n *\n * Otherwise, we then compare the current scale to the deposit's scale snapshot. If they're equal, the compounded deposit is given by d_t * P/P_t.\n * If it spans one scale change, it is given by d_t * P/(P_t * 1e9). If it spans more than one scale change, we define the compounded deposit\n * as 0, since it is now less than 1e-9'th of its initial value (e.g. a deposit of 1 billion ZUSD has depleted to < 1 ZUSD).\n *\n *\n * --- TRACKING DEPOSITOR'S ETH GAIN OVER SCALE CHANGES AND EPOCHS ---\n *\n * In the current epoch, the latest value of S is stored upon each scale change, and the mapping (scale -> S) is stored for each epoch.\n *\n * This allows us to calculate a deposit's accumulated ETH gain, during the epoch in which the deposit was non-sov and earned ETH.\n *\n * We calculate the depositor's accumulated ETH gain for the scale at which they made the deposit, using the ETH gain formula:\n * e_1 = d_t * (S - S_t) / P_t\n *\n * and also for scale after, taking care to divide the latter by a factor of 1e9:\n * e_2 = d_t * S / (P_t * 1e9)\n *\n * The gain in the second scale will be full, as the starting point was in the previous scale, thus no need to subtract anything.\n * The deposit therefore was present for reward events from the beginning of that second scale.\n *\n * S_i-S_t + S_{i+1}\n * .<--------.------------>\n * . .\n * . S_i . S_{i+1}\n * <--.-------->.<----------->\n * S_t. .\n * <->. .\n * t .\n * |---+---------|-------------|-----...\n * i i+1\n *\n * The sum of (e_1 + e_2) captures the depositor's total accumulated ETH gain, handling the case where their\n * deposit spanned one scale change. We only care about gains across one scale change, since the compounded\n * deposit is defined as being 0 once it has spanned more than one scale change.\n *\n *\n * --- UPDATING P WHEN A LIQUIDATION OCCURS ---\n *\n * Please see the implementation spec in the proof document, which closely follows on from the compounded deposit / ETH gain derivations:\n * https://github.com/liquity/liquity/blob/master/papers/Scalable_Reward_Distribution_with_Compounding_Stakes.pdf\n *\n *\n * --- SOV ISSUANCE TO STABILITY POOL DEPOSITORS ---\n *\n * An SOV issuance event occurs at every deposit operation, and every liquidation.\n *\n * Each deposit is tagged with the address of the front end through which it was made.\n *\n * All deposits earn a share of the issued SOV in proportion to the deposit as a share of total deposits. The SOV earned\n * by a given deposit, is split between the depositor and the front end through which the deposit was made, based on the front end's kickbackRate.\n *\n * Please see the system Readme for an overview:\n * https://github.com/liquity/dev/blob/main/README.md#zero-issuance-to-stability-providers\n *\n * We use the same mathematical product-sum approach to track SOV gains for depositors, where 'G' is the sum corresponding to SOV gains.\n * The product P (and snapshot P_t) is re-used, as the ratio P/P_t tracks a deposit's depletion due to liquidations.\n *\n */\ncontract StabilityPool is LiquityBase, StabilityPoolStorage, CheckContract, IStabilityPool {\n using LiquitySafeMath128 for uint128;\n address private constant ADDRESS_ZERO = address(0);\n\n // --- Events ---\n\n event StabilityPoolETHBalanceUpdated(uint256 _newBalance);\n event StabilityPoolZUSDBalanceUpdated(uint256 _newBalance);\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n event DefaultPoolAddressChanged(address _newDefaultPoolAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event SortedTrovesAddressChanged(address _newSortedTrovesAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event CommunityIssuanceAddressChanged(address _newCommunityIssuanceAddress);\n\n event P_Updated(uint256 _P);\n event S_Updated(uint256 _S, uint128 _epoch, uint128 _scale);\n event G_Updated(uint256 _G, uint128 _epoch, uint128 _scale);\n event EpochUpdated(uint128 _currentEpoch);\n event ScaleUpdated(uint128 _currentScale);\n\n event FrontEndRegistered(address indexed _frontEnd, uint256 _kickbackRate);\n event FrontEndTagSet(address indexed _depositor, address indexed _frontEnd);\n\n event DepositSnapshotUpdated(address indexed _depositor, uint256 _P, uint256 _S, uint256 _G);\n event FrontEndSnapshotUpdated(address indexed _frontEnd, uint256 _P, uint256 _G);\n event UserDepositChanged(address indexed _depositor, uint256 _newDeposit);\n event FrontEndStakeChanged(\n address indexed _frontEnd,\n uint256 _newFrontEndStake,\n address _depositor\n );\n\n event ETHGainWithdrawn(address indexed _depositor, uint256 _ETH, uint256 _ZUSDLoss);\n event SOVPaidToDepositor(address indexed _depositor, uint256 _SOV);\n event SOVPaidToFrontEnd(address indexed _frontEnd, uint256 _SOV);\n event EtherSent(address _to, uint256 _amount);\n\n // --- Contract setters ---\n\n function setAddresses(\n address _liquityBaseParamsAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _zusdTokenAddress,\n address _sortedTrovesAddress,\n address _priceFeedAddress,\n address _communityIssuanceAddress\n ) external override onlyOwner {\n checkContract(_liquityBaseParamsAddress);\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_sortedTrovesAddress);\n checkContract(_priceFeedAddress);\n checkContract(_communityIssuanceAddress);\n\n P = DECIMAL_PRECISION;\n\n liquityBaseParams = ILiquityBaseParams(_liquityBaseParamsAddress);\n borrowerOperations = IBorrowerOperations(_borrowerOperationsAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n activePool = IActivePool(_activePoolAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n priceFeed = IPriceFeed(_priceFeedAddress);\n communityIssuance = ICommunityIssuance(_communityIssuanceAddress);\n\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n emit ZUSDTokenAddressChanged(_zusdTokenAddress);\n emit SortedTrovesAddressChanged(_sortedTrovesAddress);\n emit PriceFeedAddressChanged(_priceFeedAddress);\n emit CommunityIssuanceAddressChanged(_communityIssuanceAddress);\n }\n\n /**\n * @dev setter function specific for community issuance contract.\n * @param _communityIssuanceAddress address of new community issuance contract.\n */\n function setCommunityIssuanceAddress(address _communityIssuanceAddress) external onlyOwner {\n checkContract(_communityIssuanceAddress);\n communityIssuance = ICommunityIssuance(_communityIssuanceAddress);\n emit CommunityIssuanceAddressChanged(_communityIssuanceAddress);\n }\n\n // --- Getters for public variables. Required by IPool interface ---\n\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n function getTotalZUSDDeposits() external view override returns (uint256) {\n return totalZUSDDeposits;\n }\n\n // --- External Depositor Functions ---\n\n /** provideToSP():\n *\n * - Triggers a SOV issuance, based on time passed since the last issuance and total amount of ZUSD is deposited. The SOV issuance is shared between *all* depositors and front ends\n * - Tags the deposit with the provided front end tag param, if it's a new deposit\n * - Sends depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Increases deposit and tagged front end's stake, and takes new snapshots for each.\n */\n function provideToSP(uint256 _amount, address _frontEndTag) external override {\n _provideToSP(_amount, _frontEndTag);\n }\n\n function _provideToSP(uint256 _amount, address _frontEndTag) internal {\n _requireFrontEndIsRegisteredOrZero(_frontEndTag);\n _requireFrontEndNotRegistered(msg.sender);\n _requireNonZeroAmount(_amount);\n\n uint256 initialDeposit = deposits[msg.sender].initialValue;\n\n ICommunityIssuance communityIssuanceCached = communityIssuance;\n\n _triggerSOVIssuance(communityIssuanceCached);\n\n if (initialDeposit == 0) {\n _setFrontEndTag(msg.sender, _frontEndTag);\n }\n uint256 depositorETHGain = getDepositorETHGain(msg.sender);\n uint256 compoundedZUSDDeposit = getCompoundedZUSDDeposit(msg.sender);\n uint256 ZUSDLoss = initialDeposit.sub(compoundedZUSDDeposit); // Needed only for event log\n\n // First pay out any SOV gains\n address frontEnd = deposits[msg.sender].frontEndTag;\n _payOutSOVGains(communityIssuanceCached, msg.sender, frontEnd);\n\n // Update front end stake\n uint256 compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd);\n uint256 newFrontEndStake = compoundedFrontEndStake.add(_amount);\n _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake);\n emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender);\n\n _sendZUSDtoStabilityPool(msg.sender, _amount);\n\n uint256 newDeposit = compoundedZUSDDeposit.add(_amount);\n _updateDepositAndSnapshots(msg.sender, newDeposit);\n emit UserDepositChanged(msg.sender, newDeposit);\n\n emit ETHGainWithdrawn(msg.sender, depositorETHGain, ZUSDLoss); // ZUSD Loss required for event log\n\n _sendETHGainToDepositor(depositorETHGain);\n }\n\n ///DLLR _owner or _spender can convert a specified amount of DLLR into ZUSD via Sovryn Mynt and deposit the ZUSD into the SOV Stability Pool, all in a single transaction\n function provideToSpFromDLLR(\n uint256 _dllrAmount,\n IMassetManager.PermitParams calldata _permitParams\n ) external override {\n uint256 _ZUSDAmount = MyntLib.redeemZusdFromDllrWithPermit(\n borrowerOperations.getMassetManager(),\n _dllrAmount,\n address(zusdToken),\n _permitParams\n );\n\n _provideToSP(_ZUSDAmount, ADDRESS_ZERO);\n }\n\n /** withdrawFromSP():\n *\n * - Triggers a SOV issuance, based on time passed since the last issuance and total amount of ZUSD is deposited. The SOV issuance is shared between *all* depositors and front ends\n * - Removes the deposit's front end tag if it is a full withdrawal\n * - Sends all depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Decreases deposit and tagged front end's stake, and takes new snapshots for each.\n *\n * If _amount > userDeposit, the user withdraws all of their compounded deposit.\n */\n function withdrawFromSP(uint256 _amount) external override {\n _withdrawFromSpTo(_amount, msg.sender);\n }\n\n ///@return actual ZUSD amount withdrawn\n function _withdrawFromSpTo(uint256 _amount, address _receiver) internal returns (uint256) {\n require(_receiver != address(0), \"SP::_withdrawFromSpTo: _receiver is zero address\");\n if (_amount != 0) {\n _requireNoUnderCollateralizedTroves();\n }\n uint256 initialDeposit = deposits[msg.sender].initialValue;\n _requireUserHasDeposit(initialDeposit);\n\n ICommunityIssuance communityIssuanceCached = communityIssuance;\n\n _triggerSOVIssuance(communityIssuanceCached);\n\n uint256 depositorETHGain = getDepositorETHGain(msg.sender);\n\n uint256 compoundedZUSDDeposit = getCompoundedZUSDDeposit(msg.sender);\n uint256 ZUSDtoWithdraw = LiquityMath._min(_amount, compoundedZUSDDeposit);\n uint256 ZUSDLoss = initialDeposit.sub(compoundedZUSDDeposit); // Needed only for event log\n\n // First pay out any SOV gains\n address frontEnd = deposits[msg.sender].frontEndTag;\n _payOutSOVGains(communityIssuanceCached, msg.sender, frontEnd);\n\n // Update front end stake\n uint256 compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd);\n uint256 newFrontEndStake = compoundedFrontEndStake.sub(ZUSDtoWithdraw);\n _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake);\n emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender);\n\n _sendZUSDToDepositor(_receiver, ZUSDtoWithdraw);\n\n // Update deposit\n uint256 newDeposit = compoundedZUSDDeposit.sub(ZUSDtoWithdraw);\n _updateDepositAndSnapshots(msg.sender, newDeposit);\n emit UserDepositChanged(msg.sender, newDeposit);\n\n emit ETHGainWithdrawn(msg.sender, depositorETHGain, ZUSDLoss); // ZUSD Loss required for event log\n\n _sendETHGainTo(depositorETHGain, msg.sender);\n\n return ZUSDtoWithdraw;\n }\n\n ///Stability Pool depositor can withdraw a specified amount of ZUSD from the SOV Stability Pool and convert the ZUSD to DLLR via Sovryn Mynt, all in a single transaction\n function withdrawFromSpAndConvertToDLLR(uint256 _zusdAmountRequested) external override {\n IMassetManager massetManager = borrowerOperations.getMassetManager();\n uint256 amountWithdrawn = _withdrawFromSpTo(_zusdAmountRequested, address(this));\n require(\n zusdToken.approve(address(massetManager), amountWithdrawn),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n massetManager.mintTo(address(zusdToken), amountWithdrawn, msg.sender);\n emit WithdrawFromSpAndConvertToDLLR(msg.sender, _zusdAmountRequested, amountWithdrawn);\n }\n\n /** withdrawETHGainToTrove:\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Sends all depositor's SOV gain to depositor\n * - Sends all tagged front end's SOV gain to the tagged front end\n * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove\n * - Leaves their compounded deposit in the Stability Pool\n * - Updates snapshots for deposit and tagged front end stake */\n function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external override {\n uint256 initialDeposit = deposits[msg.sender].initialValue;\n _requireUserHasDeposit(initialDeposit);\n _requireUserHasTrove(msg.sender);\n _requireUserHasETHGain(msg.sender);\n\n ICommunityIssuance communityIssuanceCached = communityIssuance;\n\n _triggerSOVIssuance(communityIssuanceCached);\n\n uint256 depositorETHGain = getDepositorETHGain(msg.sender);\n\n uint256 compoundedZUSDDeposit = getCompoundedZUSDDeposit(msg.sender);\n uint256 ZUSDLoss = initialDeposit.sub(compoundedZUSDDeposit); // Needed only for event log\n\n // First pay out any SOV gains\n address frontEnd = deposits[msg.sender].frontEndTag;\n _payOutSOVGains(communityIssuanceCached, msg.sender, frontEnd);\n\n // Update front end stake\n uint256 compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd);\n uint256 newFrontEndStake = compoundedFrontEndStake;\n _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake);\n emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender);\n\n _updateDepositAndSnapshots(msg.sender, compoundedZUSDDeposit);\n\n /* Emit events before transferring ETH gain to Trove.\n This lets the event log make more sense (i.e. so it appears that first the ETH gain is withdrawn\n and then it is deposited into the Trove, not the other way around). */\n emit ETHGainWithdrawn(msg.sender, depositorETHGain, ZUSDLoss);\n emit UserDepositChanged(msg.sender, compoundedZUSDDeposit);\n\n ETH = ETH.sub(depositorETHGain);\n emit StabilityPoolETHBalanceUpdated(ETH);\n emit EtherSent(msg.sender, depositorETHGain);\n\n borrowerOperations.moveETHGainToTrove{ value: depositorETHGain }(\n msg.sender,\n _upperHint,\n _lowerHint\n );\n }\n\n // --- SOV issuance functions ---\n\n function _triggerSOVIssuance(ICommunityIssuance _communityIssuance) internal {\n uint256 SOVIssuance = _communityIssuance.issueSOV(totalZUSDDeposits);\n _updateG(SOVIssuance);\n }\n\n function _updateG(uint256 _SOVIssuance) internal {\n uint256 totalZUSD = totalZUSDDeposits; // cached to save an SLOAD\n /*\n * When total deposits is 0, G is not updated. In this case, the SOV issued can not be obtained by later\n * depositors - it is missed out on, and remains in the balanceof the CommunityIssuance contract.\n *\n */\n if (totalZUSD == 0 || _SOVIssuance == 0) {\n return;\n }\n\n uint256 SOVPerUnitStaked;\n SOVPerUnitStaked = _computeSOVPerUnitStaked(_SOVIssuance, totalZUSD);\n\n uint256 marginalSOVGain = SOVPerUnitStaked.mul(P);\n epochToScaleToG[currentEpoch][currentScale] = epochToScaleToG[currentEpoch][currentScale]\n .add(marginalSOVGain);\n\n emit G_Updated(epochToScaleToG[currentEpoch][currentScale], currentEpoch, currentScale);\n }\n\n function _computeSOVPerUnitStaked(uint256 _SOVIssuance, uint256 _totalZUSDDeposits)\n internal\n returns (uint256)\n {\n /*\n * Calculate the SOV-per-unit staked. Division uses a \"feedback\" error correction, to keep the\n * cumulative error low in the running total G:\n *\n * 1) Form a numerator which compensates for the floor division error that occurred the last time this\n * function was called.\n * 2) Calculate \"per-unit-staked\" ratio.\n * 3) Multiply the ratio back by its denominator, to reveal the current floor division error.\n * 4) Store this error for use in the next correction when this function is called.\n * 5) Note: static analysis tools complain about this \"division before multiplication\", however, it is intended.\n */\n uint256 SOVNumerator = _SOVIssuance.mul(DECIMAL_PRECISION).add(lastSOVError);\n\n uint256 SOVPerUnitStaked = SOVNumerator.div(_totalZUSDDeposits);\n lastSOVError = SOVNumerator.sub(SOVPerUnitStaked.mul(_totalZUSDDeposits));\n\n return SOVPerUnitStaked;\n }\n\n // --- Liquidation functions ---\n\n /**\n * Cancels out the specified debt against the ZUSD contained in the Stability Pool (as far as possible)\n * and transfers the Trove's ETH collateral from ActivePool to StabilityPool.\n * Only called by liquidation functions in the TroveManager.\n */\n function offset(uint256 _debtToOffset, uint256 _collToAdd) external override {\n _requireCallerIsTroveManager();\n uint256 totalZUSD = totalZUSDDeposits; // cached to save an SLOAD\n if (totalZUSD == 0 || _debtToOffset == 0) {\n return;\n }\n\n _triggerSOVIssuance(communityIssuance);\n\n (\n uint256 ETHGainPerUnitStaked,\n uint256 ZUSDLossPerUnitStaked\n ) = _computeRewardsPerUnitStaked(_collToAdd, _debtToOffset, totalZUSD);\n\n _updateRewardSumAndProduct(ETHGainPerUnitStaked, ZUSDLossPerUnitStaked); // updates S and P\n\n _moveOffsetCollAndDebt(_collToAdd, _debtToOffset);\n }\n\n // --- Offset helper functions ---\n\n function _computeRewardsPerUnitStaked(\n uint256 _collToAdd,\n uint256 _debtToOffset,\n uint256 _totalZUSDDeposits\n ) internal returns (uint256 ETHGainPerUnitStaked, uint256 ZUSDLossPerUnitStaked) {\n /*\n * Compute the ZUSD and ETH rewards. Uses a \"feedback\" error correction, to keep\n * the cumulative error in the P and S state variables low:\n *\n * 1) Form numerators which compensate for the floor division errors that occurred the last time this\n * function was called.\n * 2) Calculate \"per-unit-staked\" ratios.\n * 3) Multiply each ratio back by its denominator, to reveal the current floor division error.\n * 4) Store these errors for use in the next correction when this function is called.\n * 5) Note: static analysis tools complain about this \"division before multiplication\", however, it is intended.\n */\n uint256 ETHNumerator = _collToAdd.mul(DECIMAL_PRECISION).add(lastETHError_Offset);\n\n assert(_debtToOffset <= _totalZUSDDeposits);\n if (_debtToOffset == _totalZUSDDeposits) {\n ZUSDLossPerUnitStaked = DECIMAL_PRECISION; // When the Pool depletes to 0, so does each deposit\n lastZUSDLossError_Offset = 0;\n } else {\n uint256 ZUSDLossNumerator = _debtToOffset.mul(DECIMAL_PRECISION).sub(\n lastZUSDLossError_Offset\n );\n /*\n * Add 1 to make error in quotient positive. We want \"slightly too much\" ZUSD loss,\n * which ensures the error in any given compoundedZUSDDeposit favors the Stability Pool.\n */\n ZUSDLossPerUnitStaked = (ZUSDLossNumerator.div(_totalZUSDDeposits)).add(1);\n lastZUSDLossError_Offset = (ZUSDLossPerUnitStaked.mul(_totalZUSDDeposits)).sub(\n ZUSDLossNumerator\n );\n }\n\n ETHGainPerUnitStaked = ETHNumerator.div(_totalZUSDDeposits);\n lastETHError_Offset = ETHNumerator.sub(ETHGainPerUnitStaked.mul(_totalZUSDDeposits));\n\n return (ETHGainPerUnitStaked, ZUSDLossPerUnitStaked);\n }\n\n /// Update the Stability Pool reward sum S and product P\n function _updateRewardSumAndProduct(\n uint256 _ETHGainPerUnitStaked,\n uint256 _ZUSDLossPerUnitStaked\n ) internal {\n uint256 currentP = P;\n uint256 newP;\n\n assert(_ZUSDLossPerUnitStaked <= DECIMAL_PRECISION);\n /*\n * The newProductFactor is the factor by which to change all deposits, due to the depletion of Stability Pool ZUSD in the liquidation.\n * We make the product factor 0 if there was a pool-emptying. Otherwise, it is (1 - ZUSDLossPerUnitStaked)\n */\n uint256 newProductFactor = uint256(DECIMAL_PRECISION).sub(_ZUSDLossPerUnitStaked);\n\n uint128 currentScaleCached = currentScale;\n uint128 currentEpochCached = currentEpoch;\n uint256 currentS = epochToScaleToSum[currentEpochCached][currentScaleCached];\n\n /*\n * Calculate the new S first, before we update P.\n * The ETH gain for any given depositor from a liquidation depends on the value of their deposit\n * (and the value of totalDeposits) prior to the Stability being depleted by the debt in the liquidation.\n *\n * Since S corresponds to ETH gain, and P to deposit loss, we update S first.\n */\n uint256 marginalETHGain = _ETHGainPerUnitStaked.mul(currentP);\n uint256 newS = currentS.add(marginalETHGain);\n epochToScaleToSum[currentEpochCached][currentScaleCached] = newS;\n emit S_Updated(newS, currentEpochCached, currentScaleCached);\n\n // If the Stability Pool was emptied, increment the epoch, and reset the scale and product P\n if (newProductFactor == 0) {\n currentEpoch = currentEpochCached.add(1);\n emit EpochUpdated(currentEpoch);\n currentScale = 0;\n emit ScaleUpdated(currentScale);\n newP = DECIMAL_PRECISION;\n\n // If multiplying P by a non-sov product factor would reduce P below the scale boundary, increment the scale\n } else if (currentP.mul(newProductFactor).div(DECIMAL_PRECISION) < SCALE_FACTOR) {\n newP = currentP.mul(newProductFactor).mul(SCALE_FACTOR).div(DECIMAL_PRECISION);\n currentScale = currentScaleCached.add(1);\n emit ScaleUpdated(currentScale);\n } else {\n newP = currentP.mul(newProductFactor).div(DECIMAL_PRECISION);\n }\n\n assert(newP > 0);\n P = newP;\n\n emit P_Updated(newP);\n }\n\n function _moveOffsetCollAndDebt(uint256 _collToAdd, uint256 _debtToOffset) internal {\n IActivePool activePoolCached = activePool;\n\n // Cancel the liquidated ZUSD debt with the ZUSD in the stability pool\n activePoolCached.decreaseZUSDDebt(_debtToOffset);\n _decreaseZUSD(_debtToOffset);\n\n // Burn the debt that was successfully offset\n zusdToken.burn(address(this), _debtToOffset);\n\n activePoolCached.sendETH(address(this), _collToAdd);\n }\n\n function _decreaseZUSD(uint256 _amount) internal {\n uint256 newTotalZUSDDeposits = totalZUSDDeposits.sub(_amount);\n totalZUSDDeposits = newTotalZUSDDeposits;\n emit StabilityPoolZUSDBalanceUpdated(newTotalZUSDDeposits);\n }\n\n // --- Reward calculator functions for depositor and front end ---\n\n /** Calculates the ETH gain earned by the deposit since its last snapshots were taken.\n * Given by the formula: E = d0 * (S - S(0))/P(0)\n * where S(0) and P(0) are the depositor's snapshots of the sum S and product P, respectively.\n * d0 is the last recorded deposit value.\n */\n function getDepositorETHGain(address _depositor) public view override returns (uint256) {\n uint256 initialDeposit = deposits[_depositor].initialValue;\n\n if (initialDeposit == 0) {\n return 0;\n }\n\n Snapshots memory snapshots = depositSnapshots[_depositor];\n\n uint256 ETHGain = _getETHGainFromSnapshots(initialDeposit, snapshots);\n return ETHGain;\n }\n\n function _getETHGainFromSnapshots(uint256 initialDeposit, Snapshots memory snapshots)\n internal\n view\n returns (uint256)\n {\n /*\n * Grab the sum 'S' from the epoch at which the stake was made. The ETH gain may span up to one scale change.\n * If it does, the second portion of the ETH gain is scaled by 1e9.\n * If the gain spans no scale change, the second portion will be 0.\n */\n uint128 epochSnapshot = snapshots.epoch;\n uint128 scaleSnapshot = snapshots.scale;\n uint256 S_Snapshot = snapshots.S;\n uint256 P_Snapshot = snapshots.P;\n\n uint256 firstPortion = epochToScaleToSum[epochSnapshot][scaleSnapshot].sub(S_Snapshot);\n uint256 secondPortion = epochToScaleToSum[epochSnapshot][scaleSnapshot.add(1)].div(\n SCALE_FACTOR\n );\n\n uint256 ETHGain = initialDeposit.mul(firstPortion.add(secondPortion)).div(P_Snapshot).div(\n DECIMAL_PRECISION\n );\n\n return ETHGain;\n }\n\n /**\n * Calculate the SOV gain earned by a deposit since its last snapshots were taken.\n * Given by the formula: SOV = d0 * (G - G(0))/P(0)\n * where G(0) and P(0) are the depositor's snapshots of the sum G and product P, respectively.\n * d0 is the last recorded deposit value.\n */\n function getDepositorSOVGain(address _depositor) public view override returns (uint256) {\n uint256 initialDeposit = deposits[_depositor].initialValue;\n if (initialDeposit == 0) {\n return 0;\n }\n\n address frontEndTag = deposits[_depositor].frontEndTag;\n\n /*\n * If not tagged with a front end, the depositor gets a 100% cut of what their deposit earned.\n * Otherwise, their cut of the deposit's earnings is equal to the kickbackRate, set by the front end through\n * which they made their deposit.\n */\n uint256 kickbackRate = frontEndTag == ADDRESS_ZERO\n ? DECIMAL_PRECISION\n : frontEnds[frontEndTag].kickbackRate;\n\n Snapshots memory snapshots = depositSnapshots[_depositor];\n\n uint256 SOVGain = kickbackRate\n .mul(_getSOVGainFromSnapshots(initialDeposit, snapshots))\n .div(DECIMAL_PRECISION);\n\n return SOVGain;\n }\n\n /**\n * Return the SOV gain earned by the front end. Given by the formula: E = D0 * (G - G(0))/P(0)\n * where G(0) and P(0) are the depositor's snapshots of the sum G and product P, respectively.\n *\n * D0 is the last recorded value of the front end's total tagged deposits.\n */\n function getFrontEndSOVGain(address _frontEnd) public view override returns (uint256) {\n uint256 frontEndStake = frontEndStakes[_frontEnd];\n if (frontEndStake == 0) {\n return 0;\n }\n\n uint256 kickbackRate = frontEnds[_frontEnd].kickbackRate;\n uint256 frontEndShare = uint256(DECIMAL_PRECISION).sub(kickbackRate);\n\n Snapshots memory snapshots = frontEndSnapshots[_frontEnd];\n\n uint256 SOVGain = frontEndShare\n .mul(_getSOVGainFromSnapshots(frontEndStake, snapshots))\n .div(DECIMAL_PRECISION);\n return SOVGain;\n }\n\n function _getSOVGainFromSnapshots(uint256 initialStake, Snapshots memory snapshots)\n internal\n view\n returns (uint256)\n {\n /*\n * Grab the sum 'G' from the epoch at which the stake was made. The SOV gain may span up to one scale change.\n * If it does, the second portion of the SOV gain is scaled by 1e9.\n * If the gain spans no scale change, the second portion will be 0.\n */\n uint128 epochSnapshot = snapshots.epoch;\n uint128 scaleSnapshot = snapshots.scale;\n uint256 G_Snapshot = snapshots.G;\n uint256 P_Snapshot = snapshots.P;\n\n uint256 firstPortion = epochToScaleToG[epochSnapshot][scaleSnapshot].sub(G_Snapshot);\n uint256 secondPortion = epochToScaleToG[epochSnapshot][scaleSnapshot.add(1)].div(\n SCALE_FACTOR\n );\n\n uint256 SOVGain = initialStake.mul(firstPortion.add(secondPortion)).div(P_Snapshot).div(\n DECIMAL_PRECISION\n );\n\n return SOVGain;\n }\n\n // --- Compounded deposit and compounded front end stake ---\n\n /**\n * Return the user's compounded deposit. Given by the formula: d = d0 * P/P(0)\n * where P(0) is the depositor's snapshot of the product P, taken when they last updated their deposit.\n */\n function getCompoundedZUSDDeposit(address _depositor) public view override returns (uint256) {\n uint256 initialDeposit = deposits[_depositor].initialValue;\n if (initialDeposit == 0) {\n return 0;\n }\n\n Snapshots memory snapshots = depositSnapshots[_depositor];\n\n uint256 compoundedDeposit = _getCompoundedStakeFromSnapshots(initialDeposit, snapshots);\n return compoundedDeposit;\n }\n\n /**\n * Return the front end's compounded stake. Given by the formula: D = D0 * P/P(0)\n * where P(0) is the depositor's snapshot of the product P, taken at the last time\n * when one of the front end's tagged deposits updated their deposit.\n *\n * The front end's compounded stake is equal to the sum of its depositors' compounded deposits.\n */\n function getCompoundedFrontEndStake(address _frontEnd) public view override returns (uint256) {\n uint256 frontEndStake = frontEndStakes[_frontEnd];\n if (frontEndStake == 0) {\n return 0;\n }\n\n Snapshots memory snapshots = frontEndSnapshots[_frontEnd];\n\n uint256 compoundedFrontEndStake = _getCompoundedStakeFromSnapshots(\n frontEndStake,\n snapshots\n );\n return compoundedFrontEndStake;\n }\n\n // Internal function, used to calculcate compounded deposits and compounded front end stakes.\n function _getCompoundedStakeFromSnapshots(uint256 initialStake, Snapshots memory snapshots)\n internal\n view\n returns (uint256)\n {\n uint256 snapshot_P = snapshots.P;\n uint128 scaleSnapshot = snapshots.scale;\n uint128 epochSnapshot = snapshots.epoch;\n\n // If stake was made before a pool-emptying event, then it has been fully cancelled with debt -- so, return 0\n if (epochSnapshot < currentEpoch) {\n return 0;\n }\n\n uint256 compoundedStake;\n uint128 scaleDiff = currentScale.sub(scaleSnapshot);\n\n /* Compute the compounded stake. If a scale change in P was made during the stake's lifetime,\n * account for it. If more than one scale change was made, then the stake has decreased by a factor of\n * at least 1e-9 -- so return 0.\n */\n if (scaleDiff == 0) {\n compoundedStake = initialStake.mul(P).div(snapshot_P);\n } else if (scaleDiff == 1) {\n compoundedStake = initialStake.mul(P).div(snapshot_P).div(SCALE_FACTOR);\n } else {\n // if scaleDiff >= 2\n compoundedStake = 0;\n }\n\n /*\n * If compounded deposit is less than a billionth of the initial deposit, return 0.\n *\n * NOTE: originally, this line was in place to stop rounding errors making the deposit too large. However, the error\n * corrections should ensure the error in P \"favors the Pool\", i.e. any given compounded deposit should slightly less\n * than it's theoretical value.\n *\n * Thus it's unclear whether this line is still really needed.\n */\n if (compoundedStake < initialStake.div(1e9)) {\n return 0;\n }\n\n return compoundedStake;\n }\n\n // --- Sender functions for ZUSD deposit, ETH gains and SOV gains ---\n\n /// Transfer the ZUSD tokens from the user to the Stability Pool's address, and update its recorded ZUSD\n function _sendZUSDtoStabilityPool(address _address, uint256 _amount) internal {\n zusdToken.sendToPool(_address, address(this), _amount);\n uint256 newTotalZUSDDeposits = totalZUSDDeposits.add(_amount);\n totalZUSDDeposits = newTotalZUSDDeposits;\n emit StabilityPoolZUSDBalanceUpdated(newTotalZUSDDeposits);\n }\n\n function _sendETHGainToDepositor(uint256 _amount) internal {\n _sendETHGainTo(_amount, msg.sender);\n }\n\n function _sendETHGainTo(uint256 _amount, address _receiver) internal {\n require(_receiver != address(0), \"SP::_sendETHGainTo: _receiver is zero address\");\n if (_amount == 0) {\n return;\n }\n uint256 newETH = ETH.sub(_amount);\n ETH = newETH;\n emit StabilityPoolETHBalanceUpdated(newETH);\n emit EtherSent(msg.sender, _amount);\n\n (bool success, ) = msg.sender.call{ value: _amount }(\"\");\n require(success, \"StabilityPool: sending ETH failed\");\n }\n\n /// Send ZUSD to user and decrease ZUSD in Pool\n function _sendZUSDToDepositor(address _depositor, uint256 ZUSDWithdrawal) internal {\n if (ZUSDWithdrawal == 0) {\n return;\n }\n\n zusdToken.returnFromPool(address(this), _depositor, ZUSDWithdrawal);\n _decreaseZUSD(ZUSDWithdrawal);\n }\n\n // --- External Front End functions ---\n\n /// Front end makes a one-time selection of kickback rate upon registering\n function registerFrontEnd(uint256 _kickbackRate) external override {\n _requireFrontEndNotRegistered(msg.sender);\n _requireUserHasNoDeposit(msg.sender);\n _requireValidKickbackRate(_kickbackRate);\n\n frontEnds[msg.sender].kickbackRate = _kickbackRate;\n frontEnds[msg.sender].registered = true;\n\n emit FrontEndRegistered(msg.sender, _kickbackRate);\n }\n\n // --- Stability Pool Deposit Functionality ---\n\n function _setFrontEndTag(address _depositor, address _frontEndTag) internal {\n deposits[_depositor].frontEndTag = _frontEndTag;\n emit FrontEndTagSet(_depositor, _frontEndTag);\n }\n\n function _updateDepositAndSnapshots(address _depositor, uint256 _newValue) internal {\n deposits[_depositor].initialValue = _newValue;\n\n if (_newValue == 0) {\n delete deposits[_depositor].frontEndTag;\n delete depositSnapshots[_depositor];\n emit DepositSnapshotUpdated(_depositor, 0, 0, 0);\n return;\n }\n uint128 currentScaleCached = currentScale;\n uint128 currentEpochCached = currentEpoch;\n uint256 currentP = P;\n\n // Get S and G for the current epoch and current scale\n uint256 currentS = epochToScaleToSum[currentEpochCached][currentScaleCached];\n uint256 currentG = epochToScaleToG[currentEpochCached][currentScaleCached];\n\n // Record new snapshots of the latest running product P, sum S, and sum G, for the depositor\n depositSnapshots[_depositor].P = currentP;\n depositSnapshots[_depositor].S = currentS;\n depositSnapshots[_depositor].G = currentG;\n depositSnapshots[_depositor].scale = currentScaleCached;\n depositSnapshots[_depositor].epoch = currentEpochCached;\n\n emit DepositSnapshotUpdated(_depositor, currentP, currentS, currentG);\n }\n\n function _updateFrontEndStakeAndSnapshots(address _frontEnd, uint256 _newValue) internal {\n frontEndStakes[_frontEnd] = _newValue;\n\n if (_newValue == 0) {\n delete frontEndSnapshots[_frontEnd];\n emit FrontEndSnapshotUpdated(_frontEnd, 0, 0);\n return;\n }\n\n uint128 currentScaleCached = currentScale;\n uint128 currentEpochCached = currentEpoch;\n uint256 currentP = P;\n\n // Get G for the current epoch and current scale\n uint256 currentG = epochToScaleToG[currentEpochCached][currentScaleCached];\n\n // Record new snapshots of the latest running product P and sum G for the front end\n frontEndSnapshots[_frontEnd].P = currentP;\n frontEndSnapshots[_frontEnd].G = currentG;\n frontEndSnapshots[_frontEnd].scale = currentScaleCached;\n frontEndSnapshots[_frontEnd].epoch = currentEpochCached;\n\n emit FrontEndSnapshotUpdated(_frontEnd, currentP, currentG);\n }\n\n function _payOutSOVGains(\n ICommunityIssuance _communityIssuance,\n address _depositor,\n address _frontEnd\n ) internal {\n // Pay out front end's SOV gain\n if (_frontEnd != ADDRESS_ZERO) {\n uint256 frontEndSOVGain = getFrontEndSOVGain(_frontEnd);\n _communityIssuance.sendSOV(_frontEnd, frontEndSOVGain);\n emit SOVPaidToFrontEnd(_frontEnd, frontEndSOVGain);\n }\n\n // Pay out depositor's SOV gain\n uint256 depositorSOVGain = getDepositorSOVGain(_depositor);\n _communityIssuance.sendSOV(_depositor, depositorSOVGain);\n emit SOVPaidToDepositor(_depositor, depositorSOVGain);\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == address(activePool), \"StabilityPool: Caller is not ActivePool\");\n }\n\n function _requireCallerIsTroveManager() internal view {\n require(msg.sender == address(troveManager), \"StabilityPool: Caller is not TroveManager\");\n }\n\n function _requireNoUnderCollateralizedTroves() internal {\n uint256 price = priceFeed.fetchPrice();\n address lowestTrove = sortedTroves.getLast();\n uint256 ICR = troveManager.getCurrentICR(lowestTrove, price);\n require(\n ICR >= liquityBaseParams.MCR(),\n \"StabilityPool: Cannot withdraw while there are troves with ICR < MCR\"\n );\n }\n\n function _requireUserHasDeposit(uint256 _initialDeposit) internal pure {\n require(_initialDeposit > 0, \"StabilityPool: User must have a non-zero deposit\");\n }\n\n function _requireUserHasNoDeposit(address _address) internal view {\n uint256 initialDeposit = deposits[_address].initialValue;\n require(initialDeposit == 0, \"StabilityPool: User must have no deposit\");\n }\n\n function _requireNonZeroAmount(uint256 _amount) internal pure {\n require(_amount > 0, \"StabilityPool: Amount must be non-zero\");\n }\n\n function _requireUserHasTrove(address _depositor) internal view {\n require(\n troveManager.getTroveStatus(_depositor) == 1,\n \"StabilityPool: caller must have an active trove to withdraw ETHGain to\"\n );\n }\n\n function _requireUserHasETHGain(address _depositor) internal view {\n uint256 ETHGain = getDepositorETHGain(_depositor);\n require(ETHGain > 0, \"StabilityPool: caller must have non-zero ETH Gain\");\n }\n\n function _requireFrontEndNotRegistered(address _address) internal view {\n require(\n !frontEnds[_address].registered,\n \"StabilityPool: must not already be a registered front end\"\n );\n }\n\n function _requireFrontEndIsRegisteredOrZero(address _address) internal view {\n require(\n frontEnds[_address].registered || _address == ADDRESS_ZERO,\n \"StabilityPool: Tag must be a registered front end, or the zero address\"\n );\n }\n\n function _requireValidKickbackRate(uint256 _kickbackRate) internal pure {\n require(\n _kickbackRate <= DECIMAL_PRECISION,\n \"StabilityPool: Kickback rate must be in range [0,1]\"\n );\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsActivePool();\n ETH = ETH.add(msg.value);\n StabilityPoolETHBalanceUpdated(ETH);\n }\n}\n" + }, + "contracts/StabilityPoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ICommunityIssuance.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/BaseMath.sol\";\n\ncontract StabilityPoolStorage is Ownable, BaseMath {\n string public constant NAME = \"StabilityPool\";\n\n IBorrowerOperations public borrowerOperations;\n\n ITroveManager public troveManager;\n\n IZUSDToken public zusdToken;\n\n // Needed to check if there are pending liquidations\n ISortedTroves public sortedTroves;\n\n ICommunityIssuance public communityIssuance;\n\n uint256 internal ETH; // deposited ether tracker\n\n // Tracker for ZUSD held in the pool. Changes when users deposit/withdraw, and when Trove debt is offset.\n uint256 internal totalZUSDDeposits;\n\n // --- Data structures ---\n\n struct FrontEnd {\n uint256 kickbackRate;\n bool registered;\n }\n\n struct Deposit {\n uint256 initialValue;\n address frontEndTag;\n }\n\n struct Snapshots {\n uint256 S;\n uint256 P;\n uint256 G;\n uint128 scale;\n uint128 epoch;\n }\n\n mapping(address => Deposit) public deposits; // depositor address -> Deposit struct\n mapping(address => Snapshots) public depositSnapshots; // depositor address -> snapshots struct\n\n mapping(address => FrontEnd) public frontEnds; // front end address -> FrontEnd struct\n mapping(address => uint256) public frontEndStakes; // front end address -> last recorded total deposits, tagged with that front end\n mapping(address => Snapshots) public frontEndSnapshots; // front end address -> snapshots struct\n\n /* Product 'P': Running product by which to multiply an initial deposit, in order to find the current compounded deposit,\n * after a series of liquidations have occurred, each of which cancel some ZUSD debt with the deposit.\n *\n * During its lifetime, a deposit's value evolves from d_t to d_t * P / P_t , where P_t\n * is the snapshot of P taken at the instant the deposit was made. 18-digit decimal.\n */\n uint256 public P;\n\n uint256 public constant SCALE_FACTOR = 1e9;\n\n // Each time the scale of P shifts by SCALE_FACTOR, the scale is incremented by 1\n uint128 public currentScale;\n\n // With each offset that fully empties the Pool, the epoch is incremented by 1\n uint128 public currentEpoch;\n\n /* ETH Gain sum 'S': During its lifetime, each deposit d_t earns an ETH gain of ( d_t * [S - S_t] )/P_t, where S_t\n * is the depositor's snapshot of S taken at the time t when the deposit was made.\n *\n * The 'S' sums are stored in a nested mapping (epoch => scale => sum):\n *\n * - The inner mapping records the sum S at different scales\n * - The outer mapping records the (scale => sum) mappings, for different epochs.\n */\n mapping(uint128 => mapping(uint128 => uint256)) public epochToScaleToSum;\n\n /*\n * Similarly, the sum 'G' is used to calculate SOV gains. During it's lifetime, each deposit d_t earns a SOV gain of\n * ( d_t * [G - G_t] )/P_t, where G_t is the depositor's snapshot of G taken at time t when the deposit was made.\n *\n * SOV reward events occur are triggered by depositor operations (new deposit, topup, withdrawal), and liquidations.\n * In each case, the SOV reward is issued (i.e. G is updated), before other state changes are made.\n */\n mapping(uint128 => mapping(uint128 => uint256)) public epochToScaleToG;\n\n // Error tracker for the error correction in the SOV issuance calculation\n uint256 public lastSOVError;\n // Error trackers for the error correction in the offset calculation\n uint256 public lastETHError_Offset;\n uint256 public lastZUSDLossError_Offset;\n}\n" + }, + "contracts/TestContracts/ActivePoolTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ActivePool.sol\";\n\ncontract ActivePoolTester is ActivePool {\n \n function unprotectedIncreaseZUSDDebt(uint _amount) external {\n ZUSDDebt = ZUSDDebt.add(_amount);\n }\n\n function unprotectedPayable() external payable {\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/TestContracts/BorrowerOperationsTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../BorrowerOperations.sol\";\n\n/* Tester contract inherits from BorrowerOperations, and provides external functions \nfor testing the parent's internal functions. */\ncontract BorrowerOperationsTester is BorrowerOperations {\n\n function getNewICRFromTroveChange\n (\n uint _coll, \n uint _debt, \n uint _collChange, \n bool isCollIncrease, \n uint _debtChange, \n bool isDebtIncrease, \n uint _price\n ) \n external\n pure\n returns (uint)\n {\n return _getNewICRFromTroveChange(_coll, _debt, _collChange, isCollIncrease, _debtChange, isDebtIncrease, _price);\n }\n\n function getNewTCRFromTroveChange\n (\n uint _collChange, \n bool isCollIncrease, \n uint _debtChange, \n bool isDebtIncrease, \n uint _price\n ) \n external \n view\n returns (uint) \n {\n return _getNewTCRFromTroveChange(_collChange, isCollIncrease, _debtChange, isDebtIncrease, _price);\n }\n\n function getUSDValue(uint _coll, uint _price) external pure returns (uint) {\n return _getUSDValue(_coll, _price);\n }\n\n function callInternalAdjustLoan\n (\n address _borrower, \n uint _collWithdrawal, \n uint _debtChange, \n bool _isDebtIncrease, \n address _upperHint,\n address _lowerHint)\n external \n {\n _adjustTrove(_borrower, _collWithdrawal, _debtChange, _isDebtIncrease, _upperHint, _lowerHint, 0);\n }\n\n\n // Payable fallback function\n receive() external payable { }\n}\n" + }, + "contracts/TestContracts/CommunityIssuanceTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/CommunityIssuance.sol\";\n\ncontract CommunityIssuanceTester is CommunityIssuance {\n function obtainSOV(uint _amount) external {\n sovToken.transfer(msg.sender, _amount);\n }\n\n function unprotectedIssueSOV(uint256 _totalZUSDDeposits) external returns (uint) {\n // No checks on caller address\n \n uint256 timePassedSinceLastIssuance = (block.timestamp.sub(lastIssuanceTime));\n uint256 latestTotalSOVIssued = _ZUSDToSOV(_totalZUSDDeposits.mul(APR).div(MAX_BPS).mul(timePassedSinceLastIssuance).div(365 days));\n \n uint256 issuance = latestTotalSOVIssued.sub(totalSOVIssued);\n\n totalSOVIssued = latestTotalSOVIssued;\n lastIssuanceTime = block.timestamp;\n emit TotalSOVIssuedUpdated(latestTotalSOVIssued);\n\n return issuance;\n }\n}\n" + }, + "contracts/TestContracts/DefaultPoolTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../DefaultPool.sol\";\n\ncontract DefaultPoolTester is DefaultPool {\n \n function unprotectedIncreaseZUSDDebt(uint _amount) external {\n ZUSDDebt = ZUSDDebt.add(_amount);\n }\n\n function unprotectedPayable() external payable {\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/TestContracts/EchidnaProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../TroveManager.sol\";\nimport \"../BorrowerOperations.sol\";\nimport \"../StabilityPool.sol\";\nimport \"../ZUSDToken.sol\";\n\ncontract EchidnaProxy {\n TroveManager troveManager;\n BorrowerOperations borrowerOperations;\n StabilityPool stabilityPool;\n ZUSDToken zusdToken;\n\n constructor(\n TroveManager _troveManager,\n BorrowerOperations _borrowerOperations,\n StabilityPool _stabilityPool,\n ZUSDToken _zusdToken\n ) public {\n troveManager = _troveManager;\n borrowerOperations = _borrowerOperations;\n stabilityPool = _stabilityPool;\n zusdToken = _zusdToken;\n }\n\n receive() external payable {\n // do nothing\n }\n\n // TroveManager\n\n function liquidatePrx(address _user) external {\n troveManager.liquidate(_user);\n }\n\n function liquidateTrovesPrx(uint _n) external {\n troveManager.liquidateTroves(_n);\n }\n\n function batchLiquidateTrovesPrx(address[] calldata _troveArray) external {\n troveManager.batchLiquidateTroves(_troveArray);\n }\n\n function redeemCollateralPrx(\n uint _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint _partialRedemptionHintNICR,\n uint _maxIterations,\n uint _maxFee\n ) external {\n troveManager.redeemCollateral(_ZUSDAmount, _firstRedemptionHint, _upperPartialRedemptionHint, _lowerPartialRedemptionHint, _partialRedemptionHintNICR, _maxIterations, _maxFee);\n }\n\n // Borrower Operations\n function openTrovePrx(uint _ETH, uint _ZUSDAmount, address _upperHint, address _lowerHint, uint _maxFee) external payable {\n borrowerOperations.openTrove{value: _ETH}(_maxFee, _ZUSDAmount, _upperHint, _lowerHint);\n }\n\n function addCollPrx(uint _ETH, address _upperHint, address _lowerHint) external payable {\n borrowerOperations.addColl{value: _ETH}(_upperHint, _lowerHint);\n }\n\n function withdrawCollPrx(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.withdrawColl(_amount, _upperHint, _lowerHint);\n }\n\n function withdrawZUSDPrx(uint _amount, address _upperHint, address _lowerHint, uint _maxFee) external {\n borrowerOperations.withdrawZUSD(_maxFee, _amount, _upperHint, _lowerHint);\n }\n\n function repayZUSDPrx(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.repayZUSD(_amount, _upperHint, _lowerHint);\n }\n\n function closeTrovePrx() external {\n borrowerOperations.closeTrove();\n }\n\n function adjustTrovePrx(uint _ETH, uint _collWithdrawal, uint _debtChange, bool _isDebtIncrease, address _upperHint, address _lowerHint, uint _maxFee) external payable {\n borrowerOperations.adjustTrove{value: _ETH}(_maxFee, _collWithdrawal, _debtChange, _isDebtIncrease, _upperHint, _lowerHint);\n }\n\n // Pool Manager\n function provideToSPPrx(uint _amount, address _frontEndTag) external {\n stabilityPool.provideToSP(_amount, _frontEndTag);\n }\n\n function withdrawFromSPPrx(uint _amount) external {\n stabilityPool.withdrawFromSP(_amount);\n }\n\n // ZUSD Token\n\n function transferPrx(address recipient, uint256 amount) external returns (bool) {\n return zusdToken.transfer(recipient, amount);\n }\n\n function approvePrx(address spender, uint256 amount) external returns (bool) {\n return zusdToken.approve(spender, amount);\n }\n\n function transferFromPrx(address sender, address recipient, uint256 amount) external returns (bool) {\n return zusdToken.transferFrom(sender, recipient, amount);\n }\n\n function increaseAllowancePrx(address spender, uint256 addedValue) external returns (bool) {\n return zusdToken.increaseAllowance(spender, addedValue);\n }\n\n function decreaseAllowancePrx(address spender, uint256 subtractedValue) external returns (bool) {\n return zusdToken.decreaseAllowance(spender, subtractedValue);\n }\n}\n" + }, + "contracts/TestContracts/EchidnaTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../LiquityBaseParams.sol\";\nimport \"../Interfaces/ITroveManager.sol\";\nimport \"../TroveManager.sol\";\nimport \"../TroveManagerStorage.sol\";\nimport \"../Dependencies/TroveManagerRedeemOps.sol\";\nimport \"../BorrowerOperations.sol\";\nimport \"../ActivePool.sol\";\nimport \"../DefaultPool.sol\";\nimport \"../StabilityPool.sol\";\nimport \"../GasPool.sol\";\nimport \"../CollSurplusPool.sol\";\nimport \"../ZUSDToken.sol\";\nimport \"./PriceFeedTestnet.sol\";\nimport \"../SortedTroves.sol\";\nimport \"./EchidnaProxy.sol\";\n\n//import \"../Dependencies/console.sol\";\n\n// Run with:\n// rm -f fuzzTests/corpus/* # (optional)\n// ~/.local/bin/echidna-test contracts/TestContracts/EchidnaTester.sol --contract EchidnaTester --config fuzzTests/echidna_config.yaml\n\ncontract EchidnaTester {\n using SafeMath for uint;\n\n uint private constant NUMBER_OF_ACTORS = 100;\n uint private constant INITIAL_BALANCE = 1e24;\n uint private MCR;\n uint private CCR;\n uint private ZUSD_GAS_COMPENSATION;\n\n LiquityBaseParams public liquityBaseParams;\n TroveManagerRedeemOps public troveManagerRedeemOps;\n TroveManager public troveManager;\n BorrowerOperations public borrowerOperations;\n ActivePool public activePool;\n DefaultPool public defaultPool;\n StabilityPool public stabilityPool;\n GasPool public gasPool;\n CollSurplusPool public collSurplusPool;\n ZUSDToken public zusdToken;\n PriceFeedTestnet priceFeedTestnet;\n SortedTroves sortedTroves;\n\n EchidnaProxy[NUMBER_OF_ACTORS] public echidnaProxies;\n\n uint private numberOfTroves;\n\n constructor() public payable {\n liquityBaseParams = new LiquityBaseParams();\n troveManagerRedeemOps = new TroveManagerRedeemOps(14 * 86400);\n troveManager = new TroveManager(14 days);\n borrowerOperations = new BorrowerOperations();\n activePool = new ActivePool();\n defaultPool = new DefaultPool();\n stabilityPool = new StabilityPool();\n gasPool = new GasPool();\n zusdToken = new ZUSDToken();\n zusdToken.initialize(\n address(troveManager),\n address(stabilityPool),\n address(borrowerOperations)\n );\n\n collSurplusPool = new CollSurplusPool();\n priceFeedTestnet = new PriceFeedTestnet();\n\n sortedTroves = new SortedTroves();\n\n troveManager.setAddresses(\n ITroveManager.TroveManagerInitAddressesParams(\n address(0),\n address(troveManagerRedeemOps),\n address(liquityBaseParams),\n address(borrowerOperations),\n address(activePool),\n address(defaultPool),\n address(stabilityPool),\n address(gasPool),\n address(collSurplusPool),\n address(priceFeedTestnet),\n address(zusdToken),\n address(sortedTroves),\n address(0),\n address(0)\n )\n );\n\n borrowerOperations.setAddresses(\n address(0),\n address(liquityBaseParams),\n address(troveManager),\n address(activePool),\n address(defaultPool),\n address(stabilityPool),\n address(gasPool),\n address(collSurplusPool),\n address(priceFeedTestnet),\n address(sortedTroves),\n address(zusdToken),\n address(0)\n );\n\n activePool.setAddresses(\n address(borrowerOperations),\n address(troveManager),\n address(stabilityPool),\n address(defaultPool)\n );\n\n defaultPool.setAddresses(address(troveManager), address(activePool));\n\n stabilityPool.setAddresses(\n address(liquityBaseParams),\n address(borrowerOperations),\n address(troveManager),\n address(activePool),\n address(zusdToken),\n address(sortedTroves),\n address(priceFeedTestnet),\n address(0)\n );\n\n collSurplusPool.setAddresses(\n address(borrowerOperations),\n address(troveManager),\n address(activePool)\n );\n\n sortedTroves.setParams(1e18, address(troveManager), address(borrowerOperations));\n\n for (uint i = 0; i < NUMBER_OF_ACTORS; i++) {\n echidnaProxies[i] = new EchidnaProxy(\n troveManager,\n borrowerOperations,\n stabilityPool,\n zusdToken\n );\n (bool success, ) = address(echidnaProxies[i]).call{ value: INITIAL_BALANCE }(\"\");\n require(success);\n }\n\n MCR = borrowerOperations.liquityBaseParams().MCR();\n CCR = borrowerOperations.liquityBaseParams().CCR();\n ZUSD_GAS_COMPENSATION = borrowerOperations.ZUSD_GAS_COMPENSATION();\n require(MCR > 0);\n require(CCR > 0);\n\n // TODO:\n priceFeedTestnet.setPrice(1e22);\n }\n\n // TroveManager\n\n function liquidateExt(uint _i, address _user) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].liquidatePrx(_user);\n }\n\n function liquidateTrovesExt(uint _i, uint _n) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].liquidateTrovesPrx(_n);\n }\n\n function batchLiquidateTrovesExt(uint _i, address[] calldata _troveArray) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].batchLiquidateTrovesPrx(_troveArray);\n }\n\n function redeemCollateralExt(\n uint _i,\n uint _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint _partialRedemptionHintNICR\n ) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].redeemCollateralPrx(\n _ZUSDAmount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n 0,\n 0\n );\n }\n\n // Borrower Operations\n\n function getAdjustedETH(\n uint actorBalance,\n uint _ETH,\n uint ratio\n ) internal view returns (uint) {\n uint price = priceFeedTestnet.getPrice();\n require(price > 0);\n uint minETH = ratio.mul(ZUSD_GAS_COMPENSATION).div(price);\n require(actorBalance > minETH);\n uint ETH = minETH + (_ETH % (actorBalance - minETH));\n return ETH;\n }\n\n function getAdjustedZUSD(uint ETH, uint _ZUSDAmount, uint ratio) internal view returns (uint) {\n uint price = priceFeedTestnet.getPrice();\n uint ZUSDAmount = _ZUSDAmount;\n uint compositeDebt = ZUSDAmount.add(ZUSD_GAS_COMPENSATION);\n uint ICR = LiquityMath._computeCR(ETH, compositeDebt, price);\n if (ICR < ratio) {\n compositeDebt = ETH.mul(price).div(ratio);\n ZUSDAmount = compositeDebt.sub(ZUSD_GAS_COMPENSATION);\n }\n return ZUSDAmount;\n }\n\n function openTroveExt(uint _i, uint _ETH, uint _ZUSDAmount) public payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n EchidnaProxy echidnaProxy = echidnaProxies[actor];\n uint actorBalance = address(echidnaProxy).balance;\n\n // we pass in CCR instead of MCR in case it’s the first one\n uint ETH = getAdjustedETH(actorBalance, _ETH, CCR);\n uint ZUSDAmount = getAdjustedZUSD(ETH, _ZUSDAmount, CCR);\n\n echidnaProxy.openTrovePrx(ETH, ZUSDAmount, address(0), address(0), 0);\n\n numberOfTroves = troveManager.getTroveOwnersCount();\n assert(numberOfTroves > 0);\n // canary\n //assert(numberOfTroves == 0);\n }\n\n function openTroveRawExt(\n uint _i,\n uint _ETH,\n uint _ZUSDAmount,\n address _upperHint,\n address _lowerHint,\n uint _maxFee\n ) public payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].openTrovePrx(_ETH, _ZUSDAmount, _upperHint, _lowerHint, _maxFee);\n }\n\n function addCollExt(uint _i, uint _ETH) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n EchidnaProxy echidnaProxy = echidnaProxies[actor];\n uint actorBalance = address(echidnaProxy).balance;\n\n uint ETH = getAdjustedETH(actorBalance, _ETH, MCR);\n\n echidnaProxy.addCollPrx(ETH, address(0), address(0));\n }\n\n function addCollRawExt(\n uint _i,\n uint _ETH,\n address _upperHint,\n address _lowerHint\n ) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].addCollPrx(_ETH, _upperHint, _lowerHint);\n }\n\n function withdrawCollExt(\n uint _i,\n uint _amount,\n address _upperHint,\n address _lowerHint\n ) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].withdrawCollPrx(_amount, _upperHint, _lowerHint);\n }\n\n function withdrawZUSDExt(\n uint _i,\n uint _amount,\n address _upperHint,\n address _lowerHint,\n uint _maxFee\n ) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].withdrawZUSDPrx(_amount, _upperHint, _lowerHint, _maxFee);\n }\n\n function repayZUSDExt(uint _i, uint _amount, address _upperHint, address _lowerHint) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].repayZUSDPrx(_amount, _upperHint, _lowerHint);\n }\n\n function closeTroveExt(uint _i) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].closeTrovePrx();\n }\n\n function adjustTroveExt(\n uint _i,\n uint _ETH,\n uint _collWithdrawal,\n uint _debtChange,\n bool _isDebtIncrease\n ) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n EchidnaProxy echidnaProxy = echidnaProxies[actor];\n uint actorBalance = address(echidnaProxy).balance;\n\n uint ETH = getAdjustedETH(actorBalance, _ETH, MCR);\n uint debtChange = _debtChange;\n if (_isDebtIncrease) {\n // TODO: add current amount already withdrawn:\n debtChange = getAdjustedZUSD(ETH, uint(_debtChange), MCR);\n }\n // TODO: collWithdrawal, debtChange\n echidnaProxy.adjustTrovePrx(\n ETH,\n _collWithdrawal,\n debtChange,\n _isDebtIncrease,\n address(0),\n address(0),\n 0\n );\n }\n\n function adjustTroveRawExt(\n uint _i,\n uint _ETH,\n uint _collWithdrawal,\n uint _debtChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n uint _maxFee\n ) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].adjustTrovePrx(\n _ETH,\n _collWithdrawal,\n _debtChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFee\n );\n }\n\n // Pool Manager\n\n function provideToSPExt(uint _i, uint _amount, address _frontEndTag) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].provideToSPPrx(_amount, _frontEndTag);\n }\n\n function withdrawFromSPExt(uint _i, uint _amount) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].withdrawFromSPPrx(_amount);\n }\n\n // ZUSD Token\n\n function transferExt(uint _i, address recipient, uint256 amount) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].transferPrx(recipient, amount);\n }\n\n function approveExt(uint _i, address spender, uint256 amount) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].approvePrx(spender, amount);\n }\n\n function transferFromExt(\n uint _i,\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].transferFromPrx(sender, recipient, amount);\n }\n\n function increaseAllowanceExt(\n uint _i,\n address spender,\n uint256 addedValue\n ) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].increaseAllowancePrx(spender, addedValue);\n }\n\n function decreaseAllowanceExt(\n uint _i,\n address spender,\n uint256 subtractedValue\n ) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].decreaseAllowancePrx(spender, subtractedValue);\n }\n\n // PriceFeed\n\n function setPriceExt(uint256 _price) external {\n bool result = priceFeedTestnet.setPrice(_price);\n assert(result);\n }\n\n // --------------------------\n // Invariants and properties\n // --------------------------\n\n function echidna_canary_number_of_troves() public view returns (bool) {\n if (numberOfTroves > 20) {\n return false;\n }\n\n return true;\n }\n\n function echidna_canary_active_pool_balance() public view returns (bool) {\n if (address(activePool).balance > 0) {\n return false;\n }\n return true;\n }\n\n function echidna_troves_order() external view returns (bool) {\n address currentTrove = sortedTroves.getFirst();\n address nextTrove = sortedTroves.getNext(currentTrove);\n\n while (currentTrove != address(0) && nextTrove != address(0)) {\n if (troveManager.getNominalICR(nextTrove) > troveManager.getNominalICR(currentTrove)) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n currentTrove = nextTrove;\n nextTrove = sortedTroves.getNext(currentTrove);\n }\n\n return true;\n }\n\n /**\n * Status\n * Minimum debt (gas compensation)\n * Stake > 0\n */\n function echidna_trove_properties() public view returns (bool) {\n address currentTrove = sortedTroves.getFirst();\n while (currentTrove != address(0)) {\n // Status\n if (\n TroveManagerStorage.Status(troveManager.getTroveStatus(currentTrove)) !=\n TroveManagerStorage.Status.active\n ) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n // Minimum debt (gas compensation)\n if (troveManager.getTroveDebt(currentTrove) < ZUSD_GAS_COMPENSATION) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n // Stake > 0\n if (troveManager.getTroveStake(currentTrove) == 0) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n currentTrove = sortedTroves.getNext(currentTrove);\n }\n return true;\n }\n\n function echidna_ETH_balances() public view returns (bool) {\n if (address(troveManager).balance > 0) {\n return false;\n }\n\n if (address(borrowerOperations).balance > 0) {\n return false;\n }\n\n if (address(activePool).balance != activePool.getETH()) {\n return false;\n }\n\n if (address(defaultPool).balance != defaultPool.getETH()) {\n return false;\n }\n\n if (address(stabilityPool).balance != stabilityPool.getETH()) {\n return false;\n }\n\n if (address(zusdToken).balance > 0) {\n return false;\n }\n\n if (address(priceFeedTestnet).balance > 0) {\n return false;\n }\n\n if (address(sortedTroves).balance > 0) {\n return false;\n }\n\n return true;\n }\n\n // TODO: What should we do with this? Should it be allowed? Should it be a canary?\n function echidna_price() public view returns (bool) {\n uint price = priceFeedTestnet.getPrice();\n\n if (price == 0) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n return true;\n }\n\n // Total ZUSD matches\n function echidna_ZUSD_global_balances() public view returns (bool) {\n uint totalSupply = zusdToken.totalSupply();\n uint gasPoolBalance = zusdToken.balanceOf(address(gasPool));\n\n uint activePoolBalance = activePool.getZUSDDebt();\n uint defaultPoolBalance = defaultPool.getZUSDDebt();\n if (totalSupply != activePoolBalance + defaultPoolBalance) {\n return false;\n }\n\n uint stabilityPoolBalance = stabilityPool.getTotalZUSDDeposits();\n address currentTrove = sortedTroves.getFirst();\n uint trovesBalance;\n while (currentTrove != address(0)) {\n trovesBalance += zusdToken.balanceOf(address(currentTrove));\n currentTrove = sortedTroves.getNext(currentTrove);\n }\n // we cannot state equality because tranfers are made to external addresses too\n if (totalSupply <= stabilityPoolBalance + trovesBalance + gasPoolBalance) {\n return false;\n }\n\n return true;\n }\n\n /*\n function echidna_test() public view returns(bool) {\n return true;\n }\n */\n}\n" + }, + "contracts/TestContracts/ExternalPriceFeedTester.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Dependencies/PriceFeed/IExternalPriceFeed.sol\";\n\ninterface IMoCBaseOracle {\n function peek() external view returns (bytes32, bool);\n}\n\ncontract ExternalPriceFeedTester is IExternalPriceFeed {\n uint256 price;\n bool success;\n\n function setLatestAnswer(uint256 _price, bool _success) external {\n price = _price;\n success = _success;\n }\n\n function latestAnswer() external view override returns (uint256, bool) {\n return (price, success);\n }\n}\n" + }, + "contracts/TestContracts/FunctionCaller.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/ITroveManager.sol\";\nimport \"../Interfaces/ISortedTroves.sol\";\nimport \"../Interfaces/IPriceFeed.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\n\n/* Wrapper contract - used for calculating gas of read-only and internal functions. \nNot part of the Zero application. */\ncontract FunctionCaller {\n ITroveManager troveManager;\n address public troveManagerAddress;\n\n ISortedTroves sortedTroves;\n address public sortedTrovesAddress;\n\n IPriceFeed priceFeed;\n address public priceFeedAddress;\n\n // --- Dependency setters ---\n\n function setTroveManagerAddress(address _troveManagerAddress) external {\n troveManagerAddress = _troveManagerAddress;\n troveManager = ITroveManager(_troveManagerAddress);\n }\n\n function setSortedTrovesAddress(address _sortedTrovesAddress) external {\n troveManagerAddress = _sortedTrovesAddress;\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n }\n\n function setPriceFeedAddress(address _priceFeedAddress) external {\n priceFeedAddress = _priceFeedAddress;\n priceFeed = IPriceFeed(_priceFeedAddress);\n }\n\n // --- Non-view wrapper functions used for calculating gas ---\n\n function troveManager_getCurrentICR(address _address, uint256 _price)\n external\n returns (uint256)\n {\n return troveManager.getCurrentICR(_address, _price);\n }\n\n function sortedTroves_findInsertPosition(\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external returns (address, address) {\n return sortedTroves.findInsertPosition(_NICR, _prevId, _nextId);\n }\n}\n" + }, + "contracts/TestContracts/LiquityMathTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/LiquityMath.sol\";\n\n/* Tester contract for math functions in Math.sol library. */\n\ncontract LiquityMathTester {\n\n function callMax(uint _a, uint _b) external pure returns (uint) {\n return LiquityMath._max(_a, _b);\n }\n\n // Non-view wrapper for gas test\n function callDecPowTx(uint _base, uint _n) external returns (uint) {\n return LiquityMath._decPow(_base, _n);\n }\n\n // External wrapper\n function callDecPow(uint _base, uint _n) external pure returns (uint) {\n return LiquityMath._decPow(_base, _n);\n }\n}\n" + }, + "contracts/TestContracts/LiquitySafeMath128Tester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/LiquitySafeMath128.sol\";\n\n/* Tester contract for math functions in LiquitySafeMath128.sol library. */\n\ncontract LiquitySafeMath128Tester {\n using LiquitySafeMath128 for uint128;\n\n function add(uint128 a, uint128 b) external pure returns (uint128) {\n return a.add(b);\n }\n\n function sub(uint128 a, uint128 b) external pure returns (uint128) {\n return a.sub(b);\n }\n}\n" + }, + "contracts/TestContracts/MassetManagerTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { ERC20Permit } from \"@openzeppelin/contracts/drafts/ERC20Permit.sol\";\nimport \"../BorrowerOperationsStorage.sol\";\nimport \"hardhat/console.sol\";\n\n//TODO: rename NueMockToken to contract DLLRMockToken is ERC20(\"Sovryn Dollar\", \"DLLR\")\ncontract NueMockToken is ERC20(\"Nuestro\", \"NUE\"), ERC20Permit(\"Nuestro\"), Ownable {\n constructor() public {}\n\n function mint(address _account, uint256 _amount) public onlyOwner {\n _mint(_account, _amount);\n }\n\n function burn(address _account, uint256 _amount) public onlyOwner {\n _burn(_account, _amount);\n }\n\n function getChainId() external pure returns (uint256 chainID) {\n //return _chainID(); // it’s private\n assembly {\n chainID := chainid()\n }\n }\n\n function transferWithPermit(\n address _from,\n address _to,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external {\n permit(_from, msg.sender, _amount, _deadline, _v, _r, _s);\n transferFrom(_from, _to, _amount);\n }\n\n //TODO: add EIP-2612 Permit functionality\n}\n\ncontract MassetManagerTester is IMassetManager {\n NueMockToken public nueMockToken;\n\n constructor() public {\n nueMockToken = new NueMockToken();\n }\n\n function mintTo(\n address _bAsset,\n uint256 _bAssetQuantity,\n address _recipient\n ) external override returns (uint256) {\n IERC20(_bAsset).transferFrom(msg.sender, address(this), _bAssetQuantity);\n uint256 nueBalanceOfRecipientBeforeMint = nueMockToken.balanceOf(_recipient);\n nueMockToken.mint(_recipient, _bAssetQuantity);\n return nueMockToken.balanceOf(_recipient) - nueBalanceOfRecipientBeforeMint;\n }\n\n function getToken() external view override returns (address) {\n return address(nueMockToken);\n }\n\n /// @dev Transfer 'bAsset' to the recipient then burn the 'aggregator' nueMockToken\n function redeemTo(\n address _bAsset, //ZUSD nueMockToken\n uint256 _massetQuantity,\n address _recipient //user\n ) external override returns (uint256 massetRedeemed) {\n ERC20(_bAsset).transfer(_recipient, _massetQuantity);\n // nueMockToken.burn(_recipient, _massetQuantity); // _recipient used to be for the previous bridge-like implementation\n nueMockToken.burn(msg.sender, _massetQuantity);\n\n return _massetQuantity;\n }\n}\n" + }, + "contracts/TestContracts/MockFeeSharingCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/ZEROToken.sol\";\n\ninterface MockIFeeSharingCollector {\n\tfunction transferTokens(address _token, uint96 _amount) external;\n}\n\n/// @dev Simple contract that will receive ZERO tokens issued to the SOV stakers.\ncontract MockFeeSharingCollector is MockIFeeSharingCollector {\n\tfunction transferTokens(address _token, uint96 _amount) override external {\n\t\t/// Just a fake function to receive the tokens\n\t\tZEROToken(_token).transferFrom(msg.sender, address(this), _amount);\n\t}\n\n\tfunction transferRBTC() external payable {}\n}\n" + }, + "contracts/TestContracts/PriceFeedSovryn.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IPriceFeedSovryn.sol\";\nimport \"../Dependencies/SafeMath.sol\";\n\n/*\n* PriceFeed placeholder for testnet and development. The price is simply set manually and saved in a state \n* variable. The contract does not connect to a live Chainlink price feed. \n*/\ncontract PriceFeedSovryn {\n using SafeMath for uint256;\n\n mapping(address => mapping(address => uint256)) public prices;\n\n // --- Functions ---\n // Manual external price setter.\n function setPrice(address sourceToken, address destToken, uint256 price) external {\n prices[sourceToken][destToken] = price;\n }\n\n function queryRate(address sourceToken, address destToken) public view returns(uint256 rate, uint256 precision) {\n return (prices[sourceToken][destToken], 1e18);\n }\n\n function queryReturn(\n address sourceToken,\n address destToken,\n uint256 sourceAmount\n ) public view returns (uint256 destAmount) {\n (uint256 rate, uint256 precision) = queryRate(sourceToken, destToken);\n return sourceAmount.mul(rate).div(precision);\n }\n}\n" + }, + "contracts/TestContracts/PriceFeedTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../PriceFeed.sol\";\n\ncontract PriceFeedTester is PriceFeed {\n function setLastGoodPrice(uint256 _lastGoodPrice) external {\n lastGoodPrice = _lastGoodPrice;\n }\n}\n" + }, + "contracts/TestContracts/PriceFeedTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IPriceFeed.sol\";\n\n/*\n* PriceFeed placeholder for testnet and development. The price is simply set manually and saved in a state \n* variable. The contract does not connect to a live Chainlink price feed. \n*/\ncontract PriceFeedTestnet is IPriceFeed {\n \n uint256 private _price = 200 * 1e18;\n\n // --- Functions ---\n\n // View price getter for simplicity in tests\n function getPrice() external view returns (uint256) {\n return _price;\n }\n\n function fetchPrice() external override returns (uint256) {\n // Fire an event just like the mainnet version would.\n // This lets the subgraph rely on events to get the latest price even when developing locally.\n emit LastGoodPriceUpdated(_price);\n return _price;\n }\n\n // Manual external price setter.\n function setPrice(uint256 price) external returns (bool) {\n _price = price;\n return true;\n }\n}\n" + }, + "contracts/TestContracts/SortedTrovesTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/ISortedTroves.sol\";\n\n\ncontract SortedTrovesTester {\n ISortedTroves sortedTroves;\n\n function setSortedTroves(address _sortedTrovesAddress) external {\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n }\n\n function insert(address _id, uint256 _NICR, address _prevId, address _nextId) external {\n sortedTroves.insert(_id, _NICR, _prevId, _nextId);\n }\n\n function remove(address _id) external {\n sortedTroves.remove(_id);\n }\n\n function reInsert(address _id, uint256 _newNICR, address _prevId, address _nextId) external {\n sortedTroves.reInsert(_id, _newNICR, _prevId, _nextId);\n }\n\n function getNominalICR(address) external pure returns (uint) {\n return 1;\n }\n\n function getCurrentICR(address, uint) external pure returns (uint) {\n return 1;\n }\n}\n" + }, + "contracts/TestContracts/StabilityPoolTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../StabilityPool.sol\";\n\ncontract StabilityPoolTester is StabilityPool {\n \n function unprotectedPayable() external payable {\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/TestContracts/TroveManagerTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../TroveManager.sol\";\n\n/* Tester contract inherits from TroveManager, and provides external functions \nfor testing the parent's internal functions. */\n\ncontract TroveManagerTester is TroveManager(14 days) {\n function computeICR(uint _coll, uint _debt, uint _price) external pure returns (uint) {\n return LiquityMath._computeCR(_coll, _debt, _price);\n }\n\n function getCollGasCompensation(uint _coll) external view returns (uint) {\n return _getCollGasCompensation(_coll);\n }\n\n function getZUSDGasCompensation() external pure returns (uint) {\n return ZUSD_GAS_COMPENSATION;\n }\n\n function getCompositeDebt(uint _debt) external pure returns (uint) {\n return _getCompositeDebt(_debt);\n }\n\n function unprotectedDecayBaseRateFromBorrowing() external returns (uint) {\n baseRate = _calcDecayedBaseRate();\n assert(baseRate >= 0 && baseRate <= DECIMAL_PRECISION);\n\n _updateLastFeeOpTime();\n return baseRate;\n }\n\n function minutesPassedSinceLastFeeOp() external view returns (uint) {\n return _minutesPassedSinceLastFeeOp();\n }\n\n function setLastFeeOpTimeToNow() external {\n lastFeeOperationTime = block.timestamp;\n }\n\n function setBaseRate(uint _baseRate) external {\n baseRate = _baseRate;\n }\n\n function callGetRedemptionFee(uint _ETHDrawn) external view returns (uint) {\n _getRedemptionFee(_ETHDrawn);\n }\n\n function getActualDebtFromComposite(uint _debtVal) external pure returns (uint) {\n return _getNetDebt(_debtVal);\n }\n\n function callInternalRemoveTroveOwner(address _troveOwner) external {\n uint troveOwnersArrayLength = TroveOwners.length;\n _removeTroveOwner(_troveOwner, troveOwnersArrayLength);\n }\n}\n" + }, + "contracts/TestContracts/UpgradableProxyTester.sol": { + "content": "\n// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Proxy/UpgradableProxy.sol\";\ncontract Storage {\n uint someVar;\n}\n\ncontract ProxiableContract is Storage {\n\n function getSomeVar() public view returns (uint) {\n return someVar;\n }\n\n function setSomeVar(uint value) public {\n someVar = value;\n }\n}\n\ncontract Storage2 {\n uint anotherVar;\n}\n\ncontract ProxiableContract2 is ProxiableContract, Storage2 {\n\n function getAnotherVar() public view returns (uint) {\n return anotherVar;\n }\n\n function setAnotherVar(uint value) public {\n anotherVar = value;\n }\n\n function mulVars() public view returns (uint) {\n return someVar * anotherVar;\n }\n}\n\ncontract UpgradableProxyTester is UpgradableProxy, Storage {}\n" + }, + "contracts/TestContracts/ZEROStakingTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/ZEROStaking.sol\";\n\n\ncontract ZEROStakingTester is ZEROStaking {\n function requireCallerIsFeeDistributor() external view {\n _requireCallerIsFeeDistributor();\n }\n}\n" + }, + "contracts/TestContracts/ZEROTokenTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/ZEROToken.sol\";\n\ncontract ZEROTokenTester is ZEROToken {\n constructor\n (\n address _zeroStakingAddress,\n address _marketMakerAddress,\n address _presaleAddress\n ) \n public \n {\n initialize(\n _zeroStakingAddress,\n _marketMakerAddress,\n _presaleAddress\n );\n } \n\n function unprotectedMint(address account, uint256 amount) external {\n // No check for the caller here\n\n _mint(account, amount);\n }\n\n function unprotectedSendToZEROStaking(address _sender, uint256 _amount) external {\n // No check for the caller here\n \n _transfer(_sender, zeroStakingAddress, _amount);\n }\n\n function callInternalApprove(address owner, address spender, uint256 amount) external returns (bool) {\n _approve(owner, spender, amount);\n }\n\n function callInternalTransfer(address sender, address recipient, uint256 amount) external returns (bool) {\n _transfer(sender, recipient, amount);\n }\n\n function getChainId() external pure returns (uint256 chainID) {\n //return _chainID(); // it’s private\n assembly {\n chainID := chainid()\n }\n }\n}" + }, + "contracts/TestContracts/ZUSDTokenCaller.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IZUSDToken.sol\";\n\ncontract ZUSDTokenCaller {\n IZUSDToken ZUSD;\n\n function setZUSD(IZUSDToken _ZUSD) external {\n ZUSD = _ZUSD;\n }\n\n function zusdMint(address _account, uint _amount) external {\n ZUSD.mint(_account, _amount);\n }\n\n function zusdBurn(address _account, uint _amount) external {\n ZUSD.burn(_account, _amount);\n }\n\n function zusdSendToPool(address _sender, address _poolAddress, uint256 _amount) external {\n ZUSD.sendToPool(_sender, _poolAddress, _amount);\n }\n\n function zusdReturnFromPool(address _poolAddress, address _receiver, uint256 _amount ) external {\n ZUSD.returnFromPool(_poolAddress, _receiver, _amount);\n }\n}\n" + }, + "contracts/TestContracts/ZUSDTokenTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZUSDToken.sol\";\n\ncontract ZUSDTokenTester is ZUSDToken {\n \n constructor( \n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) public {\n initialize(_troveManagerAddress, _stabilityPoolAddress, _borrowerOperationsAddress);\n }\n \n function unprotectedMint(address _account, uint256 _amount) external {\n // No check on caller here\n\n _mint(_account, _amount);\n }\n\n function unprotectedBurn(address _account, uint _amount) external {\n // No check on caller here\n \n _burn(_account, _amount);\n }\n\n function unprotectedSendToPool(address _sender, address _poolAddress, uint256 _amount) external {\n // No check on caller here\n\n _transfer(_sender, _poolAddress, _amount);\n }\n\n function unprotectedReturnFromPool(address _poolAddress, address _receiver, uint256 _amount ) external {\n // No check on caller here\n\n _transfer(_poolAddress, _receiver, _amount);\n }\n\n function callInternalApprove(address owner, address spender, uint256 amount) external returns (bool) {\n _approve(owner, spender, amount);\n }\n\n function getChainId() external pure returns (uint256 chainID) {\n //return _chainID(); // it’s private\n assembly {\n chainID := chainid()\n }\n }\n\n function getDigest(address owner, address spender, uint amount, uint nonce, uint deadline) external view returns (bytes32) {\n return keccak256(abi.encodePacked(\n uint16(0x1901),\n domainSeparator(),\n keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, amount, nonce, deadline))\n )\n );\n }\n\n function recoverAddress(bytes32 digest, uint8 v, bytes32 r, bytes32 s) external pure returns (address) {\n return ecrecover(digest, v, r, s);\n }\n}\n" + }, + "contracts/TestContracts/ZUSDTokenTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IZUSDToken.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/console.sol\";\nimport \"../ZUSDToken.sol\";\n\n/**\n *\n * Based upon OpenZeppelin's ERC20 contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol\n *\n * and their EIP2612 (ERC20Permit / ERC712) functionality:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\n *\n *\n * --- Functionality added specific to the ZUSDToken ---\n *\n * 1) Transfer protection: blacklist of addresses that are invalid recipients (i.e. core Zero contracts) in external\n * transfer() and transferFrom() calls. The purpose is to protect users from losing tokens by mistakenly sending ZUSD directly to a Zero\n * core contract, when they should rather call the right function.\n *\n * 2) sendToPool() and returnFromPool(): functions callable only Zero core contracts, which move ZUSD tokens between Zero <-> user.\n */\n\n/// @dev ZUSDTokenTestnet has unptotected initialize function to bypass initializer() modifier validation\n/// @notice use if need to redeploy the token logic AND run initialize() again on the proxy\ncontract ZUSDTokenTestnet is ZUSDToken {\n function initialize(\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) public override onlyOwner {\n _initialize(_troveManagerAddress, _stabilityPoolAddress, _borrowerOperationsAddress);\n }\n}\n" + }, + "contracts/TroveManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROToken.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./Dependencies/TroveManagerBase.sol\";\nimport \"./TroveManagerStorage.sol\";\n\ncontract TroveManager is TroveManagerBase, CheckContract, ITroveManager {\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerRedeemOpsAddressChanged(address _troveManagerRedeemOps);\n event LiquityBaseParamsAddressChanges(address _borrowerOperationsAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZEROTokenAddressChanged(address _zeroTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n\n ///@param _bootstrapPeriod During bootsrap period redemptions are not allowed\n constructor(uint256 _bootstrapPeriod) public TroveManagerBase(_bootstrapPeriod) {}\n\n // --- Dependency setter ---\n function setAddresses(\n TroveManagerInitAddressesParams memory _troveManagerInitAddressesParams\n ) external override onlyOwner {\n {\n checkContract(_troveManagerInitAddressesParams._feeDistributorAddress);\n checkContract(_troveManagerInitAddressesParams._troveManagerRedeemOps);\n checkContract(_troveManagerInitAddressesParams._liquityBaseParamsAddress);\n checkContract(_troveManagerInitAddressesParams._borrowerOperationsAddress);\n checkContract(_troveManagerInitAddressesParams._activePoolAddress);\n checkContract(_troveManagerInitAddressesParams._defaultPoolAddress);\n checkContract(_troveManagerInitAddressesParams._stabilityPoolAddress);\n checkContract(_troveManagerInitAddressesParams._gasPoolAddress);\n checkContract(_troveManagerInitAddressesParams._collSurplusPoolAddress);\n checkContract(_troveManagerInitAddressesParams._priceFeedAddress);\n checkContract(_troveManagerInitAddressesParams._zusdTokenAddress);\n checkContract(_troveManagerInitAddressesParams._sortedTrovesAddress);\n checkContract(_troveManagerInitAddressesParams._zeroTokenAddress);\n checkContract(_troveManagerInitAddressesParams._zeroStakingAddress);\n }\n\n feeDistributor = IFeeDistributor(_troveManagerInitAddressesParams._feeDistributorAddress);\n troveManagerRedeemOps = _troveManagerInitAddressesParams._troveManagerRedeemOps;\n liquityBaseParams = ILiquityBaseParams(\n _troveManagerInitAddressesParams._liquityBaseParamsAddress\n );\n {\n borrowerOperationsAddress = _troveManagerInitAddressesParams\n ._borrowerOperationsAddress;\n activePool = IActivePool(_troveManagerInitAddressesParams._activePoolAddress);\n defaultPool = IDefaultPool(_troveManagerInitAddressesParams._defaultPoolAddress);\n _stabilityPool = IStabilityPool(\n _troveManagerInitAddressesParams._stabilityPoolAddress\n );\n gasPoolAddress = _troveManagerInitAddressesParams._gasPoolAddress;\n collSurplusPool = ICollSurplusPool(\n _troveManagerInitAddressesParams._collSurplusPoolAddress\n );\n priceFeed = IPriceFeed(_troveManagerInitAddressesParams._priceFeedAddress);\n _zusdToken = IZUSDToken(_troveManagerInitAddressesParams._zusdTokenAddress);\n sortedTroves = ISortedTroves(_troveManagerInitAddressesParams._sortedTrovesAddress);\n _zeroToken = IZEROToken(_troveManagerInitAddressesParams._zeroTokenAddress);\n _zeroStaking = IZEROStaking(_troveManagerInitAddressesParams._zeroStakingAddress);\n }\n\n emit FeeDistributorAddressChanged(_troveManagerInitAddressesParams._feeDistributorAddress);\n emit TroveManagerRedeemOpsAddressChanged(\n _troveManagerInitAddressesParams._troveManagerRedeemOps\n );\n emit LiquityBaseParamsAddressChanges(\n _troveManagerInitAddressesParams._borrowerOperationsAddress\n );\n emit BorrowerOperationsAddressChanged(\n _troveManagerInitAddressesParams._borrowerOperationsAddress\n );\n emit ActivePoolAddressChanged(_troveManagerInitAddressesParams._activePoolAddress);\n emit DefaultPoolAddressChanged(_troveManagerInitAddressesParams._defaultPoolAddress);\n emit StabilityPoolAddressChanged(_troveManagerInitAddressesParams._stabilityPoolAddress);\n emit GasPoolAddressChanged(_troveManagerInitAddressesParams._gasPoolAddress);\n emit CollSurplusPoolAddressChanged(\n _troveManagerInitAddressesParams._collSurplusPoolAddress\n );\n emit PriceFeedAddressChanged(_troveManagerInitAddressesParams._priceFeedAddress);\n emit ZUSDTokenAddressChanged(_troveManagerInitAddressesParams._zusdTokenAddress);\n emit SortedTrovesAddressChanged(_troveManagerInitAddressesParams._sortedTrovesAddress);\n emit ZEROTokenAddressChanged(_troveManagerInitAddressesParams._zeroTokenAddress);\n emit ZEROStakingAddressChanged(_troveManagerInitAddressesParams._zeroStakingAddress);\n }\n\n function setTroveManagerRedeemOps(address _troveManagerRedeemOps) external override onlyOwner {\n checkContract(_troveManagerRedeemOps);\n troveManagerRedeemOps = _troveManagerRedeemOps;\n emit TroveManagerRedeemOpsAddressChanged(_troveManagerRedeemOps);\n }\n\n // --- Getters ---\n\n function getTroveOwnersCount() external view override returns (uint256) {\n return TroveOwners.length;\n }\n\n function getTroveFromTroveOwnersArray(\n uint256 _index\n ) external view override returns (address) {\n return TroveOwners[_index];\n }\n\n // --- Trove Liquidation functions ---\n\n /// Single liquidation function. Closes the trove if its ICR is lower than the minimum collateral ratio.\n function liquidate(address _borrower) external override {\n _requireTroveIsActive(_borrower);\n\n address[] memory borrowers = new address[](1);\n borrowers[0] = _borrower;\n batchLiquidateTroves(borrowers);\n }\n\n // --- Inner single liquidation functions ---\n\n /// Liquidate one trove, in Normal Mode.\n function _liquidateNormalMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n address _borrower,\n uint256 _ZUSDInStabPool\n ) internal returns (LiquidationValues memory singleLiquidation) {\n LocalVariables_InnerSingleLiquidateFunction memory vars;\n\n (\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n vars.pendingDebtReward,\n vars.pendingCollReward\n ) = getEntireDebtAndColl(_borrower);\n\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n _removeStake(_borrower);\n\n singleLiquidation.collGasCompensation = _getCollGasCompensation(\n singleLiquidation.entireTroveColl\n );\n singleLiquidation.ZUSDGasCompensation = ZUSD_GAS_COMPENSATION;\n uint256 collToLiquidate = singleLiquidation.entireTroveColl.sub(\n singleLiquidation.collGasCompensation\n );\n\n (\n singleLiquidation.debtToOffset,\n singleLiquidation.collToSendToSP,\n singleLiquidation.debtToRedistribute,\n singleLiquidation.collToRedistribute\n ) = _getOffsetAndRedistributionVals(\n singleLiquidation.entireTroveDebt,\n collToLiquidate,\n _ZUSDInStabPool\n );\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n TroveManagerOperation.liquidateInNormalMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInNormalMode);\n return singleLiquidation;\n }\n\n /// Liquidate one trove, in Recovery Mode.\n function _liquidateRecoveryMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n address _borrower,\n uint256 _ICR,\n uint256 _ZUSDInStabPool,\n uint256 _TCR,\n uint256 _price\n ) internal returns (LiquidationValues memory singleLiquidation) {\n LocalVariables_InnerSingleLiquidateFunction memory vars;\n if (TroveOwners.length <= 1) {\n return singleLiquidation;\n } // don't liquidate if last trove\n (\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n vars.pendingDebtReward,\n vars.pendingCollReward\n ) = getEntireDebtAndColl(_borrower);\n\n singleLiquidation.collGasCompensation = _getCollGasCompensation(\n singleLiquidation.entireTroveColl\n );\n singleLiquidation.ZUSDGasCompensation = ZUSD_GAS_COMPENSATION;\n vars.collToLiquidate = singleLiquidation.entireTroveColl.sub(\n singleLiquidation.collGasCompensation\n );\n\n // If ICR <= 100%, purely redistribute the Trove across all active Troves\n if (_ICR <= _100pct) {\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n _removeStake(_borrower);\n\n singleLiquidation.debtToOffset = 0;\n singleLiquidation.collToSendToSP = 0;\n singleLiquidation.debtToRedistribute = singleLiquidation.entireTroveDebt;\n singleLiquidation.collToRedistribute = vars.collToLiquidate;\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n TroveManagerOperation.liquidateInRecoveryMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode);\n\n // If 100% < ICR < MCR, offset as much as possible, and redistribute the remainder\n } else if ((_ICR > _100pct) && (_ICR < liquityBaseParams.MCR())) {\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n _removeStake(_borrower);\n\n (\n singleLiquidation.debtToOffset,\n singleLiquidation.collToSendToSP,\n singleLiquidation.debtToRedistribute,\n singleLiquidation.collToRedistribute\n ) = _getOffsetAndRedistributionVals(\n singleLiquidation.entireTroveDebt,\n vars.collToLiquidate,\n _ZUSDInStabPool\n );\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n TroveManagerOperation.liquidateInRecoveryMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode);\n /*\n * If 110% <= ICR < current TCR (accounting for the preceding liquidations in the current sequence)\n * and there is ZUSD in the Stability Pool, only offset, with no redistribution,\n * but at a capped rate of 1.1 and only if the whole debt can be liquidated.\n * The remainder due to the capped rate will be claimable as collateral surplus.\n */\n } else if (\n (_ICR >= liquityBaseParams.MCR()) &&\n (_ICR < _TCR) &&\n (singleLiquidation.entireTroveDebt <= _ZUSDInStabPool)\n ) {\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n assert(_ZUSDInStabPool != 0);\n\n _removeStake(_borrower);\n singleLiquidation = _getCappedOffsetVals(\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n _price\n );\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n if (singleLiquidation.collSurplus > 0) {\n collSurplusPool.accountSurplus(_borrower, singleLiquidation.collSurplus);\n }\n\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.collToSendToSP,\n TroveManagerOperation.liquidateInRecoveryMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode);\n } else {\n // if (_ICR >= liquityBaseParams.MCR() && ( _ICR >= _TCR || singleLiquidation.entireTroveDebt > _ZUSDInStabPool))\n LiquidationValues memory zeroVals;\n return zeroVals;\n }\n\n return singleLiquidation;\n }\n\n /** In a full liquidation, returns the values for a trove's coll and debt to be offset, and coll and debt to be\n * redistributed to active troves.\n */\n function _getOffsetAndRedistributionVals(\n uint256 _debt,\n uint256 _coll,\n uint256 _ZUSDInStabPool\n )\n internal\n pure\n returns (\n uint256 debtToOffset,\n uint256 collToSendToSP,\n uint256 debtToRedistribute,\n uint256 collToRedistribute\n )\n {\n if (_ZUSDInStabPool > 0) {\n /*\n * Offset as much debt & collateral as possible against the Stability Pool, and redistribute the remainder\n * between all active troves.\n *\n * If the trove's debt is larger than the deposited ZUSD in the Stability Pool:\n *\n * - Offset an amount of the trove's debt equal to the ZUSD in the Stability Pool\n * - Send a fraction of the trove's collateral to the Stability Pool, equal to the fraction of its offset debt\n *\n */\n debtToOffset = LiquityMath._min(_debt, _ZUSDInStabPool);\n collToSendToSP = _coll.mul(debtToOffset).div(_debt);\n debtToRedistribute = _debt.sub(debtToOffset);\n collToRedistribute = _coll.sub(collToSendToSP);\n } else {\n debtToOffset = 0;\n collToSendToSP = 0;\n debtToRedistribute = _debt;\n collToRedistribute = _coll;\n }\n }\n\n /**\n * Get its offset coll/debt and ETH gas comp, and close the trove.\n */\n function _getCappedOffsetVals(\n uint256 _entireTroveDebt,\n uint256 _entireTroveColl,\n uint256 _price\n ) internal view returns (LiquidationValues memory singleLiquidation) {\n singleLiquidation.entireTroveDebt = _entireTroveDebt;\n singleLiquidation.entireTroveColl = _entireTroveColl;\n uint256 collToOffset = _entireTroveDebt.mul(liquityBaseParams.MCR()).div(_price);\n\n singleLiquidation.collGasCompensation = _getCollGasCompensation(collToOffset);\n singleLiquidation.ZUSDGasCompensation = ZUSD_GAS_COMPENSATION;\n\n singleLiquidation.debtToOffset = _entireTroveDebt;\n singleLiquidation.collToSendToSP = collToOffset.sub(singleLiquidation.collGasCompensation);\n singleLiquidation.collSurplus = _entireTroveColl.sub(collToOffset);\n singleLiquidation.debtToRedistribute = 0;\n singleLiquidation.collToRedistribute = 0;\n }\n\n /**\n * Liquidate a sequence of troves. Closes a maximum number of n under-collateralized Troves,\n * starting from the one with the lowest collateral ratio in the system, and moving upwards\n */\n function liquidateTroves(uint256 _n) external override {\n ContractsCache memory contractsCache = ContractsCache(\n activePool,\n defaultPool,\n IZUSDToken(address(0)),\n IZEROStaking(address(0)),\n sortedTroves,\n ICollSurplusPool(address(0)),\n address(0)\n );\n IStabilityPool stabilityPoolCached = _stabilityPool;\n\n LocalVariables_OuterLiquidationFunction memory vars;\n\n LiquidationTotals memory totals;\n\n vars.price = priceFeed.fetchPrice();\n vars.ZUSDInStabPool = stabilityPoolCached.getTotalZUSDDeposits();\n vars.recoveryModeAtStart = _checkRecoveryMode(vars.price);\n\n // Perform the appropriate liquidation sequence - tally the values, and obtain their totals\n if (vars.recoveryModeAtStart) {\n totals = _getTotalsFromLiquidateTrovesSequence_RecoveryMode(\n contractsCache,\n vars.price,\n vars.ZUSDInStabPool,\n _n\n );\n } else {\n // if !vars.recoveryModeAtStart\n totals = _getTotalsFromLiquidateTrovesSequence_NormalMode(\n contractsCache.activePool,\n contractsCache.defaultPool,\n vars.price,\n vars.ZUSDInStabPool,\n _n\n );\n }\n\n require(totals.totalDebtInSequence > 0, \"TroveManager: nothing to liquidate\");\n\n // Move liquidated ETH and ZUSD to the appropriate pools\n stabilityPoolCached.offset(totals.totalDebtToOffset, totals.totalCollToSendToSP);\n _redistributeDebtAndColl(\n contractsCache.activePool,\n contractsCache.defaultPool,\n totals.totalDebtToRedistribute,\n totals.totalCollToRedistribute\n );\n if (totals.totalCollSurplus > 0) {\n contractsCache.activePool.sendETH(address(collSurplusPool), totals.totalCollSurplus);\n }\n\n // Update system snapshots\n _updateSystemSnapshots_excludeCollRemainder(\n contractsCache.activePool,\n totals.totalCollGasCompensation\n );\n\n vars.liquidatedDebt = totals.totalDebtInSequence;\n vars.liquidatedColl = totals.totalCollInSequence.sub(totals.totalCollGasCompensation).sub(\n totals.totalCollSurplus\n );\n emit Liquidation(\n vars.liquidatedDebt,\n vars.liquidatedColl,\n totals.totalCollGasCompensation,\n totals.totalZUSDGasCompensation\n );\n\n // Send gas compensation to caller\n _sendGasCompensation(\n contractsCache.activePool,\n msg.sender,\n totals.totalZUSDGasCompensation,\n totals.totalCollGasCompensation\n );\n }\n\n /**\n * This function is used when the liquidateTroves sequence starts during Recovery Mode. However, it\n * handle the case where the system *leaves* Recovery Mode, part way through the liquidation sequence\n */\n function _getTotalsFromLiquidateTrovesSequence_RecoveryMode(\n ContractsCache memory _contractsCache,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n uint256 _n\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n vars.backToNormalMode = false;\n vars.entireSystemDebt = getEntireSystemDebt();\n vars.entireSystemColl = getEntireSystemColl();\n\n vars.user = _contractsCache.sortedTroves.getLast();\n address firstUser = _contractsCache.sortedTroves.getFirst();\n for (vars.i = 0; vars.i < _n && vars.user != firstUser; vars.i++) {\n // we need to cache it, because current user is likely going to be deleted\n address nextUser = _contractsCache.sortedTroves.getPrev(vars.user);\n\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (!vars.backToNormalMode) {\n // Break the loop if ICR is greater than liquityBaseParams.MCR() and Stability Pool is empty\n if (vars.ICR >= liquityBaseParams.MCR() && vars.remainingZUSDInStabPool == 0) {\n break;\n }\n\n uint256 TCR = LiquityMath._computeCR(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n\n singleLiquidation = _liquidateRecoveryMode(\n _contractsCache.activePool,\n _contractsCache.defaultPool,\n vars.user,\n vars.ICR,\n vars.remainingZUSDInStabPool,\n TCR,\n _price\n );\n\n // Update aggregate trackers\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n vars.entireSystemDebt = vars.entireSystemDebt.sub(singleLiquidation.debtToOffset);\n vars.entireSystemColl = vars\n .entireSystemColl\n .sub(singleLiquidation.collToSendToSP)\n .sub(singleLiquidation.collSurplus);\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n\n vars.backToNormalMode = !_checkPotentialRecoveryMode(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n } else if (vars.backToNormalMode && vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _contractsCache.activePool,\n _contractsCache.defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n } else break; // break if the loop reaches a Trove with ICR >= MCR\n\n vars.user = nextUser;\n }\n }\n\n function _getTotalsFromLiquidateTrovesSequence_NormalMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n uint256 _n\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n ISortedTroves sortedTrovesCached = sortedTroves;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n\n for (vars.i = 0; vars.i < _n; vars.i++) {\n vars.user = sortedTrovesCached.getLast();\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n } else break; // break if the loop reaches a Trove with ICR >= MCR\n }\n }\n\n /**\n * Attempt to liquidate a custom list of troves provided by the caller.\n */\n function batchLiquidateTroves(address[] memory _troveArray) public override {\n require(_troveArray.length != 0, \"TroveManager: Calldata address array must not be empty\");\n\n IActivePool activePoolCached = activePool;\n IDefaultPool defaultPoolCached = defaultPool;\n IStabilityPool stabilityPoolCached = _stabilityPool;\n\n LocalVariables_OuterLiquidationFunction memory vars;\n LiquidationTotals memory totals;\n\n vars.price = priceFeed.fetchPrice();\n vars.ZUSDInStabPool = stabilityPoolCached.getTotalZUSDDeposits();\n vars.recoveryModeAtStart = _checkRecoveryMode(vars.price);\n\n // Perform the appropriate liquidation sequence - tally values and obtain their totals.\n if (vars.recoveryModeAtStart) {\n totals = _getTotalFromBatchLiquidate_RecoveryMode(\n activePoolCached,\n defaultPoolCached,\n vars.price,\n vars.ZUSDInStabPool,\n _troveArray\n );\n } else {\n // if !vars.recoveryModeAtStart\n totals = _getTotalsFromBatchLiquidate_NormalMode(\n activePoolCached,\n defaultPoolCached,\n vars.price,\n vars.ZUSDInStabPool,\n _troveArray\n );\n }\n\n require(totals.totalDebtInSequence > 0, \"TroveManager: nothing to liquidate\");\n\n // Move liquidated ETH and ZUSD to the appropriate pools\n stabilityPoolCached.offset(totals.totalDebtToOffset, totals.totalCollToSendToSP);\n _redistributeDebtAndColl(\n activePoolCached,\n defaultPoolCached,\n totals.totalDebtToRedistribute,\n totals.totalCollToRedistribute\n );\n if (totals.totalCollSurplus > 0) {\n activePoolCached.sendETH(address(collSurplusPool), totals.totalCollSurplus);\n }\n\n // Update system snapshots\n _updateSystemSnapshots_excludeCollRemainder(\n activePoolCached,\n totals.totalCollGasCompensation\n );\n\n vars.liquidatedDebt = totals.totalDebtInSequence;\n vars.liquidatedColl = totals.totalCollInSequence.sub(totals.totalCollGasCompensation).sub(\n totals.totalCollSurplus\n );\n emit Liquidation(\n vars.liquidatedDebt,\n vars.liquidatedColl,\n totals.totalCollGasCompensation,\n totals.totalZUSDGasCompensation\n );\n\n // Send gas compensation to caller\n _sendGasCompensation(\n activePoolCached,\n msg.sender,\n totals.totalZUSDGasCompensation,\n totals.totalCollGasCompensation\n );\n }\n\n /**\n * This function is used when the batch liquidation sequence starts during Recovery Mode. However, it\n * handle the case where the system *leaves* Recovery Mode, part way through the liquidation sequence\n */\n function _getTotalFromBatchLiquidate_RecoveryMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n address[] memory _troveArray\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n vars.backToNormalMode = false;\n vars.entireSystemDebt = getEntireSystemDebt();\n vars.entireSystemColl = getEntireSystemColl();\n\n for (vars.i = 0; vars.i < _troveArray.length; vars.i++) {\n vars.user = _troveArray[vars.i];\n // Skip non-active troves\n if (Troves[vars.user].status != Status.active) {\n continue;\n }\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (!vars.backToNormalMode) {\n // Skip this trove if ICR is greater than liquityBaseParams.MCR() and Stability Pool is empty\n if (vars.ICR >= liquityBaseParams.MCR() && vars.remainingZUSDInStabPool == 0) {\n continue;\n }\n\n uint256 TCR = LiquityMath._computeCR(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n\n singleLiquidation = _liquidateRecoveryMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.ICR,\n vars.remainingZUSDInStabPool,\n TCR,\n _price\n );\n\n // Update aggregate trackers\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n vars.entireSystemDebt = vars.entireSystemDebt.sub(singleLiquidation.debtToOffset);\n vars.entireSystemColl = vars.entireSystemColl.sub(\n singleLiquidation.collToSendToSP\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n\n vars.backToNormalMode = !_checkPotentialRecoveryMode(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n } else if (vars.backToNormalMode && vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n } else continue; // In Normal Mode skip troves with ICR >= MCR\n }\n }\n\n function _getTotalsFromBatchLiquidate_NormalMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n address[] memory _troveArray\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n\n for (vars.i = 0; vars.i < _troveArray.length; vars.i++) {\n vars.user = _troveArray[vars.i];\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n }\n }\n }\n\n // --- Liquidation helper functions ---\n\n function _addLiquidationValuesToTotals(\n LiquidationTotals memory oldTotals,\n LiquidationValues memory singleLiquidation\n ) internal pure returns (LiquidationTotals memory newTotals) {\n // Tally all the values with their respective running totals\n newTotals.totalCollGasCompensation = oldTotals.totalCollGasCompensation.add(\n singleLiquidation.collGasCompensation\n );\n newTotals.totalZUSDGasCompensation = oldTotals.totalZUSDGasCompensation.add(\n singleLiquidation.ZUSDGasCompensation\n );\n newTotals.totalDebtInSequence = oldTotals.totalDebtInSequence.add(\n singleLiquidation.entireTroveDebt\n );\n newTotals.totalCollInSequence = oldTotals.totalCollInSequence.add(\n singleLiquidation.entireTroveColl\n );\n newTotals.totalDebtToOffset = oldTotals.totalDebtToOffset.add(\n singleLiquidation.debtToOffset\n );\n newTotals.totalCollToSendToSP = oldTotals.totalCollToSendToSP.add(\n singleLiquidation.collToSendToSP\n );\n newTotals.totalDebtToRedistribute = oldTotals.totalDebtToRedistribute.add(\n singleLiquidation.debtToRedistribute\n );\n newTotals.totalCollToRedistribute = oldTotals.totalCollToRedistribute.add(\n singleLiquidation.collToRedistribute\n );\n newTotals.totalCollSurplus = oldTotals.totalCollSurplus.add(singleLiquidation.collSurplus);\n\n return newTotals;\n }\n\n function _sendGasCompensation(\n IActivePool _activePool,\n address _liquidator,\n uint256 _ZUSD,\n uint256 _ETH\n ) internal {\n if (_ZUSD > 0) {\n _zusdToken.returnFromPool(gasPoolAddress, _liquidator, _ZUSD);\n }\n\n if (_ETH > 0) {\n _activePool.sendETH(_liquidator, _ETH);\n }\n }\n\n // --- Helper functions ---\n\n /// @return the nominal collateral ratio (ICR) of a given Trove, without the price. Takes a trove's pending coll and debt rewards from redistributions into account.\n function getNominalICR(address _borrower) public view override returns (uint256) {\n (uint256 currentETH, uint256 currentZUSDDebt) = _getCurrentTroveAmounts(_borrower);\n\n uint256 NICR = LiquityMath._computeNominalCR(currentETH, currentZUSDDebt);\n return NICR;\n }\n\n function applyPendingRewards(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _applyPendingRewards(activePool, defaultPool, _borrower);\n }\n\n /// Update borrower's snapshots of L_ETH and L_ZUSDDebt to reflect the current values\n function updateTroveRewardSnapshots(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _updateTroveRewardSnapshots(_borrower);\n }\n\n /// Return the Troves entire debt and coll, including pending rewards from redistributions.\n function getEntireDebtAndColl(\n address _borrower\n )\n public\n view\n override\n returns (\n uint256 debt,\n uint256 coll,\n uint256 pendingZUSDDebtReward,\n uint256 pendingETHReward\n )\n {\n debt = Troves[_borrower].debt;\n coll = Troves[_borrower].coll;\n\n pendingZUSDDebtReward = getPendingZUSDDebtReward(_borrower);\n pendingETHReward = getPendingETHReward(_borrower);\n\n debt = debt.add(pendingZUSDDebtReward);\n coll = coll.add(pendingETHReward);\n }\n\n function removeStake(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _removeStake(_borrower);\n }\n\n function updateStakeAndTotalStakes(address _borrower) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n return _updateStakeAndTotalStakes(_borrower);\n }\n\n function _redistributeDebtAndColl(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _debt,\n uint256 _coll\n ) internal {\n if (_debt == 0) {\n return;\n }\n\n /*\n * Add distributed coll and debt rewards-per-unit-staked to the running totals. Division uses a \"feedback\"\n * error correction, to keep the cumulative error low in the running totals L_ETH and L_ZUSDDebt:\n *\n * 1) Form numerators which compensate for the floor division errors that occurred the last time this\n * function was called.\n * 2) Calculate \"per-unit-staked\" ratios.\n * 3) Multiply each ratio back by its denominator, to reveal the current floor division error.\n * 4) Store these errors for use in the next correction when this function is called.\n * 5) Note: static analysis tools complain about this \"division before multiplication\", however, it is intended.\n */\n uint256 ETHNumerator = _coll.mul(DECIMAL_PRECISION).add(lastETHError_Redistribution);\n uint256 ZUSDDebtNumerator = _debt.mul(DECIMAL_PRECISION).add(\n lastZUSDDebtError_Redistribution\n );\n\n // Get the per-unit-staked terms\n uint256 ETHRewardPerUnitStaked = ETHNumerator.div(totalStakes);\n uint256 ZUSDDebtRewardPerUnitStaked = ZUSDDebtNumerator.div(totalStakes);\n\n lastETHError_Redistribution = ETHNumerator.sub(ETHRewardPerUnitStaked.mul(totalStakes));\n lastZUSDDebtError_Redistribution = ZUSDDebtNumerator.sub(\n ZUSDDebtRewardPerUnitStaked.mul(totalStakes)\n );\n\n // Add per-unit-staked terms to the running totals\n L_ETH = L_ETH.add(ETHRewardPerUnitStaked);\n L_ZUSDDebt = L_ZUSDDebt.add(ZUSDDebtRewardPerUnitStaked);\n\n emit LTermsUpdated(L_ETH, L_ZUSDDebt);\n\n // Transfer coll and debt from ActivePool to DefaultPool\n _activePool.decreaseZUSDDebt(_debt);\n _defaultPool.increaseZUSDDebt(_debt);\n _activePool.sendETH(address(_defaultPool), _coll);\n }\n\n function closeTrove(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _closeTrove(_borrower, Status.closedByOwner);\n }\n\n /**\n * Updates snapshots of system total stakes and total collateral, excluding a given collateral remainder from the calculation.\n * Used in a liquidation sequence.\n *\n * The calculation excludes a portion of collateral that is in the ActivePool:\n *\n * the total ETH gas compensation from the liquidation sequence\n *\n * The ETH as compensation must be excluded as it is always sent out at the very end of the liquidation sequence.\n */\n function _updateSystemSnapshots_excludeCollRemainder(\n IActivePool _activePool,\n uint256 _collRemainder\n ) internal {\n totalStakesSnapshot = totalStakes;\n\n uint256 activeColl = _activePool.getETH();\n uint256 liquidatedColl = defaultPool.getETH();\n totalCollateralSnapshot = activeColl.sub(_collRemainder).add(liquidatedColl);\n\n emit SystemSnapshotsUpdated(totalStakesSnapshot, totalCollateralSnapshot);\n }\n\n /// Push the owner's address to the Trove owners list, and record the corresponding array index on the Trove struct\n function addTroveOwnerToArray(address _borrower) external override returns (uint256 index) {\n _requireCallerIsBorrowerOperations();\n return _addTroveOwnerToArray(_borrower);\n }\n\n function _addTroveOwnerToArray(address _borrower) internal returns (uint128 index) {\n /* Max array size is 2**128 - 1, i.e. ~3e30 troves. No risk of overflow, since troves have minimum ZUSD\n debt of liquidation reserve plus MIN_NET_DEBT. 3e30 ZUSD dwarfs the value of all wealth in the world ( which is < 1e15 USD). */\n\n // Push the Troveowner to the array\n TroveOwners.push(_borrower);\n\n // Record the index of the new Troveowner on their Trove struct\n index = uint128(TroveOwners.length.sub(1));\n Troves[_borrower].arrayIndex = index;\n\n return index;\n }\n\n // --- Recovery Mode and TCR functions ---\n\n function getTCR(uint256 _price) external view override returns (uint256) {\n return _getTCR(_price);\n }\n\n function MCR() external view override returns (uint256) {\n return liquityBaseParams.MCR();\n }\n\n function CCR() external view override returns (uint256) {\n return liquityBaseParams.CCR();\n }\n\n function checkRecoveryMode(uint256 _price) external view override returns (bool) {\n return _checkRecoveryMode(_price);\n }\n\n // Check whether or not the system *would be* in Recovery Mode, given an ETH:USD price, and the entire system coll and debt.\n function _checkPotentialRecoveryMode(\n uint256 _entireSystemColl,\n uint256 _entireSystemDebt,\n uint256 _price\n ) internal view returns (bool) {\n uint256 TCR = LiquityMath._computeCR(_entireSystemColl, _entireSystemDebt, _price);\n\n return TCR < liquityBaseParams.CCR();\n }\n\n function getRedemptionRateWithDecay() public view override returns (uint256) {\n return _calcRedemptionRate(_calcDecayedBaseRate());\n }\n\n function getRedemptionFeeWithDecay(\n uint256 _ETHDrawn\n ) external view override returns (uint256) {\n return _calcRedemptionFee(getRedemptionRateWithDecay(), _ETHDrawn);\n }\n\n // --- Borrowing fee functions ---\n\n function getBorrowingRate() public view override returns (uint256) {\n return _calcBorrowingRate(baseRate);\n }\n\n function getBorrowingRateWithDecay() public view override returns (uint256) {\n return _calcBorrowingRate(_calcDecayedBaseRate());\n }\n\n function _calcBorrowingRate(uint256 _baseRate) internal view returns (uint256) {\n return\n LiquityMath._min(\n liquityBaseParams.BORROWING_FEE_FLOOR().add(_baseRate),\n liquityBaseParams.MAX_BORROWING_FEE()\n );\n }\n\n function getBorrowingFee(uint256 _ZUSDDebt) external view override returns (uint256) {\n return _calcBorrowingFee(getBorrowingRate(), _ZUSDDebt);\n }\n\n function getBorrowingFeeWithDecay(uint256 _ZUSDDebt) external view override returns (uint256) {\n return _calcBorrowingFee(getBorrowingRateWithDecay(), _ZUSDDebt);\n }\n\n function _calcBorrowingFee(\n uint256 _borrowingRate,\n uint256 _ZUSDDebt\n ) internal pure returns (uint256) {\n return _borrowingRate.mul(_ZUSDDebt).div(DECIMAL_PRECISION);\n }\n\n /// Updates the baseRate state variable based on time elapsed since the last redemption or ZUSD borrowing operation.\n function decayBaseRateFromBorrowing() external override {\n _requireCallerIsBorrowerOperations();\n\n uint256 decayedBaseRate = _calcDecayedBaseRate();\n assert(decayedBaseRate <= DECIMAL_PRECISION); // The baseRate can decay to 0\n\n baseRate = decayedBaseRate;\n emit BaseRateUpdated(decayedBaseRate);\n\n _updateLastFeeOpTime();\n }\n\n // --- Internal fee functions ---\n\n // --- Trove property getters ---\n\n function getTroveStatus(address _borrower) external view override returns (uint256) {\n return uint256(Troves[_borrower].status);\n }\n\n function getTroveStake(address _borrower) external view override returns (uint256) {\n return Troves[_borrower].stake;\n }\n\n function getTroveDebt(address _borrower) external view override returns (uint256) {\n return Troves[_borrower].debt;\n }\n\n function getTroveColl(address _borrower) external view override returns (uint256) {\n return Troves[_borrower].coll;\n }\n\n // --- Trove property setters, called by BorrowerOperations ---\n\n function setTroveStatus(address _borrower, uint256 _num) external override {\n _requireCallerIsBorrowerOperations();\n Troves[_borrower].status = Status(_num);\n }\n\n function increaseTroveColl(\n address _borrower,\n uint256 _collIncrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newColl = Troves[_borrower].coll.add(_collIncrease);\n Troves[_borrower].coll = newColl;\n return newColl;\n }\n\n function decreaseTroveColl(\n address _borrower,\n uint256 _collDecrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newColl = Troves[_borrower].coll.sub(_collDecrease);\n Troves[_borrower].coll = newColl;\n return newColl;\n }\n\n function increaseTroveDebt(\n address _borrower,\n uint256 _debtIncrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newDebt = Troves[_borrower].debt.add(_debtIncrease);\n Troves[_borrower].debt = newDebt;\n return newDebt;\n }\n\n function decreaseTroveDebt(\n address _borrower,\n uint256 _debtDecrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newDebt = Troves[_borrower].debt.sub(_debtDecrease);\n Troves[_borrower].debt = newDebt;\n return newDebt;\n }\n\n function getCurrentICR(\n address _borrower,\n uint256 _price\n ) external view override returns (uint256) {\n return _getCurrentICR(_borrower, _price);\n }\n\n function getPendingETHReward(address _borrower) public view override returns (uint256) {\n return _getPendingETHReward(_borrower);\n }\n\n function getPendingZUSDDebtReward(address _borrower) public view override returns (uint256) {\n return _getPendingZUSDDebtReward(_borrower);\n }\n\n function hasPendingRewards(address _borrower) public view override returns (bool) {\n return _hasPendingRewards(_borrower);\n }\n\n function getRedemptionRate() public view override returns (uint256) {\n return _getRedemptionRate();\n }\n\n /// @dev this function forwards the call to the troveManagerRedeemOps in a delegate call fashion\n /// so the parameters are not needed\n function redeemCollateral(\n uint256 _ZUSDamount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage\n ) external override {\n (bool success, bytes memory returndata) = troveManagerRedeemOps.delegatecall(msg.data);\n require(success, string(returndata));\n }\n\n /// @dev this function forwards the call to the troveManagerRedeemOps in a delegate call fashion\n /// so the parameters are not needed\n ///DLLR _owner or _spender can use Sovryn Mynt to convert DLLR to ZUSD, then use the Zero redemption mechanism to redeem ZUSD for RBTC, all in a single transaction\n function redeemCollateralViaDLLR(\n uint256 _dllrAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage,\n IMassetManager.PermitParams calldata _permitParams\n ) external override {\n (bool success, bytes memory returndata) = troveManagerRedeemOps.delegatecall(msg.data);\n require(success, string(returndata));\n }\n}\n" + }, + "contracts/TroveManagerStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROToken.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/BaseMath.sol\";\nimport \"./Dependencies/console.sol\";\n\ncontract TroveManagerStorage is Ownable, BaseMath {\n string public constant NAME = \"TroveManager\";\n\n // --- Connected contract declarations ---\n\n address public troveManagerRedeemOps;\n\n address public borrowerOperationsAddress;\n\n IStabilityPool public _stabilityPool;\n\n address gasPoolAddress;\n\n ICollSurplusPool collSurplusPool;\n\n IZUSDToken public _zusdToken;\n\n IZEROToken public _zeroToken;\n\n IZEROStaking public _zeroStaking;\n\n IFeeDistributor public feeDistributor;\n\n // A doubly linked list of Troves, sorted by their sorted by their collateral ratios\n ISortedTroves public sortedTroves;\n\n // --- Data structures ---\n\n uint256 public baseRate;\n\n // The timestamp of the latest fee operation (redemption or new ZUSD issuance)\n uint256 public lastFeeOperationTime;\n\n enum Status {\n nonExistent,\n active,\n closedByOwner,\n closedByLiquidation,\n closedByRedemption\n }\n\n // Store the necessary data for a trove\n struct Trove {\n uint256 debt;\n uint256 coll;\n uint256 stake;\n Status status;\n uint128 arrayIndex;\n }\n\n mapping(address => Trove) public Troves;\n\n uint256 public totalStakes;\n\n // Snapshot of the value of totalStakes, taken immediately after the latest liquidation\n uint256 public totalStakesSnapshot;\n\n // Snapshot of the total collateral across the ActivePool and DefaultPool, immediately after the latest liquidation.\n uint256 public totalCollateralSnapshot;\n\n /*\n * L_ETH and L_ZUSDDebt track the sums of accumulated liquidation rewards per unit staked. During its lifetime, each stake earns:\n *\n * An ETH gain of ( stake * [L_ETH - L_ETH(0)] )\n * A ZUSDDebt increase of ( stake * [L_ZUSDDebt - L_ZUSDDebt(0)] )\n *\n * Where L_ETH(0) and L_ZUSDDebt(0) are snapshots of L_ETH and L_ZUSDDebt for the active Trove taken at the instant the stake was made\n */\n uint256 public L_ETH;\n uint256 public L_ZUSDDebt;\n\n // Map addresses with active troves to their RewardSnapshot\n mapping(address => RewardSnapshot) public rewardSnapshots;\n\n // Object containing the ETH and ZUSD snapshots for a given active trove\n struct RewardSnapshot {\n uint256 ETH;\n uint256 ZUSDDebt;\n }\n\n // Array of all active trove addresses - used to to compute an approximate hint off-chain, for the sorted list insertion\n address[] public TroveOwners;\n\n // Error trackers for the trove redistribution calculation\n uint256 public lastETHError_Redistribution;\n uint256 public lastZUSDDebtError_Redistribution;\n}\n" + }, + "contracts/ZERO/CommunityIssuance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Interfaces/ICommunityIssuance.sol\";\nimport \"../Dependencies/BaseMath.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"./CommunityIssuanceStorage.sol\";\n\ncontract CommunityIssuance is\n CommunityIssuanceStorage,\n CheckContract,\n BaseMath\n{\n using SafeMath for uint256;\n\n // --- Events ---\n\n event SOVTokenAddressSet(address _sovTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event StabilityPoolAddressSet(address _stabilityPoolAddress);\n event PriceFeedAddressSet(address _priceFeed);\n event RewardManagerAddressSet(address _rewardManagerAddress);\n event TotalSOVIssuedUpdated(uint256 _latestSOVIssued);\n event APRSet(uint256 _APR);\n\n // --- Modifier ---\n modifier onlyRewardManager() {\n require(msg.sender == rewardManager, \"Permission::rewardManager: access denied\");\n _;\n }\n\n // --- Functions ---\n\n /**\n * @dev initialization function to set configs.\n * can only be initialized by owner.\n * @param _sovTokenAddress sov token address.\n * @param _zusdTokenAddress zero token address.\n * @param _stabilityPoolAddress stability pool address.\n * @param _priceFeed price feed address.\n * @param _APR apr in basis points.\n */\n function initialize(\n address _sovTokenAddress,\n address _zusdTokenAddress,\n address _stabilityPoolAddress,\n address _priceFeed,\n uint256 _APR\n ) external initializer onlyOwner {\n checkContract(_sovTokenAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_priceFeed);\n\n _validateAPR(_APR);\n\n sovToken = IERC20(_sovTokenAddress);\n zusdToken = IERC20(_zusdTokenAddress);\n stabilityPoolAddress = _stabilityPoolAddress;\n priceFeed = IPriceFeedSovryn(_priceFeed);\n APR = _APR;\n lastIssuanceTime = block.timestamp;\n\n emit SOVTokenAddressSet(_sovTokenAddress);\n emit StabilityPoolAddressSet(_stabilityPoolAddress);\n emit PriceFeedAddressSet(_priceFeed);\n emit APRSet(_APR);\n }\n\n /**\n * @dev setter function to set the APR value in basis points.\n * can only be called by reward manager.\n * @param _APR apr value in basis points.\n */\n function setAPR(uint256 _APR) external onlyRewardManager {\n _validateAPR(_APR);\n\n APR = _APR;\n\n emit APRSet(_APR);\n }\n\n /**\n * @dev setter function to set the price feed.\n * can only be called by the owner.\n * @param _priceFeedAddress price feed address.\n */\n function setPriceFeed(address _priceFeedAddress) external onlyOwner {\n checkContract(_priceFeedAddress);\n\n priceFeed = IPriceFeedSovryn(_priceFeedAddress);\n\n emit PriceFeedAddressSet(_priceFeedAddress);\n }\n\n /**\n * @dev setter function to set reward manager.\n * can only be called by the owner.\n * @param _rewardManagerAddress reward manager address.\n */\n function setRewardManager(address _rewardManagerAddress) external onlyOwner {\n require(_rewardManagerAddress != address(0), \"Account cannot be zero address\");\n\n rewardManager = _rewardManagerAddress;\n\n emit RewardManagerAddressSet(_rewardManagerAddress);\n }\n\n /**\n * @dev validate the APR value.\n * the value must be >= 0 <= MAX_BPS (10000)\n */\n function _validateAPR(uint256 _APR) private {\n require(_APR <= MAX_BPS, \"APR must be less than 10000\");\n }\n\n\n function issueSOV(uint256 _totalZUSDDeposits) public returns (uint256) {\n _requireCallerIsStabilityPool();\n\n uint256 timePassedSinceLastIssuance = (block.timestamp.sub(lastIssuanceTime));\n uint256 latestTotalSOVIssued = _ZUSDToSOV(_totalZUSDDeposits.mul(APR).div(MAX_BPS).mul(timePassedSinceLastIssuance).div(365 days));\n \n uint256 issuance = latestTotalSOVIssued.sub(totalSOVIssued);\n\n totalSOVIssued = latestTotalSOVIssued;\n lastIssuanceTime = block.timestamp;\n emit TotalSOVIssuedUpdated(latestTotalSOVIssued);\n\n return issuance;\n }\n\n function sendSOV(address _account, uint256 _SOVamount) public {\n _requireCallerIsStabilityPool();\n\n bool success = sovToken.transfer(_account, _SOVamount);\n require(success, \"Failed to send ZERO\");\n }\n\n function _requireCallerIsStabilityPool() internal view {\n require(msg.sender == stabilityPoolAddress, \"CommunityIssuance: caller is not SP\");\n }\n\n /**\n * @dev get the ZUSD to SOV rate conversion. Mostly will be using Sovryn's PriceFeed.\n * @param _zusdAmount zusd amount to get the rate conversion\n * @return the total SOV will be returned.\n */\n function _ZUSDToSOV(uint256 _zusdAmount) internal view returns (uint256) {\n return priceFeed.queryReturn(address(zusdToken), address(sovToken), _zusdAmount);\n }\n}\n" + }, + "contracts/ZERO/CommunityIssuanceStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Interfaces/IPriceFeedSovryn.sol\";\nimport \"../Dependencies/Initializable.sol\";\n\ncontract CommunityIssuanceStorage is Ownable, Initializable {\n // --- Data ---\n\n string constant public NAME = \"CommunityIssuance\";\n\n uint256 constant MAX_BPS = 10000;\n\n IERC20 public sovToken;\n\n IERC20 public zusdToken;\n\n address public stabilityPoolAddress;\n\n uint256 public totalSOVIssued;\n\n uint256 public lastIssuanceTime;\n\n uint256 public APR; //in basis points\n\n address public rewardManager;\n\n IPriceFeedSovryn public priceFeed;\n}\n" + }, + "contracts/ZERO/ZEROStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/BaseMath.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/console.sol\";\nimport \"../Interfaces/IZEROToken.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\nimport \"../Interfaces/IZUSDToken.sol\";\nimport \"./ZEROStakingStorage.sol\";\n\ncontract ZEROStaking is ZEROStakingStorage, IZEROStaking, CheckContract, BaseMath {\n using SafeMath for uint256;\n\n // --- Events ---\n\n event ZEROTokenAddressSet(address _zeroTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event FeeDistributorAddressSet(address _feeDistributorAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event StakeChanged(address indexed staker, uint256 newStake);\n event StakingGainsWithdrawn(address indexed staker, uint256 ZUSDGain, uint256 ETHGain);\n event F_ETHUpdated(uint256 _F_ETH);\n event F_ZUSDUpdated(uint256 _F_ZUSD);\n event TotalZEROStakedUpdated(uint256 _totalZEROStaked);\n event EtherSent(address _account, uint256 _amount);\n event StakerSnapshotsUpdated(address _staker, uint256 _F_ETH, uint256 _F_ZUSD);\n\n // --- Functions ---\n\n function setAddresses(\n address _zeroTokenAddress,\n address _zusdTokenAddress,\n address _feeDistributorAddress,\n address _activePoolAddress\n ) external override onlyOwner {\n checkContract(_zeroTokenAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_feeDistributorAddress);\n checkContract(_activePoolAddress);\n\n zeroToken = IZEROToken(_zeroTokenAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n feeDistributorAddress = _feeDistributorAddress;\n activePoolAddress = _activePoolAddress;\n\n emit ZEROTokenAddressSet(_zeroTokenAddress);\n emit ZEROTokenAddressSet(_zusdTokenAddress);\n emit FeeDistributorAddressSet(_feeDistributorAddress);\n emit ActivePoolAddressSet(_activePoolAddress);\n }\n\n // If caller has a pre-existing stake, send any accumulated ETH and ZUSD gains to them.\n function stake(uint256 _ZEROamount) external override {\n _requireNonZeroAmount(_ZEROamount);\n\n uint256 currentStake = stakes[msg.sender];\n\n uint256 ETHGain;\n uint256 ZUSDGain;\n // Grab any accumulated ETH and ZUSD gains from the current stake\n if (currentStake != 0) {\n ETHGain = _getPendingETHGain(msg.sender);\n ZUSDGain = _getPendingZUSDGain(msg.sender);\n }\n\n _updateUserSnapshots(msg.sender);\n\n uint256 newStake = currentStake.add(_ZEROamount);\n\n // Increase user’s stake and total ZERO staked\n stakes[msg.sender] = newStake;\n totalZEROStaked = totalZEROStaked.add(_ZEROamount);\n emit TotalZEROStakedUpdated(totalZEROStaked);\n\n // Transfer ZERO from caller to this contract\n zeroToken.sendToZEROStaking(msg.sender, _ZEROamount);\n\n emit StakeChanged(msg.sender, newStake);\n emit StakingGainsWithdrawn(msg.sender, ZUSDGain, ETHGain);\n\n // Send accumulated ZUSD and ETH gains to the caller\n if (currentStake != 0) {\n require(zusdToken.transfer(msg.sender, ZUSDGain), \"Coudn't execute ZUSD transfer\");\n _sendETHGainToUser(ETHGain);\n }\n }\n\n /// Unstake the ZERO and send the it back to the caller, along with their accumulated ZUSD & ETH gains.\n /// If requested amount > stake, send their entire stake.\n function unstake(uint256 _ZEROamount) external override {\n uint256 currentStake = stakes[msg.sender];\n _requireUserHasStake(currentStake);\n\n // Grab any accumulated ETH and ZUSD gains from the current stake\n uint256 ETHGain = _getPendingETHGain(msg.sender);\n uint256 ZUSDGain = _getPendingZUSDGain(msg.sender);\n\n _updateUserSnapshots(msg.sender);\n\n if (_ZEROamount > 0) {\n uint256 ZEROToWithdraw = LiquityMath._min(_ZEROamount, currentStake);\n\n uint256 newStake = currentStake.sub(ZEROToWithdraw);\n\n // Decrease user's stake and total ZERO staked\n stakes[msg.sender] = newStake;\n totalZEROStaked = totalZEROStaked.sub(ZEROToWithdraw);\n emit TotalZEROStakedUpdated(totalZEROStaked);\n\n // Transfer unstaked ZERO to user\n require(\n zeroToken.transfer(msg.sender, ZEROToWithdraw),\n \"Couldn't execute ZUSD transfer\"\n );\n\n emit StakeChanged(msg.sender, newStake);\n }\n\n emit StakingGainsWithdrawn(msg.sender, ZUSDGain, ETHGain);\n\n // Send accumulated ZUSD and ETH gains to the caller\n require(zusdToken.transfer(msg.sender, ZUSDGain), \"Couldn't execute ZUSD transfer\");\n _sendETHGainToUser(ETHGain);\n }\n\n // --- Reward-per-unit-staked increase functions. Called by Zero core contracts ---\n\n function increaseF_ETH(uint256 _ETHFee) external override {\n _requireCallerIsFeeDistributor();\n uint256 ETHFeePerZEROStaked;\n\n if (totalZEROStaked > 0) {\n ETHFeePerZEROStaked = _ETHFee.mul(DECIMAL_PRECISION).div(totalZEROStaked);\n }\n\n F_ETH = F_ETH.add(ETHFeePerZEROStaked);\n emit F_ETHUpdated(F_ETH);\n }\n\n function increaseF_ZUSD(uint256 _ZUSDFee) external override {\n _requireCallerIsFeeDistributor();\n uint256 ZUSDFeePerZEROStaked;\n\n if (totalZEROStaked > 0) {\n ZUSDFeePerZEROStaked = _ZUSDFee.mul(DECIMAL_PRECISION).div(totalZEROStaked);\n }\n\n F_ZUSD = F_ZUSD.add(ZUSDFeePerZEROStaked);\n emit F_ZUSDUpdated(F_ZUSD);\n }\n\n // --- Pending reward functions ---\n\n function getPendingETHGain(address _user) external view override returns (uint256) {\n return _getPendingETHGain(_user);\n }\n\n function _getPendingETHGain(address _user) internal view returns (uint256) {\n uint256 F_ETH_Snapshot = snapshots[_user].F_ETH_Snapshot;\n uint256 ETHGain = stakes[_user].mul(F_ETH.sub(F_ETH_Snapshot)).div(DECIMAL_PRECISION);\n return ETHGain;\n }\n\n function getPendingZUSDGain(address _user) external view override returns (uint256) {\n return _getPendingZUSDGain(_user);\n }\n\n function _getPendingZUSDGain(address _user) internal view returns (uint256) {\n uint256 F_ZUSD_Snapshot = snapshots[_user].F_ZUSD_Snapshot;\n uint256 ZUSDGain = stakes[_user].mul(F_ZUSD.sub(F_ZUSD_Snapshot)).div(DECIMAL_PRECISION);\n return ZUSDGain;\n }\n\n // --- Internal helper functions ---\n\n function _updateUserSnapshots(address _user) internal {\n snapshots[_user].F_ETH_Snapshot = F_ETH;\n snapshots[_user].F_ZUSD_Snapshot = F_ZUSD;\n emit StakerSnapshotsUpdated(_user, F_ETH, F_ZUSD);\n }\n\n function _sendETHGainToUser(uint256 ETHGain) internal {\n emit EtherSent(msg.sender, ETHGain);\n (bool success, ) = msg.sender.call{value: ETHGain}(\"\");\n require(success, \"ZEROStaking: Failed to send accumulated ETHGain\");\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsFeeDistributor() internal view {\n require(msg.sender == feeDistributorAddress, \"ZEROStaking: caller is not FeeDistributor\");\n }\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"ZEROStaking: caller is not ActivePool\");\n }\n\n function _requireUserHasStake(uint256 currentStake) internal pure {\n require(currentStake > 0, \"ZEROStaking: User must have a non-zero stake\");\n }\n\n function _requireNonZeroAmount(uint256 _amount) internal pure {\n require(_amount > 0, \"ZEROStaking: Amount must be non-zero\");\n }\n\n receive() external payable {\n _requireCallerIsFeeDistributor();\n }\n}\n" + }, + "contracts/ZERO/ZEROStakingStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Interfaces/IZEROToken.sol\";\nimport \"../Interfaces/IZUSDToken.sol\";\n\ncontract ZEROStakingStorage is Ownable {\n // --- Data ---\n string constant public NAME = \"ZEROStaking\";\n\n mapping( address => uint) public stakes;\n uint public totalZEROStaked;\n\n uint public F_ETH; // Running sum of ETH fees per-ZERO-staked\n uint public F_ZUSD; // Running sum of ZERO fees per-ZERO-staked\n\n // User snapshots of F_ETH and F_ZUSD, taken at the point at which their latest deposit was made\n mapping (address => Snapshot) public snapshots; \n\n struct Snapshot {\n uint F_ETH_Snapshot;\n uint F_ZUSD_Snapshot;\n }\n \n IZEROToken public zeroToken;\n IZUSDToken public zusdToken;\n\n address public feeDistributorAddress;\n address public activePoolAddress;\n\n}\n" + }, + "contracts/ZERO/ZEROToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Interfaces/IZEROToken.sol\";\nimport \"./ZEROTokenStorage.sol\";\n\n/**\n * Based upon OpenZeppelin's ERC20 contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol\n *\n * and their EIP2612 (ERC20Permit / ERC712) functionality:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\n *\n *\n * --- Functionality added specific to the ZEROToken ---\n *\n * 1) Transfer protection: blacklist of addresses that are invalid recipients (i.e. core Zero contracts) in external\n * transfer() and transferFrom() calls. The purpose is to protect users from losing tokens by mistakenly sending ZERO directly to a Zero\n * core contract, when they should rather call the right function.\n *\n * 2) sendToZEROStaking(): callable only by Zero core contracts, which move ZERO tokens from user -> ZEROStaking contract.\n *\n */\n\ncontract ZEROToken is ZEROTokenStorage, CheckContract, IZEROToken {\n using SafeMath for uint256;\n\n // --- Functions ---\n\n function initialize(\n address _zeroStakingAddress,\n address _marketMakerAddress,\n address _presaleAddress\n ) public initializer {\n // checkContract(_marketMakerAddress);\n // checkContract(_presaleAddress);\n\n deploymentStartTime = block.timestamp;\n\n zeroStakingAddress = _zeroStakingAddress;\n marketMakerAddress = _marketMakerAddress;\n presale = IBalanceRedirectPresale(_presaleAddress);\n\n bytes32 hashedName = keccak256(bytes(_NAME));\n bytes32 hashedVersion = keccak256(bytes(_VERSION));\n\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = _chainID();\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(_TYPE_HASH, hashedName, hashedVersion);\n }\n\n // --- External functions ---\n\n /// @notice Generates `amount` tokens that are assigned to `account`\n /// @param account The address that will be assigned the new tokens\n /// @param amount The quantity of tokens generated\n function mint(address account, uint256 amount) external {\n require(\n msg.sender == marketMakerAddress || msg.sender == address(presale),\n \"Invalid caller\"\n );\n _mint(account, amount);\n }\n\n /// @notice Burns `amount` tokens from `account`\n /// @param account The address that will lose the tokens\n /// @param amount The quantity of tokens to burn\n function burn(address account, uint256 amount) external {\n require(msg.sender == marketMakerAddress, \"Invalid caller\");\n _burn(account, amount);\n }\n\n function totalSupply() external view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) external view override returns (uint256) {\n return _balances[account];\n }\n\n function getDeploymentStartTime() external view override returns (uint256) {\n return deploymentStartTime;\n }\n\n function transfer(address recipient, uint256 amount) external override returns (bool) {\n _requireValidRecipient(recipient);\n\n // Otherwise, standard transfer functionality\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) external view override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) external override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external override returns (bool) {\n _requireValidRecipient(recipient);\n\n _transfer(sender, recipient, amount);\n _approve(\n sender,\n msg.sender,\n _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\")\n );\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue)\n external\n override\n returns (bool)\n {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue)\n external\n override\n returns (bool)\n {\n _approve(\n msg.sender,\n spender,\n _allowances[msg.sender][spender].sub(\n subtractedValue,\n \"ERC20: decreased allowance below zero\"\n )\n );\n return true;\n }\n\n function sendToZEROStaking(address _sender, uint256 _amount) external override {\n _requireCallerIsZEROStaking();\n _transfer(_sender, zeroStakingAddress, _amount);\n }\n\n // --- EIP 2612 functionality ---\n\n function domainSeparator() public view override returns (bytes32) {\n if (_chainID() == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external override {\n require(deadline >= now, \"ZERO: expired deadline\");\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n domainSeparator(),\n keccak256(\n abi.encode(_PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner]++, deadline)\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress == owner, \"ZERO: invalid signature\");\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) external view override returns (uint256) {\n // FOR EIP 2612\n return _nonces[owner];\n }\n\n // --- Internal operations ---\n\n function _chainID() private pure returns (uint256 chainID) {\n assembly {\n chainID := chainid()\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 name,\n bytes32 version\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, name, version, _chainID(), address(this)));\n }\n\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal {\n return; // disable the func call - ZEROToken is not used in beta\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n require(presale.isClosed(), \"Presale is not over yet\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account, uint256 amount) internal {\n return; // disable the func call - ZEROToken is not used in beta\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n function _burn(address account, uint256 amount) internal {\n return; // disable the func call - ZEROToken is not used in beta\n require(account != address(0), \"ERC20: mint to the zero address\");\n require(amount <= _balances[account], \"balance too low\");\n\n _totalSupply = _totalSupply.sub(amount);\n _balances[account] = _balances[account].sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n // --- Helper functions ---\n\n // --- 'require' functions ---\n\n function _requireValidRecipient(address _recipient) internal view {\n require(\n _recipient != address(0) && _recipient != address(this),\n \"ZERO: Cannot transfer tokens directly to the ZERO token contract or the zero address\"\n );\n }\n\n function _requireCallerIsZEROStaking() internal view {\n require(\n msg.sender == zeroStakingAddress,\n \"ZEROToken: caller must be the ZEROStaking contract\"\n );\n }\n\n // --- Optional functions ---\n\n function name() external view override returns (string memory) {\n return _NAME;\n }\n\n function symbol() external view override returns (string memory) {\n return _SYMBOL;\n }\n\n function decimals() external view override returns (uint8) {\n return _DECIMALS;\n }\n\n function version() external view override returns (string memory) {\n return _VERSION;\n }\n\n function permitTypeHash() external view override returns (bytes32) {\n return _PERMIT_TYPEHASH;\n }\n}\n" + }, + "contracts/ZERO/ZEROTokenStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IBalanceRedirectPresale.sol\";\nimport \"../Dependencies/Initializable.sol\";\n\ncontract ZEROTokenStorage is Initializable {\n // --- ERC20 Data ---\n\n string constant internal _NAME = \"ZERO\";\n string constant internal _SYMBOL = \"ZERO\";\n string constant internal _VERSION = \"1\";\n uint8 constant internal _DECIMALS = 18;\n\n mapping (address => uint256) internal _balances;\n mapping (address => mapping (address => uint256)) internal _allowances;\n uint internal _totalSupply;\n\n // --- EIP 2612 Data ---\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 internal constant _PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n // keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n bytes32 internal constant _TYPE_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 internal _CACHED_DOMAIN_SEPARATOR;\n uint256 internal _CACHED_CHAIN_ID;\n\n bytes32 internal _HASHED_NAME;\n bytes32 internal _HASHED_VERSION;\n \n mapping (address => uint256) internal _nonces;\n\n // --- ZEROToken specific data ---\n\n uint public constant ONE_YEAR_IN_SECONDS = 31536000; // 60 * 60 * 24 * 365\n\n // uint for use with SafeMath\n uint internal constant _1_MILLION = 1e24; // 1e6 * 1e18 = 1e24\n\n uint internal deploymentStartTime;\n\n address public zeroStakingAddress;\n address public marketMakerAddress;\n IBalanceRedirectPresale public presale;\n\n}\n" + }, + "contracts/ZUSDToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./ZUSDTokenStorage.sol\";\n\n/**\n *\n * Based upon OpenZeppelin's ERC20 contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol\n *\n * and their EIP2612 (ERC20Permit / ERC712) functionality:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\n *\n *\n * --- Functionality added specific to the ZUSDToken ---\n *\n * 1) Transfer protection: blacklist of addresses that are invalid recipients (i.e. core Zero contracts) in external\n * transfer() and transferFrom() calls. The purpose is to protect users from losing tokens by mistakenly sending ZUSD directly to a Zero\n * core contract, when they should rather call the right function.\n *\n * 2) sendToPool() and returnFromPool(): functions callable only Zero core contracts, which move ZUSD tokens between Zero <-> user.\n */\n\ncontract ZUSDToken is ZUSDTokenStorage, CheckContract, IZUSDToken, Ownable {\n using SafeMath for uint256;\n // --- Events ---\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event StabilityPoolAddressChanged(address _newStabilityPoolAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n\n function initialize(\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) public virtual initializer onlyOwner {\n _initialize(_troveManagerAddress, _stabilityPoolAddress, _borrowerOperationsAddress);\n }\n\n function _initialize(\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) internal {\n checkContract(_troveManagerAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_borrowerOperationsAddress);\n\n troveManagerAddress = _troveManagerAddress;\n emit TroveManagerAddressChanged(_troveManagerAddress);\n\n stabilityPoolAddress = _stabilityPoolAddress;\n emit StabilityPoolAddressChanged(_stabilityPoolAddress);\n\n borrowerOperationsAddress = _borrowerOperationsAddress;\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n\n bytes32 hashedName = keccak256(bytes(_NAME));\n bytes32 hashedVersion = keccak256(bytes(_VERSION));\n\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = _chainID();\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(_TYPE_HASH, hashedName, hashedVersion);\n }\n\n // --- Functions for intra-Zero calls ---\n\n function mint(address _account, uint256 _amount) external override {\n _requireCallerIsBorrowerOperations();\n _mint(_account, _amount);\n }\n\n function burn(address _account, uint256 _amount) external override {\n _requireCallerIsBOorTroveMorSP();\n _burn(_account, _amount);\n }\n\n function sendToPool(\n address _sender,\n address _poolAddress,\n uint256 _amount\n ) external override {\n _requireCallerIsStabilityPool();\n _transfer(_sender, _poolAddress, _amount);\n }\n\n function returnFromPool(\n address _poolAddress,\n address _receiver,\n uint256 _amount\n ) external override {\n _requireCallerIsTroveMorSP();\n _transfer(_poolAddress, _receiver, _amount);\n }\n\n // --- External functions ---\n\n function totalSupply() external view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) external view override returns (uint256) {\n return _balances[account];\n }\n\n function transfer(address recipient, uint256 amount) external override returns (bool) {\n _requireValidRecipient(recipient);\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) external view override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) external override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external override returns (bool) {\n _requireValidRecipient(recipient);\n _transfer(sender, recipient, amount);\n _approve(\n sender,\n msg.sender,\n _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\")\n );\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue)\n external\n override\n returns (bool)\n {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue)\n external\n override\n returns (bool)\n {\n _approve(\n msg.sender,\n spender,\n _allowances[msg.sender][spender].sub(\n subtractedValue,\n \"ERC20: decreased allowance below zero\"\n )\n );\n return true;\n }\n\n // --- EIP 2612 Functionality ---\n\n function domainSeparator() public view override returns (bytes32) {\n if (_chainID() == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external override {\n require(deadline >= now, \"ZUSD: expired deadline\");\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n domainSeparator(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n _nonces[owner]++,\n deadline\n )\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress == owner, \"ZUSD: invalid signature\");\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) external view override returns (uint256) {\n // FOR EIP 2612\n return _nonces[owner];\n }\n\n // --- Internal operations ---\n\n function _chainID() private pure returns (uint256 chainID) {\n assembly {\n chainID := chainid()\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 name,\n bytes32 version\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, name, version, _chainID(), address(this)));\n }\n\n // --- Internal operations ---\n // Warning: sanity checks (for sender and recipient) should have been done before calling these internal functions\n\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal {\n assert(sender != address(0));\n assert(recipient != address(0));\n\n _balances[sender] = _balances[sender].sub(\n amount,\n \"ERC20: transfer amount exceeds balance\"\n );\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account, uint256 amount) internal {\n assert(account != address(0));\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n function _burn(address account, uint256 amount) internal {\n assert(account != address(0));\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal {\n assert(owner != address(0));\n assert(spender != address(0));\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n // --- 'require' functions ---\n\n function _requireValidRecipient(address _recipient) internal view {\n require(\n _recipient != address(0) && _recipient != address(this),\n \"ZUSD: Cannot transfer tokens directly to the ZUSD token contract or the zero address\"\n );\n }\n\n function _requireCallerIsBorrowerOperations() internal view {\n require(\n msg.sender == borrowerOperationsAddress,\n \"ZUSDToken: Caller is not BorrowerOperations\"\n );\n }\n\n function _requireCallerIsBOorTroveMorSP() internal view {\n require(\n msg.sender == borrowerOperationsAddress ||\n msg.sender == troveManagerAddress ||\n msg.sender == stabilityPoolAddress,\n \"ZUSD: Caller is neither BorrowerOperations nor TroveManager nor StabilityPool\"\n );\n }\n\n function _requireCallerIsStabilityPool() internal view {\n require(msg.sender == stabilityPoolAddress, \"ZUSD: Caller is not the StabilityPool\");\n }\n\n function _requireCallerIsTroveMorSP() internal view {\n require(\n msg.sender == troveManagerAddress || msg.sender == stabilityPoolAddress,\n \"ZUSD: Caller is neither TroveManager nor StabilityPool\"\n );\n }\n\n // --- Optional functions ---\n\n function name() external view override returns (string memory) {\n return _NAME;\n }\n\n function symbol() external view override returns (string memory) {\n return _SYMBOL;\n }\n\n function decimals() external view override returns (uint8) {\n return _DECIMALS;\n }\n\n function version() external view override returns (string memory) {\n return _VERSION;\n }\n\n function permitTypeHash() external view override returns (bytes32) {\n return _PERMIT_TYPEHASH;\n }\n}\n" + }, + "contracts/ZUSDTokenStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Dependencies/Initializable.sol\";\n\ncontract ZUSDTokenStorage is Initializable {\n uint256 internal _totalSupply;\n string internal constant _NAME = \"ZUSD Stablecoin\";\n string internal constant _SYMBOL = \"ZUSD\";\n string internal constant _VERSION = \"1\";\n uint8 internal constant _DECIMALS = 18;\n\n // --- Data for EIP2612 ---\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 internal constant _PERMIT_TYPEHASH =\n 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n // keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n bytes32 internal constant _TYPE_HASH =\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n // Cache the domain separator, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 internal _CACHED_DOMAIN_SEPARATOR;\n uint256 internal _CACHED_CHAIN_ID;\n\n bytes32 internal _HASHED_NAME;\n bytes32 internal _HASHED_VERSION;\n\n mapping(address => uint256) internal _nonces;\n\n // User data for ZUSD token\n mapping(address => uint256) internal _balances;\n mapping(address => mapping(address => uint256)) internal _allowances;\n\n // --- Addresses ---\n address internal troveManagerAddress;\n address internal stabilityPoolAddress;\n address internal borrowerOperationsAddress;\n}\n" + }, + "hardhat/console.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >= 0.4.22 <0.9.0;\n\nlibrary console {\n\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n\tfunction _sendLogPayload(bytes memory payload) private view {\n\t\tuint256 payloadLength = payload.length;\n\t\taddress consoleAddress = CONSOLE_ADDRESS;\n\t\tassembly {\n\t\t\tlet payloadStart := add(payload, 32)\n\t\t\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n\t\t}\n\t}\n\n\tfunction log() internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log()\"));\n\t}\n\n\tfunction logInt(int256 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n\t}\n\n\tfunction logUint(uint256 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n\t}\n\n\tfunction logString(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction logBool(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction logAddress(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction logBytes(bytes memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n\t}\n\n\tfunction logBytes1(bytes1 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n\t}\n\n\tfunction logBytes2(bytes2 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n\t}\n\n\tfunction logBytes3(bytes3 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n\t}\n\n\tfunction logBytes4(bytes4 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n\t}\n\n\tfunction logBytes5(bytes5 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n\t}\n\n\tfunction logBytes6(bytes6 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n\t}\n\n\tfunction logBytes7(bytes7 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n\t}\n\n\tfunction logBytes8(bytes8 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n\t}\n\n\tfunction logBytes9(bytes9 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n\t}\n\n\tfunction logBytes10(bytes10 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n\t}\n\n\tfunction logBytes11(bytes11 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n\t}\n\n\tfunction logBytes12(bytes12 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n\t}\n\n\tfunction logBytes13(bytes13 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n\t}\n\n\tfunction logBytes14(bytes14 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n\t}\n\n\tfunction logBytes15(bytes15 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n\t}\n\n\tfunction logBytes16(bytes16 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n\t}\n\n\tfunction logBytes17(bytes17 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n\t}\n\n\tfunction logBytes18(bytes18 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n\t}\n\n\tfunction logBytes19(bytes19 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n\t}\n\n\tfunction logBytes20(bytes20 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n\t}\n\n\tfunction logBytes21(bytes21 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n\t}\n\n\tfunction logBytes22(bytes22 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n\t}\n\n\tfunction logBytes23(bytes23 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n\t}\n\n\tfunction logBytes24(bytes24 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n\t}\n\n\tfunction logBytes25(bytes25 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n\t}\n\n\tfunction logBytes26(bytes26 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n\t}\n\n\tfunction logBytes27(bytes27 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n\t}\n\n\tfunction logBytes28(bytes28 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n\t}\n\n\tfunction logBytes29(bytes29 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n\t}\n\n\tfunction logBytes30(bytes30 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n\t}\n\n\tfunction logBytes31(bytes31 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n\t}\n\n\tfunction logBytes32(bytes32 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n\t}\n\n\tfunction log(uint256 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n\t}\n\n\tfunction log(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction log(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction log(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n\t}\n\n\tfunction log(address p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256)\", p0, p1));\n\t}\n\n\tfunction log(address p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n\t}\n\n\tfunction log(address p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n\t}\n\n\tfunction log(address p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/a74723cb677f46af6277664d6e1e3f48.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/a74723cb677f46af6277664d6e1e3f48.json new file mode 100644 index 00000000..7e752e69 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/a74723cb677f46af6277664d6e1e3f48.json @@ -0,0 +1,376 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n // Check the signature length\n if (signature.length != 65) {\n revert(\"ECDSA: invalid signature length\");\n }\n\n // Divide the signature in r, s and v variables\n bytes32 r;\n bytes32 s;\n uint8 v;\n\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n\n return recover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover-bytes32-bytes-} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, \"ECDSA: invalid signature 's' value\");\n require(v == 27 || v == 28, \"ECDSA: invalid signature 'v' value\");\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n require(signer != address(0), \"ECDSA: invalid signature\");\n\n return signer;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * replicates the behavior of the\n * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]\n * JSON-RPC method.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n}\n" + }, + "@openzeppelin/contracts/drafts/EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) internal {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = _getChainId();\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view virtual returns (bytes32) {\n if (_getChainId() == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(bytes32 typeHash, bytes32 name, bytes32 version) private view returns (bytes32) {\n return keccak256(\n abi.encode(\n typeHash,\n name,\n version,\n _getChainId(),\n address(this)\n )\n );\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", _domainSeparatorV4(), structHash));\n }\n\n function _getChainId() private view returns (uint256 chainId) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n // solhint-disable-next-line no-inline-assembly\n assembly {\n chainId := chainid()\n }\n }\n}\n" + }, + "@openzeppelin/contracts/drafts/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.5 <0.8.0;\n\nimport \"../token/ERC20/ERC20.sol\";\nimport \"./IERC20Permit.sol\";\nimport \"../cryptography/ECDSA.sol\";\nimport \"../utils/Counters.sol\";\nimport \"./EIP712.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping (address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private immutable _PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) internal EIP712(name, \"1\") {\n }\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\n // solhint-disable-next-line not-rely-on-time\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n _nonces[owner].current(),\n deadline\n )\n );\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _nonces[owner].increment();\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n}\n" + }, + "@openzeppelin/contracts/drafts/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens,\n * given `owner`'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for `permit`, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a, \"SafeMath: subtraction overflow\");\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: modulo by zero\");\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name_, string memory symbol_) public {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n * called.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../math/SafeMath.sol\";\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\n * directly accessed.\n */\nlibrary Counters {\n using SafeMath for uint256;\n\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n" + }, + "contracts/ActivePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IActivePool.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\n\nimport \"./ActivePoolStorage.sol\";\n\n/**\n * @title Active Pool\n * @notice The Active Pool holds the ETH collateral and ZUSD debt (but not ZUSD tokens) for all active troves.\n *\n * When a trove is liquidated, it's ETH and ZUSD debt are transferred from the Active Pool, to either the\n * Stability Pool, the Default Pool, or both, depending on the liquidation conditions.\n */\ncontract ActivePool is CheckContract, IActivePool, ActivePoolStorage {\n using SafeMath for uint256;\n // --- Events ---\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolZUSDDebtUpdated(uint256 _ZUSDDebt);\n event ActivePoolETHBalanceUpdated(uint256 _ETH);\n\n // --- Contract setters ---\n /// @notice initializer function that sets required addresses\n /// @dev Checks addresses are contracts. Only callable by contract owner.\n /// @param _borrowerOperationsAddress BorrowerOperations contract address\n /// @param _troveManagerAddress TroveManager contract address\n /// @param _stabilityPoolAddress StabilityPool contract address\n /// @param _defaultPoolAddress DefaultPool contract address\n function setAddresses(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _defaultPoolAddress\n ) external onlyOwner {\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_defaultPoolAddress);\n\n borrowerOperationsAddress = _borrowerOperationsAddress;\n troveManagerAddress = _troveManagerAddress;\n stabilityPoolAddress = _stabilityPoolAddress;\n defaultPoolAddress = _defaultPoolAddress;\n\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit StabilityPoolAddressChanged(_stabilityPoolAddress);\n emit DefaultPoolAddressChanged(_defaultPoolAddress);\n }\n\n // --- Getters for public variables. Required by IPool interface ---\n\n /// @notice Not necessarily equal to the the contract's raw ETH balance - ether can be forcibly sent to contracts.\n /// @return the ETH state variable.\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n /// @return the ZUSD debt state variable\n function getZUSDDebt() external view override returns (uint256) {\n return ZUSDDebt;\n }\n\n // --- Pool functionality ---\n\n /// @notice Send ETH amount to given account. Updates ActivePool balance. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _account account to receive the ETH amount\n /// @param _amount ETH amount to send\n function sendETH(address _account, uint256 _amount) external override {\n _requireCallerIsBOorTroveMorSP();\n ETH = ETH.sub(_amount);\n emit ActivePoolETHBalanceUpdated(ETH);\n emit EtherSent(_account, _amount);\n\n (bool success, ) = _account.call{ value: _amount }(\"\");\n require(success, \"ActivePool: sending ETH failed\");\n }\n\n /// @notice Increases ZUSD debt of the active pool. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _amount ZUSD amount to add to the pool debt\n function increaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsBOorTroveM();\n ZUSDDebt = ZUSDDebt.add(_amount);\n ActivePoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n /// @notice Decreases ZUSD debt of the active pool. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _amount ZUSD amount to sub to the pool debt\n function decreaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsBOorTroveMorSP();\n ZUSDDebt = ZUSDDebt.sub(_amount);\n ActivePoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsBorrowerOperationsOrDefaultPool() internal view {\n require(\n msg.sender == borrowerOperationsAddress || msg.sender == defaultPoolAddress,\n \"ActivePool: Caller is neither BO nor Default Pool\"\n );\n }\n\n function _requireCallerIsBOorTroveMorSP() internal view {\n require(\n msg.sender == borrowerOperationsAddress ||\n msg.sender == troveManagerAddress ||\n msg.sender == stabilityPoolAddress,\n \"ActivePool: Caller is neither BorrowerOperations nor TroveManager nor StabilityPool\"\n );\n }\n\n function _requireCallerIsBOorTroveM() internal view {\n require(\n msg.sender == borrowerOperationsAddress || msg.sender == troveManagerAddress,\n \"ActivePool: Caller is neither BorrowerOperations nor TroveManager\"\n );\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsBorrowerOperationsOrDefaultPool();\n ETH = ETH.add(msg.value);\n emit ActivePoolETHBalanceUpdated(ETH);\n }\n}\n" + }, + "contracts/ActivePoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Dependencies/Ownable.sol\";\n\n/**\n * @title Active Pool Storage\n * @dev Stores Active Pool required addresses and internal ETH and ZUSD debt states\n * Extends Ownable\n */\ncontract ActivePoolStorage is Ownable {\n string public constant NAME = \"ActivePool\";\n\n address public borrowerOperationsAddress;\n address public troveManagerAddress;\n address public stabilityPoolAddress;\n address public defaultPoolAddress;\n uint256 internal ETH; // deposited ether tracker\n uint256 internal ZUSDDebt;\n}\n" + }, + "contracts/BorrowerOperations.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./BorrowerOperationsStorage.sol\";\nimport \"./Dependencies/Mynt/MyntLib.sol\";\n\ncontract BorrowerOperations is\n LiquityBase,\n BorrowerOperationsStorage,\n CheckContract,\n IBorrowerOperations\n{\n /* --- Variable container structs ---\n\n Used to hold, return and assign variables inside a function, in order to avoid the error:\n \"CompilerError: Stack too deep\". */\n\n struct LocalVariables_adjustTrove {\n uint256 price;\n uint256 collChange;\n uint256 netDebtChange;\n bool isCollIncrease;\n uint256 debt;\n uint256 coll;\n uint256 oldICR;\n uint256 newICR;\n uint256 newTCR;\n uint256 ZUSDFee;\n uint256 newDebt;\n uint256 newColl;\n uint256 stake;\n uint256 newNICR;\n bool isRecoveryMode;\n }\n\n struct LocalVariables_openTrove {\n uint256 price;\n uint256 ZUSDFee;\n uint256 netDebt;\n uint256 compositeDebt;\n uint256 ICR;\n uint256 NICR;\n uint256 stake;\n uint256 arrayIndex;\n }\n\n struct ContractsCache {\n ITroveManager troveManager;\n IActivePool activePool;\n IZUSDToken zusdToken;\n }\n\n enum BorrowerOperation {\n openTrove,\n closeTrove,\n adjustTrove\n }\n\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n event MassetManagerAddressChanged(address _massetManagerAddress);\n\n event TroveCreated(address indexed _borrower, uint256 arrayIndex);\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 stake,\n BorrowerOperation operation\n );\n event ZUSDBorrowingFeePaid(address indexed _borrower, uint256 _ZUSDFee);\n\n // --- Dependency setters ---\n\n function setAddresses(\n address _feeDistributorAddress,\n address _liquityBaseParamsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _defaultPoolAddress,\n address _stabilityPoolAddress,\n address _gasPoolAddress,\n address _collSurplusPoolAddress,\n address _priceFeedAddress,\n address _sortedTrovesAddress,\n address _zusdTokenAddress,\n address _zeroStakingAddress\n ) external override onlyOwner {\n // This makes impossible to open a trove with zero withdrawn ZUSD\n assert(MIN_NET_DEBT > 0);\n\n checkContract(_feeDistributorAddress);\n checkContract(_liquityBaseParamsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n checkContract(_defaultPoolAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_gasPoolAddress);\n checkContract(_collSurplusPoolAddress);\n checkContract(_priceFeedAddress);\n checkContract(_sortedTrovesAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_zeroStakingAddress);\n\n feeDistributor = IFeeDistributor(_feeDistributorAddress);\n liquityBaseParams = ILiquityBaseParams(_liquityBaseParamsAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n activePool = IActivePool(_activePoolAddress);\n defaultPool = IDefaultPool(_defaultPoolAddress);\n stabilityPoolAddress = _stabilityPoolAddress;\n gasPoolAddress = _gasPoolAddress;\n collSurplusPool = ICollSurplusPool(_collSurplusPoolAddress);\n priceFeed = IPriceFeed(_priceFeedAddress);\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n zeroStakingAddress = _zeroStakingAddress;\n zeroStaking = IZEROStaking(_zeroStakingAddress);\n\n emit FeeDistributorAddressChanged(_feeDistributorAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n emit DefaultPoolAddressChanged(_defaultPoolAddress);\n emit StabilityPoolAddressChanged(_stabilityPoolAddress);\n emit GasPoolAddressChanged(_gasPoolAddress);\n emit CollSurplusPoolAddressChanged(_collSurplusPoolAddress);\n emit PriceFeedAddressChanged(_priceFeedAddress);\n emit SortedTrovesAddressChanged(_sortedTrovesAddress);\n emit ZUSDTokenAddressChanged(_zusdTokenAddress);\n emit ZEROStakingAddressChanged(_zeroStakingAddress);\n }\n\n function setMassetManagerAddress(address _massetManagerAddress) external onlyOwner {\n massetManager = IMassetManager(_massetManagerAddress);\n emit MassetManagerAddressChanged(_massetManagerAddress);\n }\n\n function openTrove(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n _openTrove(_maxFeePercentage, _ZUSDAmount, _upperHint, _lowerHint, msg.sender);\n }\n\n function openNueTrove(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n require(address(massetManager) != address(0), \"Masset address not set\");\n\n _openTrove(_maxFeePercentage, _ZUSDAmount, _upperHint, _lowerHint, address(this));\n require(\n zusdToken.approve(address(massetManager), _ZUSDAmount),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n massetManager.mintTo(address(zusdToken), _ZUSDAmount, msg.sender);\n }\n\n // --- Borrower Trove Operations ---\n function _openTrove(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint,\n address _tokensRecipient\n ) internal {\n ContractsCache memory contractsCache = ContractsCache(troveManager, activePool, zusdToken);\n LocalVariables_openTrove memory vars;\n\n vars.price = priceFeed.fetchPrice();\n bool isRecoveryMode = _checkRecoveryMode(vars.price);\n\n _requireValidMaxFeePercentage(_maxFeePercentage, isRecoveryMode);\n _requireTroveisNotActive(contractsCache.troveManager, msg.sender);\n\n vars.ZUSDFee;\n vars.netDebt = _ZUSDAmount;\n\n if (!isRecoveryMode) {\n vars.ZUSDFee = _triggerBorrowingFee(\n contractsCache.troveManager,\n contractsCache.zusdToken,\n _ZUSDAmount,\n _maxFeePercentage\n );\n vars.netDebt = vars.netDebt.add(vars.ZUSDFee);\n }\n _requireAtLeastMinNetDebt(vars.netDebt);\n\n // ICR is based on the composite debt, i.e. the requested ZUSD amount + ZUSD borrowing fee + ZUSD gas comp.\n vars.compositeDebt = _getCompositeDebt(vars.netDebt);\n assert(vars.compositeDebt > 0);\n\n vars.ICR = LiquityMath._computeCR(msg.value, vars.compositeDebt, vars.price);\n vars.NICR = LiquityMath._computeNominalCR(msg.value, vars.compositeDebt);\n\n if (isRecoveryMode) {\n _requireICRisAboveCCR(vars.ICR);\n } else {\n _requireICRisAboveMCR(vars.ICR);\n uint256 newTCR = _getNewTCRFromTroveChange(\n msg.value,\n true,\n vars.compositeDebt,\n true,\n vars.price\n ); // bools: coll increase, debt increase\n _requireNewTCRisAboveCCR(newTCR);\n }\n\n // Set the trove struct's properties\n contractsCache.troveManager.setTroveStatus(msg.sender, 1);\n contractsCache.troveManager.increaseTroveColl(msg.sender, msg.value);\n contractsCache.troveManager.increaseTroveDebt(msg.sender, vars.compositeDebt);\n\n contractsCache.troveManager.updateTroveRewardSnapshots(msg.sender);\n vars.stake = contractsCache.troveManager.updateStakeAndTotalStakes(msg.sender);\n\n sortedTroves.insert(msg.sender, vars.NICR, _upperHint, _lowerHint);\n vars.arrayIndex = contractsCache.troveManager.addTroveOwnerToArray(msg.sender);\n emit TroveCreated(msg.sender, vars.arrayIndex);\n\n // Move the ether to the Active Pool, and mint the ZUSDAmount to the borrower\n _activePoolAddColl(contractsCache.activePool, msg.value);\n _mintZusdAndIncreaseActivePoolDebt(\n contractsCache.activePool,\n contractsCache.zusdToken,\n _tokensRecipient,\n _ZUSDAmount,\n vars.netDebt\n );\n // Move the ZUSD gas compensation to the Gas Pool\n _mintZusdAndIncreaseActivePoolDebt(\n contractsCache.activePool,\n contractsCache.zusdToken,\n gasPoolAddress,\n ZUSD_GAS_COMPENSATION,\n ZUSD_GAS_COMPENSATION\n );\n\n emit TroveUpdated(\n msg.sender,\n vars.compositeDebt,\n msg.value,\n vars.stake,\n BorrowerOperation.openTrove\n );\n emit ZUSDBorrowingFeePaid(msg.sender, vars.ZUSDFee);\n }\n\n /// Send ETH as collateral to a trove\n function addColl(address _upperHint, address _lowerHint) external payable override {\n _adjustTrove(msg.sender, 0, 0, false, _upperHint, _lowerHint, 0);\n }\n\n /// Send ETH as collateral to a trove. Called by only the Stability Pool.\n function moveETHGainToTrove(\n address _borrower,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n _requireCallerIsStabilityPool();\n _adjustTrove(_borrower, 0, 0, false, _upperHint, _lowerHint, 0);\n }\n\n /// Withdraw ETH collateral from a trove\n function withdrawColl(\n uint256 _collWithdrawal,\n address _upperHint,\n address _lowerHint\n ) external override {\n _adjustTrove(msg.sender, _collWithdrawal, 0, false, _upperHint, _lowerHint, 0);\n }\n\n /// Withdraw ZUSD tokens from a trove: mint new ZUSD tokens to the owner, and increase the trove's debt accordingly\n function withdrawZUSD(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external override {\n _adjustTrove(msg.sender, 0, _ZUSDAmount, true, _upperHint, _lowerHint, _maxFeePercentage);\n }\n\n /// Borrow (withdraw) ZUSD tokens from a trove: mint new ZUSD tokens to the owner and convert it to DLLR in one transaction\n /// Zero Line of Credit owner can borrow a specified amount of ZUSD and convert it to DLLR via Sovryn Mynt\n ///@return DLLR amount minted\n function withdrawZusdAndConvertToDLLR(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external override returns (uint256) {\n address thisAddress = address(this);\n uint256 balanceBefore = zusdToken.balanceOf(thisAddress);\n\n _withdrawZusdTo(\n msg.sender,\n thisAddress,\n _ZUSDAmount,\n _upperHint,\n _lowerHint,\n _maxFeePercentage\n );\n\n require(\n zusdToken.balanceOf(thisAddress) == balanceBefore.add(_ZUSDAmount),\n \"ZUSD is not borrowed correctly\"\n );\n require(\n zusdToken.approve(address(massetManager), _ZUSDAmount),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n return massetManager.mintTo(address(zusdToken), _ZUSDAmount, msg.sender);\n }\n\n /// Repay ZUSD tokens to a Trove: Burn the repaid ZUSD tokens, and reduce the trove's debt accordingly\n function repayZUSD(\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external override {\n _adjustTrove(msg.sender, 0, _ZUSDAmount, false, _upperHint, _lowerHint, 0);\n }\n\n /// Repay ZUSD tokens to a Trove by DLLR: convert DLLR to ZUSD tokens, and then reduce the trove's debt accordingly\n function repayZusdFromDLLR(\n uint256 _dllrAmount,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external override {\n _adjustNueTrove(0, 0, _dllrAmount, false, _upperHint, _lowerHint, _permitParams);\n }\n\n function adjustTrove(\n uint256 _maxFeePercentage,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n _adjustTrove(\n msg.sender,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFeePercentage\n );\n }\n\n // in case of _isDebtIncrease = false MassetManager contract must have an approval of NUE tokens\n function adjustNueTrove(\n uint256 _maxFeePercentage,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external payable override {\n _adjustNueTrove(\n _maxFeePercentage,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _permitParams\n );\n }\n\n // in case of _isDebtIncrease = false Masset Manager contract must have an approval of NUE tokens\n function _adjustNueTrove(\n uint256 _maxFeePercentage,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) internal {\n require(address(massetManager) != address(0), \"Masset address not set\");\n\n if (!_isDebtIncrease && _ZUSDChange > 0) {\n MyntLib.redeemZusdFromDllrWithPermit(\n massetManager,\n _ZUSDChange,\n address(zusdToken),\n _permitParams\n );\n }\n _adjustSenderTrove(\n msg.sender,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFeePercentage,\n address(this)\n );\n if (_isDebtIncrease && _ZUSDChange > 0) {\n require(\n zusdToken.approve(address(massetManager), _ZUSDChange),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n massetManager.mintTo(address(zusdToken), _ZUSDChange, msg.sender);\n }\n }\n\n function _adjustTrove(\n address _borrower,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n uint256 _maxFeePercentage\n ) internal {\n _adjustSenderTrove(\n _borrower,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFeePercentage,\n msg.sender\n );\n }\n\n // _withdrawZusd: _adjustTrove(msg.sender, 0, _ZUSDAmount, true, _upperHint, _lowerHint, _maxFeePercentage);\n function _withdrawZusdTo(\n address _borrower,\n address _receiver,\n uint256 _ZUSDChange,\n address _upperHint,\n address _lowerHint,\n uint256 _maxFeePercentage\n ) internal {\n _adjustSenderTrove(\n _borrower,\n 0,\n _ZUSDChange,\n true,\n _upperHint,\n _lowerHint,\n _maxFeePercentage,\n _receiver\n );\n }\n\n /**\n * _adjustSenderTrove(): Alongside a debt change, this function can perform either a collateral top-up or a collateral withdrawal.\n *\n * It therefore expects either a positive msg.value, or a positive _collWithdrawal argument.\n *\n * If both are positive, it will revert.\n */\n function _adjustSenderTrove(\n address _borrower,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n uint256 _maxFeePercentage,\n address _tokensRecipient\n ) internal {\n ContractsCache memory contractsCache = ContractsCache(troveManager, activePool, zusdToken);\n LocalVariables_adjustTrove memory vars;\n\n vars.price = priceFeed.fetchPrice();\n vars.isRecoveryMode = _checkRecoveryMode(vars.price);\n\n if (_isDebtIncrease) {\n _requireValidMaxFeePercentage(_maxFeePercentage, vars.isRecoveryMode);\n _requireNonZeroDebtChange(_ZUSDChange);\n }\n _requireSingularCollChange(_collWithdrawal);\n _requireNonZeroAdjustment(_collWithdrawal, _ZUSDChange);\n _requireTroveisActive(contractsCache.troveManager, _borrower);\n\n // Confirm the operation is either a borrower adjusting their own trove, or a pure ETH transfer from the Stability Pool to a trove\n assert(\n msg.sender == _borrower ||\n (msg.sender == stabilityPoolAddress && msg.value > 0 && _ZUSDChange == 0)\n );\n\n contractsCache.troveManager.applyPendingRewards(_borrower);\n\n // Get the collChange based on whether or not ETH was sent in the transaction\n (vars.collChange, vars.isCollIncrease) = _getCollChange(msg.value, _collWithdrawal);\n\n vars.netDebtChange = _ZUSDChange;\n\n // If the adjustment incorporates a debt increase and system is in Normal Mode, then trigger a borrowing fee\n if (_isDebtIncrease && !vars.isRecoveryMode) {\n vars.ZUSDFee = _triggerBorrowingFee(\n contractsCache.troveManager,\n contractsCache.zusdToken,\n _ZUSDChange,\n _maxFeePercentage\n );\n vars.netDebtChange = vars.netDebtChange.add(vars.ZUSDFee); // The raw debt change includes the fee\n }\n\n vars.debt = contractsCache.troveManager.getTroveDebt(_borrower);\n vars.coll = contractsCache.troveManager.getTroveColl(_borrower);\n\n // Get the trove's old ICR before the adjustment, and what its new ICR will be after the adjustment\n vars.oldICR = LiquityMath._computeCR(vars.coll, vars.debt, vars.price);\n vars.newICR = _getNewICRFromTroveChange(\n vars.coll,\n vars.debt,\n vars.collChange,\n vars.isCollIncrease,\n vars.netDebtChange,\n _isDebtIncrease,\n vars.price\n );\n assert(_collWithdrawal <= vars.coll);\n\n // Check the adjustment satisfies all conditions for the current system mode\n _requireValidAdjustmentInCurrentMode(\n vars.isRecoveryMode,\n _collWithdrawal,\n _isDebtIncrease,\n vars\n );\n\n // When the adjustment is a debt repayment, check it's a valid amount and that the caller has enough ZUSD\n if (!_isDebtIncrease && _ZUSDChange > 0) {\n _requireAtLeastMinNetDebt(_getNetDebt(vars.debt).sub(vars.netDebtChange));\n _requireValidZUSDRepayment(vars.debt, vars.netDebtChange);\n _requireSufficientZUSDBalance(contractsCache.zusdToken, _borrower, vars.netDebtChange);\n }\n\n (vars.newColl, vars.newDebt) = _updateTroveFromAdjustment(\n contractsCache.troveManager,\n _borrower,\n vars.collChange,\n vars.isCollIncrease,\n vars.netDebtChange,\n _isDebtIncrease\n );\n vars.stake = contractsCache.troveManager.updateStakeAndTotalStakes(_borrower);\n\n // Re-insert trove in to the sorted list\n vars.newNICR = _getNewNominalICRFromTroveChange(\n vars.coll,\n vars.debt,\n vars.collChange,\n vars.isCollIncrease,\n vars.netDebtChange,\n _isDebtIncrease\n );\n sortedTroves.reInsert(_borrower, vars.newNICR, _upperHint, _lowerHint);\n\n emit TroveUpdated(\n _borrower,\n vars.newDebt,\n vars.newColl,\n vars.stake,\n BorrowerOperation.adjustTrove\n );\n emit ZUSDBorrowingFeePaid(msg.sender, vars.ZUSDFee);\n\n // Use the unmodified _ZUSDChange here, as we don't send the fee to the user\n _moveTokensAndETHfromAdjustment(\n contractsCache.activePool,\n contractsCache.zusdToken,\n msg.sender,\n vars.collChange,\n vars.isCollIncrease,\n _ZUSDChange,\n _isDebtIncrease,\n vars.netDebtChange,\n _tokensRecipient\n );\n }\n\n function closeTrove() external override {\n _closeTrove();\n }\n\n function closeNueTrove(IMassetManager.PermitParams calldata _permitParams) external override {\n require(address(massetManager) != address(0), \"Masset address not set\");\n\n uint256 debt = troveManager.getTroveDebt(msg.sender);\n\n MyntLib.redeemZusdFromDllrWithPermit(\n massetManager,\n debt.sub(ZUSD_GAS_COMPENSATION),\n address(zusdToken),\n _permitParams\n );\n _closeTrove();\n }\n\n function _closeTrove() internal {\n ITroveManager troveManagerCached = troveManager;\n IActivePool activePoolCached = activePool;\n IZUSDToken zusdTokenCached = zusdToken;\n\n _requireTroveisActive(troveManagerCached, msg.sender);\n uint256 price = priceFeed.fetchPrice();\n _requireNotInRecoveryMode(price);\n\n troveManagerCached.applyPendingRewards(msg.sender);\n\n uint256 coll = troveManagerCached.getTroveColl(msg.sender);\n uint256 debt = troveManagerCached.getTroveDebt(msg.sender);\n\n _requireSufficientZUSDBalance(\n zusdTokenCached,\n msg.sender,\n debt.sub(ZUSD_GAS_COMPENSATION)\n );\n\n uint256 newTCR = _getNewTCRFromTroveChange(coll, false, debt, false, price);\n _requireNewTCRisAboveCCR(newTCR);\n\n troveManagerCached.removeStake(msg.sender);\n troveManagerCached.closeTrove(msg.sender);\n\n emit TroveUpdated(msg.sender, 0, 0, 0, BorrowerOperation.closeTrove);\n\n // Burn the repaid ZUSD from the user's balance and the gas compensation from the Gas Pool\n _burnZusdAndDecreaseActivePoolDebt(\n activePoolCached,\n zusdTokenCached,\n msg.sender,\n debt.sub(ZUSD_GAS_COMPENSATION)\n );\n _burnZusdAndDecreaseActivePoolDebt(\n activePoolCached,\n zusdTokenCached,\n gasPoolAddress,\n ZUSD_GAS_COMPENSATION\n );\n\n // Send the collateral back to the user\n activePoolCached.sendETH(msg.sender, coll);\n }\n\n /**\n * Claim remaining collateral from a redemption or from a liquidation with ICR > MCR in Recovery Mode\n */\n function claimCollateral() external override {\n // send ETH from CollSurplus Pool to owner\n collSurplusPool.claimColl(msg.sender);\n }\n\n // --- Helper functions ---\n\n function _triggerBorrowingFee(\n ITroveManager _troveManager,\n IZUSDToken _zusdToken,\n uint256 _ZUSDAmount,\n uint256 _maxFeePercentage\n ) internal returns (uint256) {\n _troveManager.decayBaseRateFromBorrowing(); // decay the baseRate state variable\n uint256 ZUSDFee = _troveManager.getBorrowingFee(_ZUSDAmount);\n\n _requireUserAcceptsFee(ZUSDFee, _ZUSDAmount, _maxFeePercentage);\n _zusdToken.mint(address(feeDistributor), ZUSDFee);\n feeDistributor.distributeFees();\n\n return ZUSDFee;\n }\n\n function _getUSDValue(uint256 _coll, uint256 _price) internal pure returns (uint256) {\n uint256 usdValue = _price.mul(_coll).div(DECIMAL_PRECISION);\n\n return usdValue;\n }\n\n function _getCollChange(uint256 _collReceived, uint256 _requestedCollWithdrawal)\n internal\n pure\n returns (uint256 collChange, bool isCollIncrease)\n {\n if (_collReceived != 0) {\n collChange = _collReceived;\n isCollIncrease = true;\n } else {\n collChange = _requestedCollWithdrawal;\n }\n }\n\n /// Update trove's coll and debt based on whether they increase or decrease\n function _updateTroveFromAdjustment(\n ITroveManager _troveManager,\n address _borrower,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease\n ) internal returns (uint256, uint256) {\n uint256 newColl = (_isCollIncrease)\n ? _troveManager.increaseTroveColl(_borrower, _collChange)\n : _troveManager.decreaseTroveColl(_borrower, _collChange);\n uint256 newDebt = (_isDebtIncrease)\n ? _troveManager.increaseTroveDebt(_borrower, _debtChange)\n : _troveManager.decreaseTroveDebt(_borrower, _debtChange);\n\n return (newColl, newDebt);\n }\n\n function _moveTokensAndETHfromAdjustment(\n IActivePool _activePool,\n IZUSDToken _zusdToken,\n address _borrower,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n uint256 _netDebtChange,\n address _tokensRecipient\n ) internal {\n if (_isDebtIncrease) {\n _mintZusdAndIncreaseActivePoolDebt(\n _activePool,\n _zusdToken,\n _tokensRecipient,\n _ZUSDChange,\n _netDebtChange\n );\n } else {\n _burnZusdAndDecreaseActivePoolDebt(_activePool, _zusdToken, _borrower, _ZUSDChange);\n }\n\n if (_isCollIncrease) {\n _activePoolAddColl(_activePool, _collChange);\n } else {\n _activePool.sendETH(_borrower, _collChange);\n }\n }\n\n /// Send ETH to Active Pool and increase its recorded ETH balance\n function _activePoolAddColl(IActivePool _activePool, uint256 _amount) internal {\n (bool success, ) = address(_activePool).call{ value: _amount }(\"\");\n require(success, \"BorrowerOps: Sending ETH to ActivePool failed\");\n }\n\n /// Issue the specified amount of ZUSD to _account and increases the total active debt (_netDebtIncrease potentially includes a ZUSDFee)\n function _mintZusdAndIncreaseActivePoolDebt(\n IActivePool _activePool,\n IZUSDToken _zusdToken,\n address _account,\n uint256 _ZUSDAmount,\n uint256 _netDebtIncrease\n ) internal {\n _activePool.increaseZUSDDebt(_netDebtIncrease);\n _zusdToken.mint(_account, _ZUSDAmount);\n }\n\n /// Burn the specified amount of ZUSD from _account and decreases the total active debt\n function _burnZusdAndDecreaseActivePoolDebt(\n IActivePool _activePool,\n IZUSDToken _zusdToken,\n address _account,\n uint256 _ZUSD\n ) internal {\n _activePool.decreaseZUSDDebt(_ZUSD);\n _zusdToken.burn(_account, _ZUSD);\n }\n\n // --- 'Require' wrapper functions ---\n\n function _requireSingularCollChange(uint256 _collWithdrawal) internal view {\n require(\n msg.value == 0 || _collWithdrawal == 0,\n \"BorrowerOperations: Cannot withdraw and add coll\"\n );\n }\n\n function _requireCallerIsBorrower(address _borrower) internal view {\n require(\n msg.sender == _borrower,\n \"BorrowerOps: Caller must be the borrower for a withdrawal\"\n );\n }\n\n function _requireNonZeroAdjustment(uint256 _collWithdrawal, uint256 _ZUSDChange)\n internal\n view\n {\n require(\n msg.value != 0 || _collWithdrawal != 0 || _ZUSDChange != 0,\n \"BorrowerOps: There must be either a collateral change or a debt change\"\n );\n }\n\n function _requireTroveisActive(ITroveManager _troveManager, address _borrower) internal view {\n uint256 status = _troveManager.getTroveStatus(_borrower);\n require(status == 1, \"BorrowerOps: Trove does not exist or is closed\");\n }\n\n function _requireTroveisNotActive(ITroveManager _troveManager, address _borrower)\n internal\n view\n {\n uint256 status = _troveManager.getTroveStatus(_borrower);\n require(status != 1, \"BorrowerOps: Trove is active\");\n }\n\n function _requireNonZeroDebtChange(uint256 _ZUSDChange) internal pure {\n require(_ZUSDChange > 0, \"BorrowerOps: Debt increase requires non-zero debtChange\");\n }\n\n function _requireNotInRecoveryMode(uint256 _price) internal view {\n require(\n !_checkRecoveryMode(_price),\n \"BorrowerOps: Operation not permitted during Recovery Mode\"\n );\n }\n\n function _requireNoCollWithdrawal(uint256 _collWithdrawal) internal pure {\n require(\n _collWithdrawal == 0,\n \"BorrowerOps: Collateral withdrawal not permitted Recovery Mode\"\n );\n }\n\n function _requireValidAdjustmentInCurrentMode(\n bool _isRecoveryMode,\n uint256 _collWithdrawal,\n bool _isDebtIncrease,\n LocalVariables_adjustTrove memory _vars\n ) internal view {\n /*\n *In Recovery Mode, only allow:\n *\n * - Pure collateral top-up\n * - Pure debt repayment\n * - Collateral top-up with debt repayment\n * - A debt increase combined with a collateral top-up which makes the ICR >= 150% and improves the ICR (and by extension improves the TCR).\n *\n * In Normal Mode, ensure:\n *\n * - The new ICR is above MCR\n * - The adjustment won't pull the TCR below CCR\n */\n if (_isRecoveryMode) {\n _requireNoCollWithdrawal(_collWithdrawal);\n if (_isDebtIncrease) {\n _requireICRisAboveCCR(_vars.newICR);\n _requireNewICRisAboveOldICR(_vars.newICR, _vars.oldICR);\n }\n } else {\n // if Normal Mode\n _requireICRisAboveMCR(_vars.newICR);\n _vars.newTCR = _getNewTCRFromTroveChange(\n _vars.collChange,\n _vars.isCollIncrease,\n _vars.netDebtChange,\n _isDebtIncrease,\n _vars.price\n );\n _requireNewTCRisAboveCCR(_vars.newTCR);\n }\n }\n\n function _requireICRisAboveMCR(uint256 _newICR) internal view {\n require(\n _newICR >= liquityBaseParams.MCR(),\n \"BorrowerOps: An operation that would result in ICR < MCR is not permitted\"\n );\n }\n\n function _requireICRisAboveCCR(uint256 _newICR) internal view {\n require(\n _newICR >= liquityBaseParams.CCR(),\n \"BorrowerOps: Operation must leave trove with ICR >= CCR\"\n );\n }\n\n function _requireNewICRisAboveOldICR(uint256 _newICR, uint256 _oldICR) internal pure {\n require(\n _newICR >= _oldICR,\n \"BorrowerOps: Cannot decrease your Trove's ICR in Recovery Mode\"\n );\n }\n\n function _requireNewTCRisAboveCCR(uint256 _newTCR) internal view {\n require(\n _newTCR >= liquityBaseParams.CCR(),\n \"BorrowerOps: An operation that would result in TCR < CCR is not permitted\"\n );\n }\n\n function _requireAtLeastMinNetDebt(uint256 _netDebt) internal pure {\n require(\n _netDebt >= MIN_NET_DEBT,\n \"BorrowerOps: Trove's net debt must be greater than minimum\"\n );\n }\n\n function _requireValidZUSDRepayment(uint256 _currentDebt, uint256 _debtRepayment)\n internal\n pure\n {\n require(\n _debtRepayment <= _currentDebt.sub(ZUSD_GAS_COMPENSATION),\n \"BorrowerOps: Amount repaid must not be larger than the Trove's debt\"\n );\n }\n\n function _requireCallerIsStabilityPool() internal view {\n require(msg.sender == stabilityPoolAddress, \"BorrowerOps: Caller is not Stability Pool\");\n }\n\n function _requireSufficientZUSDBalance(\n IZUSDToken _zusdToken,\n address _borrower,\n uint256 _debtRepayment\n ) internal view {\n require(\n _zusdToken.balanceOf(_borrower) >= _debtRepayment,\n \"BorrowerOps: Caller doesnt have enough ZUSD to make repayment\"\n );\n }\n\n function _requireValidMaxFeePercentage(uint256 _maxFeePercentage, bool _isRecoveryMode)\n internal\n view\n {\n if (_isRecoveryMode) {\n require(\n _maxFeePercentage <= DECIMAL_PRECISION,\n \"Max fee percentage must less than or equal to 100%\"\n );\n } else {\n require(\n _maxFeePercentage >= liquityBaseParams.BORROWING_FEE_FLOOR() &&\n _maxFeePercentage <= DECIMAL_PRECISION,\n \"Max fee percentage must be between 0.5% and 100%\"\n );\n }\n }\n\n // --- ICR and TCR getters ---\n\n /// Compute the new collateral ratio, considering the change in coll and debt. Assumes 0 pending rewards.\n function _getNewNominalICRFromTroveChange(\n uint256 _coll,\n uint256 _debt,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease\n ) internal pure returns (uint256) {\n (uint256 newColl, uint256 newDebt) = _getNewTroveAmounts(\n _coll,\n _debt,\n _collChange,\n _isCollIncrease,\n _debtChange,\n _isDebtIncrease\n );\n\n uint256 newNICR = LiquityMath._computeNominalCR(newColl, newDebt);\n return newNICR;\n }\n\n /// Compute the new collateral ratio, considering the change in coll and debt. Assumes 0 pending rewards.\n function _getNewICRFromTroveChange(\n uint256 _coll,\n uint256 _debt,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease,\n uint256 _price\n ) internal pure returns (uint256) {\n (uint256 newColl, uint256 newDebt) = _getNewTroveAmounts(\n _coll,\n _debt,\n _collChange,\n _isCollIncrease,\n _debtChange,\n _isDebtIncrease\n );\n\n uint256 newICR = LiquityMath._computeCR(newColl, newDebt, _price);\n return newICR;\n }\n\n function _getNewTroveAmounts(\n uint256 _coll,\n uint256 _debt,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease\n ) internal pure returns (uint256, uint256) {\n uint256 newColl = _coll;\n uint256 newDebt = _debt;\n\n newColl = _isCollIncrease ? _coll.add(_collChange) : _coll.sub(_collChange);\n newDebt = _isDebtIncrease ? _debt.add(_debtChange) : _debt.sub(_debtChange);\n\n return (newColl, newDebt);\n }\n\n function _getNewTCRFromTroveChange(\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease,\n uint256 _price\n ) internal view returns (uint256) {\n uint256 totalColl = getEntireSystemColl();\n uint256 totalDebt = getEntireSystemDebt();\n\n totalColl = _isCollIncrease ? totalColl.add(_collChange) : totalColl.sub(_collChange);\n totalDebt = _isDebtIncrease ? totalDebt.add(_debtChange) : totalDebt.sub(_debtChange);\n\n uint256 newTCR = LiquityMath._computeCR(totalColl, totalDebt, _price);\n return newTCR;\n }\n\n function getCompositeDebt(uint256 _debt) external view override returns (uint256) {\n return _getCompositeDebt(_debt);\n }\n\n function BORROWING_FEE_FLOOR() external view override returns (uint256) {\n return liquityBaseParams.BORROWING_FEE_FLOOR();\n }\n\n function getMassetManager() external view override returns (IMassetManager) {\n return massetManager;\n }\n}\n" + }, + "contracts/BorrowerOperationsStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IActivePool.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/Mynt/IMassetManager.sol\";\n\ncontract BorrowerOperationsStorage is Ownable {\n string public constant NAME = \"BorrowerOperations\";\n\n // --- Connected contract declarations ---\n\n ITroveManager public troveManager;\n\n address stabilityPoolAddress;\n\n address gasPoolAddress;\n\n ICollSurplusPool collSurplusPool;\n\n IZEROStaking public zeroStaking;\n address public zeroStakingAddress;\n\n IZUSDToken public zusdToken;\n\n // A doubly linked list of Troves, sorted by their collateral ratios\n ISortedTroves public sortedTroves;\n\n IMassetManager public massetManager;\n IFeeDistributor public feeDistributor;\n}\n" + }, + "contracts/CollSurplusPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./CollSurplusPoolStorage.sol\";\n\ncontract CollSurplusPool is CollSurplusPoolStorage, CheckContract, ICollSurplusPool {\n using SafeMath for uint256;\n // --- Events ---\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n\n event CollBalanceUpdated(address indexed _account, uint256 _newBalance);\n event EtherSent(address _to, uint256 _amount);\n\n // --- Contract setters ---\n\n function setAddresses(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress\n ) external override onlyOwner {\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n\n borrowerOperationsAddress = _borrowerOperationsAddress;\n troveManagerAddress = _troveManagerAddress;\n activePoolAddress = _activePoolAddress;\n\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n }\n\n /** Returns the ETH state variable at ActivePool address.\n Not necessarily equal to the raw ether balance - ether can be forcibly sent to contracts. */\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n function getCollateral(address _account) external view override returns (uint256) {\n return balances[_account];\n }\n\n // --- Pool functionality ---\n\n function accountSurplus(address _account, uint256 _amount) external override {\n _requireCallerIsTroveManager();\n\n uint256 newAmount = balances[_account].add(_amount);\n balances[_account] = newAmount;\n\n emit CollBalanceUpdated(_account, newAmount);\n }\n\n function claimColl(address _account) external override {\n _requireCallerIsBorrowerOperations();\n uint256 claimableColl = balances[_account];\n require(claimableColl > 0, \"CollSurplusPool: No collateral available to claim\");\n\n balances[_account] = 0;\n emit CollBalanceUpdated(_account, 0);\n\n ETH = ETH.sub(claimableColl);\n emit EtherSent(_account, claimableColl);\n\n (bool success, ) = _account.call{ value: claimableColl }(\"\");\n require(success, \"CollSurplusPool: sending ETH failed\");\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsBorrowerOperations() internal view {\n require(\n msg.sender == borrowerOperationsAddress,\n \"CollSurplusPool: Caller is not Borrower Operations\"\n );\n }\n\n function _requireCallerIsTroveManager() internal view {\n require(msg.sender == troveManagerAddress, \"CollSurplusPool: Caller is not TroveManager\");\n }\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"CollSurplusPool: Caller is not Active Pool\");\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsActivePool();\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/CollSurplusPoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Dependencies/Ownable.sol\";\n\ncontract CollSurplusPoolStorage is Ownable {\n string public constant NAME = \"CollSurplusPool\";\n\n address public borrowerOperationsAddress;\n address public troveManagerAddress;\n address public activePoolAddress;\n\n // deposited ether tracker\n uint256 internal ETH;\n // Collateral surplus claimable by trove owners\n mapping(address => uint256) internal balances;\n}\n" + }, + "contracts/DefaultPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IDefaultPool.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./DefaultPoolStorage.sol\";\n\n/**\n * The Default Pool holds the ETH and ZUSD debt (but not ZUSD tokens) from liquidations that have been redistributed\n * to active troves but not yet \"applied\", i.e. not yet recorded on a recipient active trove's struct.\n *\n * When a trove makes an operation that applies its pending ETH and ZUSD debt, its pending ETH and ZUSD debt is moved\n * from the Default Pool to the Active Pool.\n */\ncontract DefaultPool is DefaultPoolStorage, CheckContract, IDefaultPool {\n using SafeMath for uint256;\n\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event DefaultPoolZUSDDebtUpdated(uint256 _ZUSDDebt);\n event DefaultPoolETHBalanceUpdated(uint256 _ETH);\n\n // --- Dependency setters ---\n\n function setAddresses(address _troveManagerAddress, address _activePoolAddress)\n external\n onlyOwner\n {\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n\n troveManagerAddress = _troveManagerAddress;\n activePoolAddress = _activePoolAddress;\n\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n }\n\n // --- Getters for public variables. Required by IPool interface ---\n\n /**\n * @return the ETH state variable.\n *\n * Not necessarily equal to the the contract's raw ETH balance - ether can be forcibly sent to contracts.\n */\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n function getZUSDDebt() external view override returns (uint256) {\n return ZUSDDebt;\n }\n\n // --- Pool functionality ---\n\n function sendETHToActivePool(uint256 _amount) external override {\n _requireCallerIsTroveManager();\n address activePool = activePoolAddress; // cache to save an SLOAD\n ETH = ETH.sub(_amount);\n emit DefaultPoolETHBalanceUpdated(ETH);\n emit EtherSent(activePool, _amount);\n\n (bool success, ) = activePool.call{ value: _amount }(\"\");\n require(success, \"DefaultPool: sending ETH failed\");\n }\n\n function increaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsTroveManager();\n ZUSDDebt = ZUSDDebt.add(_amount);\n emit DefaultPoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n function decreaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsTroveManager();\n ZUSDDebt = ZUSDDebt.sub(_amount);\n emit DefaultPoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"DefaultPool: Caller is not the ActivePool\");\n }\n\n function _requireCallerIsTroveManager() internal view {\n require(msg.sender == troveManagerAddress, \"DefaultPool: Caller is not the TroveManager\");\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsActivePool();\n ETH = ETH.add(msg.value);\n emit DefaultPoolETHBalanceUpdated(ETH);\n }\n}\n" + }, + "contracts/DefaultPoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract DefaultPoolStorage is Ownable {\n string public constant NAME = \"DefaultPool\";\n\n address public troveManagerAddress;\n address public activePoolAddress;\n uint256 internal ETH; // deposited ETH tracker\n uint256 internal ZUSDDebt; // debt\n}\n" + }, + "contracts/Dependencies/BaseMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\n\ncontract BaseMath {\n uint constant public DECIMAL_PRECISION = 1e18;\n}\n" + }, + "contracts/Dependencies/CheckContract.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n\ncontract CheckContract {\n /**\n * @dev Check that the account is an already deployed non-destroyed contract.\n * See: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L12\n */\n function checkContract(address _account) internal view {\n require(_account != address(0), \"Account cannot be zero address\");\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(_account) }\n require(size > 0, \"Account code size cannot be zero\");\n }\n}\n" + }, + "contracts/Dependencies/console.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// Buidler's helper contract for console logging\nlibrary console {\n\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n\tfunction log() internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log()\"));\n\t\tignored;\n\t}\tfunction logInt(int p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(int)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logUint(uint p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logString(string memory p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBool(bool p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logAddress(address p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes(bytes memory p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logByte(byte p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(byte)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes1(bytes1 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes1)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes2(bytes2 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes2)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes3(bytes3 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes3)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes4(bytes4 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes4)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes5(bytes5 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes5)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes6(bytes6 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes6)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes7(bytes7 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes7)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes8(bytes8 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes8)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes9(bytes9 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes9)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes10(bytes10 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes10)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes11(bytes11 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes11)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes12(bytes12 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes12)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes13(bytes13 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes13)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes14(bytes14 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes14)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes15(bytes15 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes15)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes16(bytes16 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes16)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes17(bytes17 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes17)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes18(bytes18 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes18)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes19(bytes19 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes19)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes20(bytes20 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes20)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes21(bytes21 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes21)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes22(bytes22 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes22)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes23(bytes23 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes23)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes24(bytes24 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes24)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes25(bytes25 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes25)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes26(bytes26 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes26)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes27(bytes27 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes27)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes28(bytes28 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes28)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes29(bytes29 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes29)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes30(bytes30 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes30)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes31(bytes31 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes31)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes32(bytes32 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes32)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(address p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n}\n" + }, + "contracts/Dependencies/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * Based on the OpenZeppelin IER20 interface:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol\n *\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n function increaseAllowance(address spender, uint256 addedValue) external returns (bool);\n function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n function name() external view returns (string memory);\n function symbol() external view returns (string memory);\n function decimals() external view returns (uint8);\n \n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}" + }, + "contracts/Dependencies/IERC2612.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * @dev Interface of the ERC2612 standard as defined in the EIP.\n *\n * Adds the {permit} method, which can be used to change one's\n * {IERC20-allowance} without having to send a transaction, by signing a\n * message. This allows users to spend tokens without having to hold Ether.\n *\n * See https://eips.ethereum.org/EIPS/eip-2612.\n * \n * Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\n */\ninterface IERC2612 {\n /**\n * @dev Sets `amount` as the allowance of `spender` over `owner`'s tokens,\n * given `owner`'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(address owner, address spender, uint256 amount, \n uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n \n /**\n * @dev Returns the current ERC2612 nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases `owner`'s nonce by one. This\n * prevents a signature from being used multiple times.\n *\n * `owner` can limit the time a Permit is valid for by setting `deadline` to \n * a value in the near future. The deadline argument can be set to uint(-1) to \n * create Permits that effectively never expire.\n */\n function nonces(address owner) external view returns (uint256);\n \n function version() external view returns (string memory);\n function permitTypeHash() external view returns (bytes32);\n function domainSeparator() external view returns (bytes32);\n}\n" + }, + "contracts/Dependencies/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * @title Initializable\n *\n * Based on OpenZeppelin's Initializable contract:\n * https://github.com/OpenZeppelin/openzeppelin-upgrades/blob/master/packages/core/contracts/Initializable.sol\n * \n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(\n initializing || isConstructor() || !initialized,\n \"Contract instance has already been initialized\"\n );\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n /// @dev Returns true if and only if the function is running in the constructor\n function isConstructor() private view returns (bool) {\n // extcodesize checks the size of the code stored in an address, and\n // address returns the current address. Since the code is still not\n // deployed when running a constructor, any checks on its code size will\n // yield zero, making it an effective way to detect if a contract is\n // under construction or not.\n address self = address(this);\n uint256 cs;\n assembly {\n cs := extcodesize(self)\n }\n return cs == 0;\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}\n" + }, + "contracts/Dependencies/LiquityBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./BaseMath.sol\";\nimport \"./LiquityMath.sol\";\nimport \"../Interfaces/IActivePool.sol\";\nimport \"../Interfaces/IDefaultPool.sol\";\nimport \"../Interfaces/IPriceFeed.sol\";\nimport \"../Interfaces/ILiquityBase.sol\";\nimport \"../Interfaces/ILiquityBaseParams.sol\";\n\n/**\n * Base contract for TroveManager, BorrowerOperations and StabilityPool. Contains global system constants and\n * common functions.\n */\ncontract LiquityBase is BaseMath, ILiquityBase {\n using SafeMath for uint256;\n\n uint256 public constant _100pct = 1000000000000000000; // 1e18 == 100%\n\n /// Amount of ZUSD to be locked in gas pool on opening troves\n uint256 public constant ZUSD_GAS_COMPENSATION = 20e18;\n\n /// Minimum amount of net ZUSD debt a trove must have\n uint256 public constant MIN_NET_DEBT = 180e18;\n\n IActivePool public activePool;\n\n IDefaultPool public defaultPool;\n\n IPriceFeed public override priceFeed;\n\n ILiquityBaseParams public override liquityBaseParams;\n\n // --- Gas compensation functions ---\n\n // Returns the composite debt (drawn debt + gas compensation) of a trove, for the purpose of ICR calculation\n function _getCompositeDebt(uint256 _debt) internal pure returns (uint256) {\n return _debt.add(ZUSD_GAS_COMPENSATION);\n }\n\n function _getNetDebt(uint256 _debt) internal pure returns (uint256) {\n return _debt.sub(ZUSD_GAS_COMPENSATION);\n }\n\n /// Return the amount of ETH to be drawn from a trove's collateral and sent as gas compensation.\n function _getCollGasCompensation(uint256 _entireColl) internal view returns (uint256) {\n return _entireColl / liquityBaseParams.PERCENT_DIVISOR();\n }\n\n function getEntireSystemColl() public view returns (uint256 entireSystemColl) {\n uint256 activeColl = activePool.getETH();\n uint256 liquidatedColl = defaultPool.getETH();\n\n return activeColl.add(liquidatedColl);\n }\n\n function getEntireSystemDebt() public view returns (uint256 entireSystemDebt) {\n uint256 activeDebt = activePool.getZUSDDebt();\n uint256 closedDebt = defaultPool.getZUSDDebt();\n\n return activeDebt.add(closedDebt);\n }\n\n function _getTCR(uint256 _price) internal view returns (uint256 TCR) {\n uint256 entireSystemColl = getEntireSystemColl();\n uint256 entireSystemDebt = getEntireSystemDebt();\n\n TCR = LiquityMath._computeCR(entireSystemColl, entireSystemDebt, _price);\n\n return TCR;\n }\n\n function _checkRecoveryMode(uint256 _price) internal view returns (bool) {\n uint256 TCR = _getTCR(_price);\n\n return TCR < liquityBaseParams.CCR();\n }\n\n function _requireUserAcceptsFee(\n uint256 _fee,\n uint256 _amount,\n uint256 _maxFeePercentage\n ) internal pure {\n uint256 feePercentage = _fee.mul(DECIMAL_PRECISION).div(_amount);\n require(feePercentage <= _maxFeePercentage, \"Fee exceeded provided maximum\");\n }\n}\n" + }, + "contracts/Dependencies/LiquityMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./SafeMath.sol\";\nimport \"./console.sol\";\n\nlibrary LiquityMath {\n using SafeMath for uint;\n\n uint internal constant DECIMAL_PRECISION = 1e18;\n\n /* Precision for Nominal ICR (independent of price). Rationale for the value:\n *\n * - Making it “too high” could lead to overflows.\n * - Making it “too low” could lead to an ICR equal to zero, due to truncation from Solidity floor division. \n *\n * This value of 1e20 is chosen for safety: the NICR will only overflow for numerator > ~1e39 ETH,\n * and will only truncate to 0 if the denominator is at least 1e20 times greater than the numerator.\n *\n */\n uint internal constant NICR_PRECISION = 1e20;\n\n function _min(uint _a, uint _b) internal pure returns (uint) {\n return (_a < _b) ? _a : _b;\n }\n\n function _max(uint _a, uint _b) internal pure returns (uint) {\n return (_a >= _b) ? _a : _b;\n }\n\n /* \n * Multiply two decimal numbers and use normal rounding rules:\n * -round product up if 19'th mantissa digit >= 5\n * -round product down if 19'th mantissa digit < 5\n *\n * Used only inside the exponentiation, _decPow().\n */\n function decMul(uint x, uint y) internal pure returns (uint decProd) {\n uint prod_xy = x.mul(y);\n\n decProd = prod_xy.add(DECIMAL_PRECISION / 2).div(DECIMAL_PRECISION);\n }\n\n /* \n * _decPow: Exponentiation function for 18-digit decimal base, and integer exponent n.\n * \n * Uses the efficient \"exponentiation by squaring\" algorithm. O(log(n)) complexity. \n * \n * Called by two functions that represent time in units of minutes:\n * 1) TroveManager._calcDecayedBaseRate\n * 2) CommunityIssuance._getCumulativeIssuanceFraction \n * \n * The exponent is capped to avoid reverting due to overflow. The cap 525600000 equals\n * \"minutes in 1000 years\": 60 * 24 * 365 * 1000\n * \n * If a period of > 1000 years is ever used as an exponent in either of the above functions, the result will be\n * negligibly different from just passing the cap, since: \n *\n * In function 1), the decayed base rate will be 0 for 1000 years or > 1000 years\n * In function 2), the difference in tokens issued at 1000 years and any time > 1000 years, will be negligible\n */\n function _decPow(uint _base, uint _minutes) internal pure returns (uint) {\n \n if (_minutes > 525600000) {_minutes = 525600000;} // cap to avoid overflow\n \n if (_minutes == 0) {return DECIMAL_PRECISION;}\n\n uint y = DECIMAL_PRECISION;\n uint x = _base;\n uint n = _minutes;\n\n // Exponentiation-by-squaring\n while (n > 1) {\n if (n % 2 == 0) {\n x = decMul(x, x);\n n = n.div(2);\n } else { // if (n % 2 != 0)\n y = decMul(x, y);\n x = decMul(x, x);\n n = (n.sub(1)).div(2);\n }\n }\n\n return decMul(x, y);\n }\n\n function _getAbsoluteDifference(uint _a, uint _b) internal pure returns (uint) {\n return (_a >= _b) ? _a.sub(_b) : _b.sub(_a);\n }\n\n function _computeNominalCR(uint _coll, uint _debt) internal pure returns (uint) {\n if (_debt > 0) {\n return _coll.mul(NICR_PRECISION).div(_debt);\n }\n // Return the maximal value for uint256 if the Trove has a debt of 0. Represents \"infinite\" CR.\n else { // if (_debt == 0)\n return 2**256 - 1;\n }\n }\n\n function _computeCR(uint _coll, uint _debt, uint _price) internal pure returns (uint) {\n if (_debt > 0) {\n uint newCollRatio = _coll.mul(_price).div(_debt);\n\n return newCollRatio;\n }\n // Return the maximal value for uint256 if the Trove has a debt of 0. Represents \"infinite\" CR.\n else { // if (_debt == 0)\n return 2**256 - 1; \n }\n }\n}\n" + }, + "contracts/Dependencies/LiquitySafeMath128.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// uint128 addition and subtraction, with overflow protection.\n\nlibrary LiquitySafeMath128 {\n function add(uint128 a, uint128 b) internal pure returns (uint128) {\n uint128 c = a + b;\n require(c >= a, \"LiquitySafeMath128: addition overflow\");\n\n return c;\n }\n \n function sub(uint128 a, uint128 b) internal pure returns (uint128) {\n require(b <= a, \"LiquitySafeMath128: subtraction overflow\");\n uint128 c = a - b;\n\n return c;\n }\n}" + }, + "contracts/Dependencies/Mynt/IDLLR.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\nimport \"../IERC20.sol\";\n\n/// Public interface for Sovryn Dollar DLLR (Meta Asset Token of Sovryn Mynt) exposing specific functions\ninterface IDLLR is IERC20 {\n /**\n * @notice Only owner can transfer the token.\n * @notice destination cannot be:\n * - zero (0x0) address.\n *\n * @param _recipient Recipient of the token.\n * @param _amount The amount of token that will be transferred.\n *\n * @return true / false.\n */\n function transfer(address _recipient, uint256 _amount) external override returns (bool);\n\n /**\n * @notice Only owner who can transfer the token.\n * @notice destination cannot be:\n * - zero (0x0) address.\n *\n * @param _from Sender of the token.\n * @param _to Recipient of the token.\n * @param _amount The amount of token that will be transferred.\n *\n * @return true / false.\n */\n function transferFrom(\n address _from,\n address _to,\n uint256 _amount\n ) external override returns (bool);\n\n /**\n * @notice transfer utilizing EIP-2612, to reduce the additional sending transaction for doing the approval to the spender.\n *\n * @notice destination cannot be:\n * - zero (0x0) address.\n *\n * @dev By calling this function, the allowance will be overwritten by the total amount.\n *\n * @param _from Sender of the token.\n * @param _to Recipient of the token.\n * @param _amount The amount of the token that will be transferred.\n * @param _deadline Expiration time of the signature.\n * @param _v Last 1 byte of ECDSA signature.\n * @param _r First 32 bytes of ECDSA signature.\n * @param _s 32 bytes after _r in ECDSA signature.\n */\n function transferWithPermit(\n address _from,\n address _to,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external;\n\n /**\n * @notice Approves and then calls the receiving contract.\n * Useful to encapsulate sending tokens to a contract in one call.\n * Solidity has no native way to send tokens to contracts.\n * ERC-20 tokens require approval to be spent by third parties, such as a contract in this case.\n * @param _spender The contract address to spend the tokens.\n * @param _amount The amount of tokens to be sent.\n * @param _data Parameters for the contract call, such as endpoint signature.\n */\n function approveAndCall(address _spender, uint256 _amount, bytes calldata _data) external;\n}\n" + }, + "contracts/Dependencies/Mynt/IMassetManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IMassetManager {\n struct PermitParams {\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n function mintTo(\n address _bAsset,\n uint256 _bAssetQuantity,\n address _recipient\n ) external returns (uint256);\n\n function getToken() external view returns (address);\n\n /**\n * @dev Credits a recipient with a certain quantity of selected bAsset, in exchange for burning the\n * relative mAsset quantity from the sender. Sender also incurs a small fee, if any.\n * @param _bAsset Address of the bAsset to redeem.\n * @param _massetQuantity Units of the masset to redeem.\n * @param _recipient Address to credit with withdrawn bAssets.\n * @return massetRedeemed Relative number of mAsset units burned to pay for the bAssets.\n */\n function redeemTo(\n address _bAsset,\n uint256 _massetQuantity,\n address _recipient\n ) external returns (uint256 massetRedeemed);\n}\n" + }, + "contracts/Dependencies/Mynt/MyntLib.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IMassetManager.sol\";\nimport \"./IDLLR.sol\";\nimport \"../SafeMath.sol\";\n\nlibrary MyntLib {\n using SafeMath for uint256;\n\n /**\n * @notice Convert DLLR _dllrAmount to _toToken utilizing EIP-2612 permit\n * to reduce the additional sending transaction for doing the approval to the spender.\n *\n * @param _myntMassetManager Mynt protocol MassetManager contract address - needed for integration\n * @param _dllrAmount The amount of the DLLR (mAsset) token that will be burned in exchange for _toToken\n * @param _toToken bAsset token address to wothdraw from DLLR\n * @param _permitParams EIP-2612 permit params:\n * _deadline Expiration time of the signature.\n * _v Last 1 byte of ECDSA signature.\n * _r First 32 bytes of ECDSA signature.\n * _s 32 bytes after _r in ECDSA signature.\n * @return redeemed ZUSD amount\n */\n function redeemZusdFromDllrWithPermit(\n IMassetManager _myntMassetManager,\n uint256 _dllrAmount,\n address _toToken,\n IMassetManager.PermitParams calldata _permitParams\n ) internal returns (uint256) {\n IDLLR dllr = IDLLR(_myntMassetManager.getToken());\n uint256 thisBalanceBefore = dllr.balanceOf(address(this));\n address thisAddress = address(this);\n dllr.transferWithPermit(\n msg.sender,\n thisAddress,\n _dllrAmount,\n _permitParams.deadline,\n _permitParams.v,\n _permitParams.r,\n _permitParams.s\n );\n require(\n dllr.balanceOf(thisAddress).sub(thisBalanceBefore) == _dllrAmount,\n \"DLLR transferred amount validation failed\"\n );\n return _myntMassetManager.redeemTo(_toToken, _dllrAmount, msg.sender);\n }\n}\n" + }, + "contracts/Dependencies/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * Based on OpenZeppelin's Ownable contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n *\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\ncontract Ownable {\n bytes32 private constant KEY_OWNER = keccak256(\"key.ownable.owner\");\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () internal {\n _setOwner(msg.sender);\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(msg.sender == getOwner(), \"Ownable:: access denied\");\n _;\n }\n\n /**\n * @notice Set address of the owner.\n * @param _owner Address of the owner.\n * */\n function _setOwner(address _owner) internal {\n require(_owner != address(0), \"Ownable::setOwner: invalid address\");\n emit OwnershipTransferred(getOwner(), _owner);\n\n bytes32 key = KEY_OWNER;\n assembly {\n sstore(key, _owner)\n }\n }\n\n /**\n * @notice Set address of the owner (only owner can call this function)\n * @param _owner Address of the owner.\n * */\n function setOwner(address _owner) public onlyOwner {\n _setOwner(_owner);\n }\n\n /**\n * @notice Return address of the owner.\n * @return _owner Address of the owner.\n * */\n function getOwner() public view returns (address _owner) {\n bytes32 key = KEY_OWNER;\n assembly {\n _owner := sload(key)\n }\n }\n}\n" + }, + "contracts/Dependencies/PriceFeed/IExternalPriceFeed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/// @title A generic interface for external price providers \ninterface IExternalPriceFeed {\n /// @dev The returned price should be 18-decimal value\n /// @return the prive value and a boolean stating if the query was successful\n function latestAnswer() external view returns (uint256, bool);\n}\n" + }, + "contracts/Dependencies/PriceFeed/MocMedianizer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./IExternalPriceFeed.sol\";\n\ninterface IMoCBaseOracle {\n function peek() external view returns (bytes32, bool);\n}\n\ncontract MoCMedianizer is IExternalPriceFeed {\n IMoCBaseOracle medianizer;\n\n constructor(address _medianizer) public {\n medianizer = IMoCBaseOracle(_medianizer);\n }\n\n function latestAnswer() external view override returns (uint256, bool) {\n (bytes32 price, bool success) = medianizer.peek();\n return (uint256(price), success);\n }\n}\n" + }, + "contracts/Dependencies/PriceFeed/RskOracle.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./IExternalPriceFeed.sol\";\n\ninterface IRSKOracle {\n function getPricing() external view returns (uint256, uint256);\n}\n\ncontract RskOracle is IExternalPriceFeed {\n \n IRSKOracle rskOracle;\n\n constructor(address _address) public {\n rskOracle = IRSKOracle(_address);\n }\n\n function latestAnswer() external view override returns (uint256, bool) {\n (uint256 price, ) = rskOracle.getPricing();\n return (price, true);\n }\n}\n" + }, + "contracts/Dependencies/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * Based on OpenZeppelin's SafeMath:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol\n *\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "contracts/Dependencies/TroveManagerBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IActivePool.sol\";\nimport \"../Interfaces/IDefaultPool.sol\";\nimport \"../Interfaces/IZUSDToken.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\nimport \"../Interfaces/ISortedTroves.sol\";\nimport \"../Interfaces/ICollSurplusPool.sol\";\nimport \"../TroveManagerStorage.sol\";\nimport \"./LiquityBase.sol\";\n\ncontract TroveManagerBase is LiquityBase, TroveManagerStorage {\n uint256 public constant SECONDS_IN_ONE_MINUTE = 60;\n\n uint256 public constant MINUTE_DECAY_FACTOR = 999037758833783000;\n\n /// During bootsrap period redemptions are not allowed\n uint256 public immutable BOOTSTRAP_PERIOD;\n\n /**\n BETA: 18 digit decimal. Parameter by which to divide the redeemed fraction, in order to calc the new base rate from a redemption.\n Corresponds to (1 / ALPHA) in the white paper.\n */\n uint256 public constant BETA = 2;\n\n /**\n --- Variable container structs for liquidations ---\n \n These structs are used to hold, return and assign variables inside the liquidation functions,\n in order to avoid the error: \"CompilerError: Stack too deep\".\n */\n\n struct LocalVariables_OuterLiquidationFunction {\n uint256 price;\n uint256 ZUSDInStabPool;\n bool recoveryModeAtStart;\n uint256 liquidatedDebt;\n uint256 liquidatedColl;\n }\n\n struct LocalVariables_InnerSingleLiquidateFunction {\n uint256 collToLiquidate;\n uint256 pendingDebtReward;\n uint256 pendingCollReward;\n }\n\n struct LocalVariables_LiquidationSequence {\n uint256 remainingZUSDInStabPool;\n uint256 i;\n uint256 ICR;\n address user;\n bool backToNormalMode;\n uint256 entireSystemDebt;\n uint256 entireSystemColl;\n }\n\n struct LiquidationValues {\n uint256 entireTroveDebt;\n uint256 entireTroveColl;\n uint256 collGasCompensation;\n uint256 ZUSDGasCompensation;\n uint256 debtToOffset;\n uint256 collToSendToSP;\n uint256 debtToRedistribute;\n uint256 collToRedistribute;\n uint256 collSurplus;\n }\n\n struct LiquidationTotals {\n uint256 totalCollInSequence;\n uint256 totalDebtInSequence;\n uint256 totalCollGasCompensation;\n uint256 totalZUSDGasCompensation;\n uint256 totalDebtToOffset;\n uint256 totalCollToSendToSP;\n uint256 totalDebtToRedistribute;\n uint256 totalCollToRedistribute;\n uint256 totalCollSurplus;\n }\n\n struct ContractsCache {\n IActivePool activePool;\n IDefaultPool defaultPool;\n IZUSDToken zusdToken;\n IZEROStaking zeroStaking;\n ISortedTroves sortedTroves;\n ICollSurplusPool collSurplusPool;\n address gasPoolAddress;\n }\n // --- Variable container structs for redemptions ---\n\n struct RedemptionTotals {\n uint256 remainingZUSD;\n uint256 totalZUSDToRedeem;\n uint256 totalETHDrawn;\n uint256 ETHFee;\n uint256 ETHToSendToRedeemer;\n uint256 decayedBaseRate;\n uint256 price;\n uint256 totalZUSDSupplyAtStart;\n }\n\n struct SingleRedemptionValues {\n uint256 ZUSDLot;\n uint256 ETHLot;\n bool cancelledPartial;\n }\n\n // --- Events ---\n\n event Liquidation(\n uint256 _liquidatedDebt,\n uint256 _liquidatedColl,\n uint256 _collGasCompensation,\n uint256 _ZUSDGasCompensation\n );\n event Redemption(\n uint256 _attemptedZUSDAmount,\n uint256 _actualZUSDAmount,\n uint256 _ETHSent,\n uint256 _ETHFee\n );\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 _stake,\n TroveManagerOperation _operation\n );\n event TroveLiquidated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n TroveManagerOperation _operation\n );\n event BaseRateUpdated(uint256 _baseRate);\n event LastFeeOpTimeUpdated(uint256 _lastFeeOpTime);\n event TotalStakesUpdated(uint256 _newTotalStakes);\n event SystemSnapshotsUpdated(uint256 _totalStakesSnapshot, uint256 _totalCollateralSnapshot);\n event LTermsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveSnapshotsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveIndexUpdated(address _borrower, uint256 _newIndex);\n\n enum TroveManagerOperation {\n applyPendingRewards,\n liquidateInNormalMode,\n liquidateInRecoveryMode,\n redeemCollateral\n }\n\n constructor(uint256 _bootstrapPeriod) public {\n BOOTSTRAP_PERIOD = _bootstrapPeriod;\n }\n\n /// Return the current collateral ratio (ICR) of a given Trove. Takes a trove's pending coll and debt rewards from redistributions into account.\n function _getCurrentICR(address _borrower, uint256 _price) public view returns (uint256) {\n (uint256 currentETH, uint256 currentZUSDDebt) = _getCurrentTroveAmounts(_borrower);\n\n uint256 ICR = LiquityMath._computeCR(currentETH, currentZUSDDebt, _price);\n return ICR;\n }\n\n function _getCurrentTroveAmounts(address _borrower) internal view returns (uint256, uint256) {\n uint256 pendingETHReward = _getPendingETHReward(_borrower);\n uint256 pendingZUSDDebtReward = _getPendingZUSDDebtReward(_borrower);\n\n uint256 currentETH = Troves[_borrower].coll.add(pendingETHReward);\n uint256 currentZUSDDebt = Troves[_borrower].debt.add(pendingZUSDDebtReward);\n\n return (currentETH, currentZUSDDebt);\n }\n\n /// Get the borrower's pending accumulated ETH reward, earned by their stake\n function _getPendingETHReward(address _borrower) public view returns (uint256) {\n uint256 snapshotETH = rewardSnapshots[_borrower].ETH;\n uint256 rewardPerUnitStaked = L_ETH.sub(snapshotETH);\n\n if (rewardPerUnitStaked == 0 || Troves[_borrower].status != Status.active) {\n return 0;\n }\n\n uint256 stake = Troves[_borrower].stake;\n\n uint256 pendingETHReward = stake.mul(rewardPerUnitStaked).div(DECIMAL_PRECISION);\n\n return pendingETHReward;\n }\n\n /// Get the borrower's pending accumulated ZUSD reward, earned by their stake\n function _getPendingZUSDDebtReward(address _borrower) public view returns (uint256) {\n uint256 snapshotZUSDDebt = rewardSnapshots[_borrower].ZUSDDebt;\n uint256 rewardPerUnitStaked = L_ZUSDDebt.sub(snapshotZUSDDebt);\n\n if (rewardPerUnitStaked == 0 || Troves[_borrower].status != Status.active) {\n return 0;\n }\n\n uint256 stake = Troves[_borrower].stake;\n\n uint256 pendingZUSDDebtReward = stake.mul(rewardPerUnitStaked).div(DECIMAL_PRECISION);\n\n return pendingZUSDDebtReward;\n }\n\n /// Add the borrowers's coll and debt rewards earned from redistributions, to their Trove\n function _applyPendingRewards(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n address _borrower\n ) internal {\n if (_hasPendingRewards(_borrower)) {\n _requireTroveIsActive(_borrower);\n\n // Compute pending rewards\n uint256 pendingETHReward = _getPendingETHReward(_borrower);\n uint256 pendingZUSDDebtReward = _getPendingZUSDDebtReward(_borrower);\n\n // Apply pending rewards to trove's state\n Troves[_borrower].coll = Troves[_borrower].coll.add(pendingETHReward);\n Troves[_borrower].debt = Troves[_borrower].debt.add(pendingZUSDDebtReward);\n\n _updateTroveRewardSnapshots(_borrower);\n\n // Transfer from DefaultPool to ActivePool\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n pendingZUSDDebtReward,\n pendingETHReward\n );\n\n emit TroveUpdated(\n _borrower,\n Troves[_borrower].debt,\n Troves[_borrower].coll,\n Troves[_borrower].stake,\n TroveManagerOperation.applyPendingRewards\n );\n }\n }\n\n function _hasPendingRewards(address _borrower) public view returns (bool) {\n /*\n * A Trove has pending rewards if its snapshot is less than the current rewards per-unit-staked sum:\n * this indicates that rewards have occured since the snapshot was made, and the user therefore has\n * pending rewards\n */\n if (Troves[_borrower].status != Status.active) {\n return false;\n }\n\n return (rewardSnapshots[_borrower].ETH < L_ETH);\n }\n\n function _updateTroveRewardSnapshots(address _borrower) internal {\n rewardSnapshots[_borrower].ETH = L_ETH;\n rewardSnapshots[_borrower].ZUSDDebt = L_ZUSDDebt;\n emit TroveSnapshotsUpdated(L_ETH, L_ZUSDDebt);\n }\n\n /// Move a Trove's pending debt and collateral rewards from distributions, from the Default Pool to the Active Pool\n function _movePendingTroveRewardsToActivePool(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _ZUSD,\n uint256 _ETH\n ) internal {\n _defaultPool.decreaseZUSDDebt(_ZUSD);\n _activePool.increaseZUSDDebt(_ZUSD);\n _defaultPool.sendETHToActivePool(_ETH);\n }\n\n /// Remove borrower's stake from the totalStakes sum, and set their stake to 0\n function _removeStake(address _borrower) internal {\n uint256 stake = Troves[_borrower].stake;\n totalStakes = totalStakes.sub(stake);\n Troves[_borrower].stake = 0;\n }\n\n function _closeTrove(address _borrower, Status closedStatus) internal {\n assert(closedStatus != Status.nonExistent && closedStatus != Status.active);\n\n uint256 TroveOwnersArrayLength = TroveOwners.length;\n _requireMoreThanOneTroveInSystem(TroveOwnersArrayLength);\n\n Troves[_borrower].status = closedStatus;\n Troves[_borrower].coll = 0;\n Troves[_borrower].debt = 0;\n\n rewardSnapshots[_borrower].ETH = 0;\n rewardSnapshots[_borrower].ZUSDDebt = 0;\n\n _removeTroveOwner(_borrower, TroveOwnersArrayLength);\n sortedTroves.remove(_borrower);\n }\n\n /// Update borrower's stake based on their latest collateral value\n function _updateStakeAndTotalStakes(address _borrower) internal returns (uint256) {\n uint256 newStake = _computeNewStake(Troves[_borrower].coll);\n uint256 oldStake = Troves[_borrower].stake;\n Troves[_borrower].stake = newStake;\n\n totalStakes = totalStakes.sub(oldStake).add(newStake);\n emit TotalStakesUpdated(totalStakes);\n\n return newStake;\n }\n\n // Calculate a new stake based on the snapshots of the totalStakes and totalCollateral taken at the last liquidation\n function _computeNewStake(uint256 _coll) internal view returns (uint256) {\n uint256 stake;\n if (totalCollateralSnapshot == 0) {\n stake = _coll;\n } else {\n /*\n * The following assert() holds true because:\n * - The system always contains >= 1 trove\n * - When we close or liquidate a trove, we redistribute the pending rewards, so if all troves were closed/liquidated,\n * rewards would’ve been emptied and totalCollateralSnapshot would be zero too.\n */\n assert(totalStakesSnapshot > 0);\n stake = _coll.mul(totalStakesSnapshot).div(totalCollateralSnapshot);\n }\n return stake;\n }\n\n function _calcDecayedBaseRate() internal view returns (uint256) {\n uint256 minutesPassed = _minutesPassedSinceLastFeeOp();\n uint256 decayFactor = LiquityMath._decPow(MINUTE_DECAY_FACTOR, minutesPassed);\n\n return baseRate.mul(decayFactor).div(DECIMAL_PRECISION);\n }\n\n function _minutesPassedSinceLastFeeOp() internal view returns (uint256) {\n return (block.timestamp.sub(lastFeeOperationTime)).div(SECONDS_IN_ONE_MINUTE);\n }\n\n // Update the last fee operation time only if time passed >= decay interval. This prevents base rate griefing.\n function _updateLastFeeOpTime() internal {\n uint256 timePassed = block.timestamp.sub(lastFeeOperationTime);\n\n if (timePassed >= SECONDS_IN_ONE_MINUTE) {\n lastFeeOperationTime = block.timestamp;\n emit LastFeeOpTimeUpdated(block.timestamp);\n }\n }\n\n function _calcRedemptionFee(\n uint256 _redemptionRate,\n uint256 _ETHDrawn\n ) internal pure returns (uint256) {\n uint256 redemptionFee = _redemptionRate.mul(_ETHDrawn).div(DECIMAL_PRECISION);\n require(\n redemptionFee < _ETHDrawn,\n \"TroveManager: Fee would eat up all returned collateral\"\n );\n return redemptionFee;\n }\n\n function _getRedemptionRate() public view returns (uint256) {\n return _calcRedemptionRate(baseRate);\n }\n\n function _getRedemptionFee(uint256 _ETHDrawn) internal view returns (uint256) {\n return _calcRedemptionFee(_getRedemptionRate(), _ETHDrawn);\n }\n\n function _calcRedemptionRate(uint256 _baseRate) internal view returns (uint256) {\n return\n LiquityMath._min(\n liquityBaseParams.REDEMPTION_FEE_FLOOR().add(_baseRate),\n DECIMAL_PRECISION // cap at a maximum of 100%\n );\n }\n\n /**\n Remove a Trove owner from the TroveOwners array, not preserving array order. Removing owner 'B' does the following:\n [A B C D E] => [A E C D], and updates E's Trove struct to point to its new array index.\n */\n function _removeTroveOwner(address _borrower, uint256 TroveOwnersArrayLength) internal {\n Status troveStatus = Troves[_borrower].status;\n // It’s set in caller function `_closeTrove`\n assert(troveStatus != Status.nonExistent && troveStatus != Status.active);\n\n uint128 index = Troves[_borrower].arrayIndex;\n uint256 length = TroveOwnersArrayLength;\n uint256 idxLast = length.sub(1);\n\n assert(index <= idxLast);\n\n address addressToMove = TroveOwners[idxLast];\n\n TroveOwners[index] = addressToMove;\n Troves[addressToMove].arrayIndex = index;\n emit TroveIndexUpdated(addressToMove, index);\n\n TroveOwners.pop();\n }\n\n // --- 'require' wrapper functions ---\n\n function _requireCallerIsBorrowerOperations() internal view {\n require(\n msg.sender == borrowerOperationsAddress,\n \"TroveManager: Caller is not the BorrowerOperations contract\"\n );\n }\n\n function _requireTroveIsActive(address _borrower) internal view {\n require(\n Troves[_borrower].status == Status.active,\n \"TroveManager: Trove does not exist or is closed\"\n );\n }\n\n function _requireZUSDBalanceCoversRedemption(\n IZUSDToken _zusdToken,\n address _redeemer,\n uint256 _amount\n ) internal view {\n require(\n _zusdToken.balanceOf(_redeemer) >= _amount,\n \"TroveManager: Requested redemption amount must be <= user's ZUSD token balance\"\n );\n }\n\n function _requireMoreThanOneTroveInSystem(uint256 TroveOwnersArrayLength) internal view {\n require(\n TroveOwnersArrayLength > 1 && sortedTroves.getSize() > 1,\n \"TroveManager: Only one trove in the system\"\n );\n }\n\n function _requireAmountGreaterThanZero(uint256 _amount) internal pure {\n require(_amount > 0, \"TroveManager: Amount must be greater than zero\");\n }\n\n function _requireTCRoverMCR(uint256 _price) internal view {\n require(\n _getTCR(_price) >= liquityBaseParams.MCR(),\n \"TroveManager: Cannot redeem when TCR < MCR\"\n );\n }\n\n function _requireAfterBootstrapPeriod() internal view {\n uint256 systemDeploymentTime = _zeroToken.getDeploymentStartTime();\n require(\n block.timestamp >= systemDeploymentTime.add(BOOTSTRAP_PERIOD),\n \"TroveManager: Redemptions are not allowed during bootstrap phase\"\n );\n }\n\n function _requireValidMaxFeePercentage(uint256 _maxFeePercentage) internal view {\n require(\n _maxFeePercentage >= liquityBaseParams.REDEMPTION_FEE_FLOOR() &&\n _maxFeePercentage <= DECIMAL_PRECISION,\n \"Max fee percentage must be between 0.5% and 100%\"\n );\n }\n}\n" + }, + "contracts/Dependencies/TroveManagerRedeemOps.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../Dependencies/Mynt/MyntLib.sol\";\nimport \"../Interfaces/IBorrowerOperations.sol\";\nimport \"./TroveManagerBase.sol\";\n\n/// This contract is designed to be used via delegatecall from the TroveManager contract\n/// TroveManagerBase constructor param is bootsrap period when redemptions are not allowed\ncontract TroveManagerRedeemOps is TroveManagerBase {\n /** Send _ZUSDamount ZUSD to the system and redeem the corresponding amount of collateral from as many Troves as are needed to fill the redemption\n request. Applies pending rewards to a Trove before reducing its debt and coll.\n \n Note that if _amount is very large, this function can run out of gas, specially if traversed troves are small. This can be easily avoided by\n splitting the total _amount in appropriate chunks and calling the function multiple times.\n \n Param `_maxIterations` can also be provided, so the loop through Troves is capped (if it’s zero, it will be ignored).This makes it easier to\n avoid OOG for the frontend, as only knowing approximately the average cost of an iteration is enough, without needing to know the “topology”\n of the trove list. It also avoids the need to set the cap in stone in the contract, nor doing gas calculations, as both gas price and opcode\n costs can vary.\n \n All Troves that are redeemed from -- with the likely exception of the last one -- will end up with no debt left, therefore they will be closed.\n If the last Trove does have some remaining debt, it has a finite ICR, and the reinsertion could be anywhere in the list, therefore it requires a hint.\n A frontend should use getRedemptionHints() to calculate what the ICR of this Trove will be after redemption, and pass a hint for its position\n in the sortedTroves list along with the ICR value that the hint was found for.\n \n If another transaction modifies the list between calling getRedemptionHints() and passing the hints to redeemCollateral(), it\n is very likely that the last (partially) redeemed Trove would end up with a different ICR than what the hint is for. In this case the\n redemption will stop after the last completely redeemed Trove and the sender will keep the remaining ZUSD amount, which they can attempt\n to redeem later.\n */\n\n constructor(uint256 _bootstrapPeriod) public TroveManagerBase(_bootstrapPeriod) {}\n\n function redeemCollateral(\n uint256 _ZUSDamount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage\n ) external {\n _redeemCollateral(\n _ZUSDamount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n _maxIterations,\n _maxFeePercentage\n );\n }\n\n function _redeemCollateral(\n uint256 _ZUSDamount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage\n ) internal {\n ContractsCache memory contractsCache = ContractsCache(\n activePool,\n defaultPool,\n _zusdToken,\n _zeroStaking,\n sortedTroves,\n collSurplusPool,\n gasPoolAddress\n );\n RedemptionTotals memory totals;\n\n _requireValidMaxFeePercentage(_maxFeePercentage);\n _requireAfterBootstrapPeriod();\n totals.price = priceFeed.fetchPrice();\n _requireTCRoverMCR(totals.price);\n _requireAmountGreaterThanZero(_ZUSDamount);\n _requireZUSDBalanceCoversRedemption(contractsCache.zusdToken, msg.sender, _ZUSDamount);\n\n totals.totalZUSDSupplyAtStart = getEntireSystemDebt();\n // Confirm redeemer's balance is less than total ZUSD supply\n assert(contractsCache.zusdToken.balanceOf(msg.sender) <= totals.totalZUSDSupplyAtStart);\n\n totals.remainingZUSD = _ZUSDamount;\n address currentBorrower;\n\n if (\n _isValidFirstRedemptionHint(\n contractsCache.sortedTroves,\n _firstRedemptionHint,\n totals.price\n )\n ) {\n currentBorrower = _firstRedemptionHint;\n } else {\n currentBorrower = contractsCache.sortedTroves.getLast();\n // Find the first trove with ICR >= MCR\n while (\n currentBorrower != address(0) &&\n _getCurrentICR(currentBorrower, totals.price) < liquityBaseParams.MCR()\n ) {\n currentBorrower = contractsCache.sortedTroves.getPrev(currentBorrower);\n }\n }\n\n // Loop through the Troves starting from the one with lowest collateral ratio until _amount of ZUSD is exchanged for collateral\n if (_maxIterations == 0) {\n _maxIterations = uint256(-1);\n }\n while (currentBorrower != address(0) && totals.remainingZUSD > 0 && _maxIterations > 0) {\n _maxIterations--;\n // Save the address of the Trove preceding the current one, before potentially modifying the list\n address nextUserToCheck = contractsCache.sortedTroves.getPrev(currentBorrower);\n\n _applyPendingRewards(\n contractsCache.activePool,\n contractsCache.defaultPool,\n currentBorrower\n );\n\n SingleRedemptionValues memory singleRedemption = _redeemCollateralFromTrove(\n contractsCache,\n currentBorrower,\n totals.remainingZUSD,\n totals.price,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR\n );\n\n if (singleRedemption.cancelledPartial) break; // Partial redemption was cancelled (out-of-date hint, or new net debt < minimum), therefore we could not redeem from the last Trove\n\n totals.totalZUSDToRedeem = totals.totalZUSDToRedeem.add(singleRedemption.ZUSDLot);\n totals.totalETHDrawn = totals.totalETHDrawn.add(singleRedemption.ETHLot);\n\n totals.remainingZUSD = totals.remainingZUSD.sub(singleRedemption.ZUSDLot);\n currentBorrower = nextUserToCheck;\n }\n require(totals.totalETHDrawn > 0, \"TroveManager: Unable to redeem any amount\");\n\n // Decay the baseRate due to time passed, and then increase it according to the size of this redemption.\n // Use the saved total ZUSD supply value, from before it was reduced by the redemption.\n _updateBaseRateFromRedemption(\n totals.totalETHDrawn,\n totals.price,\n totals.totalZUSDSupplyAtStart\n );\n\n // Calculate the ETH fee\n totals.ETHFee = _getRedemptionFee(totals.totalETHDrawn);\n\n _requireUserAcceptsFee(totals.ETHFee, totals.totalETHDrawn, _maxFeePercentage);\n\n // Send the ETH fee to the feeDistributorContract address\n contractsCache.activePool.sendETH(address(feeDistributor), totals.ETHFee);\n feeDistributor.distributeFees();\n\n totals.ETHToSendToRedeemer = totals.totalETHDrawn.sub(totals.ETHFee);\n\n emit Redemption(\n _ZUSDamount,\n totals.totalZUSDToRedeem,\n totals.totalETHDrawn,\n totals.ETHFee\n );\n\n // Burn the total ZUSD that is cancelled with debt, and send the redeemed ETH to msg.sender\n contractsCache.zusdToken.burn(msg.sender, totals.totalZUSDToRedeem);\n // Update Active Pool ZUSD, and send ETH to account\n contractsCache.activePool.decreaseZUSDDebt(totals.totalZUSDToRedeem);\n contractsCache.activePool.sendETH(msg.sender, totals.ETHToSendToRedeemer);\n }\n\n ///DLLR _owner can use Sovryn Mynt to convert DLLR to ZUSD, then use the Zero redemption mechanism to redeem ZUSD for RBTC, all in a single transaction\n function redeemCollateralViaDLLR(\n uint256 _dllrAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage,\n IMassetManager.PermitParams calldata _permitParams\n ) external {\n uint256 _zusdAmount = MyntLib.redeemZusdFromDllrWithPermit(\n IBorrowerOperations(borrowerOperationsAddress).getMassetManager(),\n _dllrAmount,\n address(_zusdToken),\n _permitParams\n );\n _redeemCollateral(\n _zusdAmount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n _maxIterations,\n _maxFeePercentage\n );\n }\n\n function _isValidFirstRedemptionHint(\n ISortedTroves _sortedTroves,\n address _firstRedemptionHint,\n uint256 _price\n ) internal view returns (bool) {\n if (\n _firstRedemptionHint == address(0) ||\n !_sortedTroves.contains(_firstRedemptionHint) ||\n _getCurrentICR(_firstRedemptionHint, _price) < liquityBaseParams.MCR()\n ) {\n return false;\n }\n\n address nextTrove = _sortedTroves.getNext(_firstRedemptionHint);\n return\n nextTrove == address(0) || _getCurrentICR(nextTrove, _price) < liquityBaseParams.MCR();\n }\n\n /// Redeem as much collateral as possible from _borrower's Trove in exchange for ZUSD up to _maxZUSDamount\n function _redeemCollateralFromTrove(\n ContractsCache memory _contractsCache,\n address _borrower,\n uint256 _maxZUSDamount,\n uint256 _price,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR\n ) internal returns (SingleRedemptionValues memory singleRedemption) {\n // Determine the remaining amount (lot) to be redeemed, capped by the entire debt of the Trove minus the liquidation reserve\n singleRedemption.ZUSDLot = LiquityMath._min(\n _maxZUSDamount,\n Troves[_borrower].debt.sub(ZUSD_GAS_COMPENSATION)\n );\n\n // Get the ETHLot of equivalent value in USD\n singleRedemption.ETHLot = singleRedemption.ZUSDLot.mul(DECIMAL_PRECISION).div(_price);\n\n // Decrease the debt and collateral of the current Trove according to the ZUSD lot and corresponding ETH to send\n uint256 newDebt = (Troves[_borrower].debt).sub(singleRedemption.ZUSDLot);\n uint256 newColl = (Troves[_borrower].coll).sub(singleRedemption.ETHLot);\n\n if (newDebt == ZUSD_GAS_COMPENSATION) {\n // No debt left in the Trove (except for the liquidation reserve), therefore the trove gets closed\n _removeStake(_borrower);\n _closeTrove(_borrower, Status.closedByRedemption);\n _redeemCloseTrove(_contractsCache, _borrower, ZUSD_GAS_COMPENSATION, newColl);\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.redeemCollateral);\n } else {\n uint256 newNICR = LiquityMath._computeNominalCR(newColl, newDebt);\n\n /*\n * If the provided hint is out of date, we bail since trying to reinsert without a good hint will almost\n * certainly result in running out of gas.\n *\n * If the resultant net debt of the partial is less than the minimum, net debt we bail.\n */\n if (newNICR != _partialRedemptionHintNICR || _getNetDebt(newDebt) < MIN_NET_DEBT) {\n singleRedemption.cancelledPartial = true;\n return singleRedemption;\n }\n\n _contractsCache.sortedTroves.reInsert(\n _borrower,\n newNICR,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint\n );\n\n Troves[_borrower].debt = newDebt;\n Troves[_borrower].coll = newColl;\n _updateStakeAndTotalStakes(_borrower);\n\n emit TroveUpdated(\n _borrower,\n newDebt,\n newColl,\n Troves[_borrower].stake,\n TroveManagerOperation.redeemCollateral\n );\n }\n\n return singleRedemption;\n }\n\n /**\n This function has two impacts on the baseRate state variable:\n 1) decays the baseRate based on time passed since last redemption or ZUSD borrowing operation.\n then,\n 2) increases the baseRate based on the amount redeemed, as a proportion of total supply\n */\n function _updateBaseRateFromRedemption(\n uint256 _ETHDrawn,\n uint256 _price,\n uint256 _totalZUSDSupply\n ) internal returns (uint256) {\n uint256 decayedBaseRate = _calcDecayedBaseRate();\n\n /* Convert the drawn ETH back to ZUSD at face value rate (1 ZUSD:1 USD), in order to get\n * the fraction of total supply that was redeemed at face value. */\n uint256 redeemedZUSDFraction = _ETHDrawn.mul(_price).div(_totalZUSDSupply);\n\n uint256 newBaseRate = decayedBaseRate.add(redeemedZUSDFraction.div(BETA));\n newBaseRate = LiquityMath._min(newBaseRate, DECIMAL_PRECISION); // cap baseRate at a maximum of 100%\n //assert(newBaseRate <= DECIMAL_PRECISION); // This is already enforced in the line above\n assert(newBaseRate > 0); // Base rate is always non-zero after redemption\n\n // Update the baseRate state variable\n baseRate = newBaseRate;\n emit BaseRateUpdated(newBaseRate);\n\n _updateLastFeeOpTime();\n\n return newBaseRate;\n }\n\n /**\n Called when a full redemption occurs, and closes the trove.\n The redeemer swaps (debt - liquidation reserve) ZUSD for (debt - liquidation reserve) worth of ETH, so the ZUSD liquidation reserve left corresponds to the remaining debt.\n In order to close the trove, the ZUSD liquidation reserve is burned, and the corresponding debt is removed from the active pool.\n The debt recorded on the trove's struct is zero'd elswhere, in _closeTrove.\n Any surplus ETH left in the trove, is sent to the Coll surplus pool, and can be later claimed by the borrower.\n */\n function _redeemCloseTrove(\n ContractsCache memory _contractsCache,\n address _borrower,\n uint256 _ZUSD,\n uint256 _ETH\n ) internal {\n _contractsCache.zusdToken.burn(gasPoolAddress, _ZUSD);\n // Update Active Pool ZUSD, and send ETH to account\n _contractsCache.activePool.decreaseZUSDDebt(_ZUSD);\n\n // send ETH from Active Pool to CollSurplus Pool\n _contractsCache.collSurplusPool.accountSurplus(_borrower, _ETH);\n _contractsCache.activePool.sendETH(address(_contractsCache.collSurplusPool), _ETH);\n }\n}\n" + }, + "contracts/FeeDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/LiquityMath.sol\";\nimport \"./FeeDistributorStorage.sol\";\nimport \"./Dependencies/SafeMath.sol\";\n\ncontract FeeDistributor is CheckContract, FeeDistributorStorage, IFeeDistributor {\n using SafeMath for uint256;\n // --- Events ---\n\n event FeeSharingCollectorAddressChanged(address _feeSharingCollectorAddress);\n event ZeroStakingAddressChanged(address _zeroStakingAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event WrbtcAddressChanged(address _wrbtcAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event ZUSDDistributed(uint256 _zusdDistributedAmount);\n event RBTCistributed(uint256 _rbtcDistributedAmount);\n\n // --- Dependency setters ---\n\n function setAddresses(\n address _feeSharingCollectorAddress,\n address _zeroStakingAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _wrbtcAddress,\n address _zusdTokenAddress,\n address _activePoolAddress\n ) external override onlyOwner {\n checkContract(_feeSharingCollectorAddress);\n checkContract(_zeroStakingAddress);\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_wrbtcAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_activePoolAddress);\n\n feeSharingCollector = IFeeSharingCollector(_feeSharingCollectorAddress);\n zeroStaking = IZEROStaking(_zeroStakingAddress);\n borrowerOperations = IBorrowerOperations(_borrowerOperationsAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n wrbtc = IWrbtc(_wrbtcAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n activePoolAddress = _activePoolAddress;\n\n // Not entirely removing this as per request from @light\n FEE_TO_FEE_SHARING_COLLECTOR = LiquityMath.DECIMAL_PRECISION; // 100%\n\n emit FeeSharingCollectorAddressChanged(_feeSharingCollectorAddress);\n emit ZeroStakingAddressChanged(_zeroStakingAddress);\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit WrbtcAddressChanged(_wrbtcAddress);\n emit ZUSDTokenAddressChanged(_zusdTokenAddress);\n emit ActivePoolAddressSet(_activePoolAddress);\n }\n\n function setFeeToFeeSharingCollector(uint256 FEE_TO_FEE_SHARING_COLLECTOR_) public onlyOwner {\n FEE_TO_FEE_SHARING_COLLECTOR = FEE_TO_FEE_SHARING_COLLECTOR_;\n }\n\n function distributeFees() public override {\n require(\n msg.sender == address(borrowerOperations) || msg.sender == address(troveManager),\n \"FeeDistributor: invalid caller\"\n );\n uint256 zusdtoDistribute = zusdToken.balanceOf(address(this));\n uint256 rbtcToDistribute = address(this).balance;\n if (zusdtoDistribute != 0) {\n _distributeZUSD(zusdtoDistribute);\n }\n if (rbtcToDistribute != 0) {\n _distributeRBTC(rbtcToDistribute);\n }\n }\n\n function _distributeZUSD(uint256 toDistribute) internal {\n // Send fee to the FeeSharingCollector address\n uint256 feeToFeeSharingCollector = toDistribute.mul(FEE_TO_FEE_SHARING_COLLECTOR).div(\n LiquityMath.DECIMAL_PRECISION\n );\n zusdToken.approve(address(feeSharingCollector), feeToFeeSharingCollector);\n\n feeSharingCollector.transferTokens(address(zusdToken), uint96(feeToFeeSharingCollector));\n // Send fee to ZERO staking contract\n uint256 feeToZeroStaking = toDistribute.sub(feeToFeeSharingCollector);\n if (feeToZeroStaking != 0) {\n require(\n zusdToken.transfer(address(zeroStaking), feeToZeroStaking),\n \"Coudn't execute ZUSD transfer\"\n );\n zeroStaking.increaseF_ZUSD(feeToZeroStaking);\n }\n emit ZUSDDistributed(toDistribute);\n }\n\n function _distributeRBTC(uint256 toDistribute) internal {\n // Send fee to the feeSharingCollector address\n uint256 feeToFeeSharingCollector = toDistribute.mul(FEE_TO_FEE_SHARING_COLLECTOR).div(\n LiquityMath.DECIMAL_PRECISION\n );\n\n feeSharingCollector.transferRBTC{ value: feeToFeeSharingCollector }();\n\n // Send the ETH fee to the ZERO staking contract\n uint256 feeToZeroStaking = toDistribute.sub(feeToFeeSharingCollector);\n if (feeToZeroStaking != 0) {\n (bool success, ) = address(zeroStaking).call{ value: feeToZeroStaking }(\"\");\n require(success, \"FeeDistributor: sending ETH failed\");\n zeroStaking.increaseF_ETH(feeToZeroStaking);\n }\n emit RBTCistributed(toDistribute);\n }\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"FeeDistributor: caller is not ActivePool\");\n }\n\n receive() external payable {\n _requireCallerIsActivePool();\n }\n}\n" + }, + "contracts/FeeDistributorStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IFeeSharingCollector.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IWrbtc.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract FeeDistributorStorage is Ownable {\n string public constant NAME = \"FeeDistributor\";\n\n // --- Connected contract declarations ---\n\n IFeeSharingCollector public feeSharingCollector;\n\n IZEROStaking public zeroStaking;\n\n IBorrowerOperations public borrowerOperations;\n\n ITroveManager public troveManager;\n\n IWrbtc public wrbtc;\n\n IZUSDToken public zusdToken;\n\n address public activePoolAddress;\n\n //pct of fees sent to feeSharingCollector address\n uint256 public FEE_TO_FEE_SHARING_COLLECTOR;\n}\n" + }, + "contracts/GasPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * The purpose of this contract is to hold ZUSD tokens for gas compensation:\n * https://github.com/DistributedCollective/zero#gas-compensation\n * When a borrower opens a trove, an additional 50 ZUSD debt is issued,\n * and 50 ZUSD is minted and sent to this contract.\n * When a borrower closes their active trove, this gas compensation is refunded:\n * 50 ZUSD is burned from the this contract's balance, and the corresponding\n * 50 ZUSD debt on the trove is cancelled.\n * See this issue for more context: https://github.com/liquity/dev/issues/186\n */\ncontract GasPool {\n // do nothing, as the core contracts have permission to send to and burn from this address\n}\n" + }, + "contracts/HintHelpers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./HintHelpersStorage.sol\";\n\ncontract HintHelpers is LiquityBase, HintHelpersStorage, CheckContract {\n // --- Events ---\n\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event TroveManagerAddressChanged(address _troveManagerAddress);\n\n // --- Dependency setters ---\n\n function setAddresses(\n address _liquityBaseParamsAddress,\n address _sortedTrovesAddress,\n address _troveManagerAddress\n ) external onlyOwner {\n checkContract(_liquityBaseParamsAddress);\n checkContract(_sortedTrovesAddress);\n checkContract(_troveManagerAddress);\n\n liquityBaseParams = ILiquityBaseParams(_liquityBaseParamsAddress);\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n\n emit SortedTrovesAddressChanged(_sortedTrovesAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n }\n\n // --- Functions ---\n\n /** getRedemptionHints() - Helper function for finding the right hints to pass to redeemCollateral().\n *\n * It simulates a redemption of `_ZUSDamount` to figure out where the redemption sequence will start and what state the final Trove\n * of the sequence will end up in.\n *\n * Returns three hints:\n * - `firstRedemptionHint` is the address of the first Trove with ICR >= MCR (i.e. the first Trove that will be redeemed).\n * - `partialRedemptionHintNICR` is the final nominal ICR of the last Trove of the sequence after being hit by partial redemption,\n * or zero in case of no partial redemption.\n * - `truncatedZUSDamount` is the maximum amount that can be redeemed out of the the provided `_ZUSDamount`. This can be lower than\n * `_ZUSDamount` when redeeming the full amount would leave the last Trove of the redemption sequence with less net debt than the\n * minimum allowed value (i.e. MIN_NET_DEBT).\n *\n * The number of Troves to consider for redemption can be capped by passing a non-zero value as `_maxIterations`, while passing zero\n * will leave it uncapped.\n */\n\n function getRedemptionHints(\n uint256 _ZUSDamount,\n uint256 _price,\n uint256 _maxIterations\n )\n external\n view\n returns (\n address firstRedemptionHint,\n uint256 partialRedemptionHintNICR,\n uint256 truncatedZUSDamount\n )\n {\n ISortedTroves sortedTrovesCached = sortedTroves;\n\n uint256 remainingZUSD = _ZUSDamount;\n address currentTroveuser = sortedTrovesCached.getLast();\n\n while (\n currentTroveuser != address(0) &&\n troveManager.getCurrentICR(currentTroveuser, _price) < liquityBaseParams.MCR()\n ) {\n currentTroveuser = sortedTrovesCached.getPrev(currentTroveuser);\n }\n\n firstRedemptionHint = currentTroveuser;\n\n if (_maxIterations == 0) {\n _maxIterations = uint256(-1);\n }\n\n while (currentTroveuser != address(0) && remainingZUSD > 0 && _maxIterations-- > 0) {\n uint256 netZUSDDebt = _getNetDebt(troveManager.getTroveDebt(currentTroveuser)).add(\n troveManager.getPendingZUSDDebtReward(currentTroveuser)\n );\n\n if (netZUSDDebt > remainingZUSD) {\n if (netZUSDDebt > MIN_NET_DEBT) {\n uint256 maxRedeemableZUSD = LiquityMath._min(\n remainingZUSD,\n netZUSDDebt.sub(MIN_NET_DEBT)\n );\n\n uint256 ETH = troveManager.getTroveColl(currentTroveuser).add(\n troveManager.getPendingETHReward(currentTroveuser)\n );\n\n uint256 newColl = ETH.sub(\n maxRedeemableZUSD.mul(DECIMAL_PRECISION).div(_price)\n );\n uint256 newDebt = netZUSDDebt.sub(maxRedeemableZUSD);\n\n uint256 compositeDebt = _getCompositeDebt(newDebt);\n partialRedemptionHintNICR = LiquityMath._computeNominalCR(\n newColl,\n compositeDebt\n );\n\n remainingZUSD = remainingZUSD.sub(maxRedeemableZUSD);\n }\n break;\n } else {\n remainingZUSD = remainingZUSD.sub(netZUSDDebt);\n }\n\n currentTroveuser = sortedTrovesCached.getPrev(currentTroveuser);\n }\n\n truncatedZUSDamount = _ZUSDamount.sub(remainingZUSD);\n }\n\n /** getApproxHint() - return address of a Trove that is, on average, (length / numTrials) positions away in the \n sortedTroves list from the correct insert position of the Trove to be inserted. \n \n Note: The output address is worst-case O(n) positions away from the correct insert position, however, the function \n is probabilistic. Input can be tuned to guarantee results to a high degree of confidence, e.g:\n\n Submitting numTrials = k * sqrt(length), with k = 15 makes it very, very likely that the ouput address will \n be <= sqrt(length) positions away from the correct insert position.\n */\n function getApproxHint(\n uint256 _CR,\n uint256 _numTrials,\n uint256 _inputRandomSeed\n )\n external\n view\n returns (\n address hintAddress,\n uint256 diff,\n uint256 latestRandomSeed\n )\n {\n uint256 arrayLength = troveManager.getTroveOwnersCount();\n\n if (arrayLength == 0) {\n return (address(0), 0, _inputRandomSeed);\n }\n\n hintAddress = sortedTroves.getLast();\n diff = LiquityMath._getAbsoluteDifference(_CR, troveManager.getNominalICR(hintAddress));\n latestRandomSeed = _inputRandomSeed;\n\n uint256 i = 1;\n\n while (i < _numTrials) {\n latestRandomSeed = uint256(keccak256(abi.encodePacked(latestRandomSeed)));\n\n uint256 arrayIndex = latestRandomSeed % arrayLength;\n address currentAddress = troveManager.getTroveFromTroveOwnersArray(arrayIndex);\n uint256 currentNICR = troveManager.getNominalICR(currentAddress);\n\n // check if abs(current - CR) > abs(closest - CR), and update closest if current is closer\n uint256 currentDiff = LiquityMath._getAbsoluteDifference(currentNICR, _CR);\n\n if (currentDiff < diff) {\n diff = currentDiff;\n hintAddress = currentAddress;\n }\n i++;\n }\n }\n\n function computeNominalCR(uint256 _coll, uint256 _debt) external pure returns (uint256) {\n return LiquityMath._computeNominalCR(_coll, _debt);\n }\n\n function computeCR(\n uint256 _coll,\n uint256 _debt,\n uint256 _price\n ) external pure returns (uint256) {\n return LiquityMath._computeCR(_coll, _debt, _price);\n }\n}\n" + }, + "contracts/HintHelpersStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract HintHelpersStorage is Ownable {\n string public constant NAME = \"HintHelpers\";\n\n ISortedTroves public sortedTroves;\n ITroveManager public troveManager;\n}\n" + }, + "contracts/Interfaces/IActivePool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IPool.sol\";\n\n/**\n * The Active Pool holds the ETH collateral and ZUSD debt (but not ZUSD tokens) for all active troves.\n *\n * When a trove is liquidated, it's ETH and ZUSD debt are transferred from the Active Pool, to either the\n * Stability Pool, the Default Pool, or both, depending on the liquidation conditions.\n *\n */\ninterface IActivePool is IPool {\n // --- Events ---\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolZUSDDebtUpdated(uint _ZUSDDebt);\n event ActivePoolETHBalanceUpdated(uint _ETH);\n\n // --- Functions ---\n\n /// @notice Send ETH amount to given account. Updates ActivePool balance. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _account account to receive the ETH amount\n /// @param _amount ETH amount to send\n function sendETH(address _account, uint _amount) external;\n}\n" + }, + "contracts/Interfaces/IBalanceRedirectPresale.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IBalanceRedirectPresale {\n\n function isClosed() external view returns (bool);\n}" + }, + "contracts/Interfaces/IBorrowerOperations.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../Dependencies/Mynt/IMassetManager.sol\";\n\n/// Common interface for the Trove Manager.\ninterface IBorrowerOperations {\n // --- Events ---\n\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n\n event TroveCreated(address indexed _borrower, uint256 arrayIndex);\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 stake,\n uint8 operation\n );\n event ZUSDBorrowingFeePaid(address indexed _borrower, uint256 _ZUSDFee);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _feeDistributorAddress feeDistributor contract address\n * @param _liquityBaseParamsAddress LiquidityBaseParams contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _activePoolAddress ActivePool contract address\n * @param _defaultPoolAddress DefaultPool contract address\n * @param _stabilityPoolAddress StabilityPool contract address\n * @param _gasPoolAddress GasPool contract address\n * @param _collSurplusPoolAddress CollSurplusPool contract address\n * @param _priceFeedAddress PrideFeed contract address\n * @param _sortedTrovesAddress SortedTroves contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _zeroStakingAddress ZEROStaking contract address\n */\n function setAddresses(\n address _feeDistributorAddress,\n address _liquityBaseParamsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _defaultPoolAddress,\n address _stabilityPoolAddress,\n address _gasPoolAddress,\n address _collSurplusPoolAddress,\n address _priceFeedAddress,\n address _sortedTrovesAddress,\n address _zusdTokenAddress,\n address _zeroStakingAddress\n ) external;\n\n /**\n * @notice payable function that creates a Trove for the caller with the requested debt, and the Ether received as collateral.\n * Successful execution is conditional mainly on the resulting collateralization ratio which must exceed the minimum (110% in Normal Mode, 150% in Recovery Mode).\n * In addition to the requested debt, extra debt is issued to pay the issuance fee, and cover the gas compensation.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _ZUSDAmount ZUSD requested debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function openTrove(\n uint256 _maxFee,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /**\n * @notice payable function that creates a Trove for the caller with the requested debt, and the Ether received as collateral.\n * Successful execution is conditional mainly on the resulting collateralization ratio which must exceed the minimum (110% in Normal Mode, 150% in Recovery Mode).\n * In addition to the requested debt, extra debt is issued to pay the issuance fee, and cover the gas compensation.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * This method is identical to `openTrove()`, but operates on NUE tokens instead of ZUSD.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _ZUSDAmount ZUSD requested debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function openNueTrove(\n uint256 _maxFee,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /// @notice payable function that adds the received Ether to the caller's active Trove.\n /// @param _upperHint upper trove id hint\n /// @param _lowerHint lower trove id hint\n function addColl(address _upperHint, address _lowerHint) external payable;\n\n /// @notice send ETH as collateral to a trove. Called by only the Stability Pool.\n /// @param _user user trove address\n /// @param _upperHint upper trove id hint\n /// @param _lowerHint lower trove id hint\n function moveETHGainToTrove(\n address _user,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /**\n * @notice withdraws `_amount` of collateral from the caller’s Trove.\n * Executes only if the user has an active Trove, the withdrawal would not pull the user’s Trove below the minimum collateralization ratio,\n * and the resulting total collateralization ratio of the system is above 150%.\n * @param _amount collateral amount to withdraw\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function withdrawColl(uint256 _amount, address _upperHint, address _lowerHint) external;\n\n /**\n * @notice issues `_amount` of ZUSD from the caller’s Trove to the caller.\n * Executes only if the Trove's collateralization ratio would remain above the minimum, and the resulting total collateralization ratio is above 150%.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _amount ZUSD amount to withdraw\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function withdrawZUSD(\n uint256 _maxFee,\n uint256 _amount,\n address _upperHint,\n address _lowerHint\n ) external;\n\n /// Borrow (withdraw) ZUSD tokens from a trove: mint new ZUSD tokens to the owner and convert it to DLLR in one transaction\n function withdrawZusdAndConvertToDLLR(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external returns (uint256);\n\n /// @notice repay `_amount` of ZUSD to the caller’s Trove, subject to leaving 50 debt in the Trove (which corresponds to the 50 ZUSD gas compensation).\n /// @param _amount ZUSD amount to repay\n /// @param _upperHint upper trove id hint\n /// @param _lowerHint lower trove id hint\n function repayZUSD(uint256 _amount, address _upperHint, address _lowerHint) external;\n\n /// Repay ZUSD tokens to a Trove: Burn the repaid ZUSD tokens, and reduce the trove's debt accordingly\n function repayZusdFromDLLR(\n uint256 _dllrAmount,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external;\n\n /**\n * @notice allows a borrower to repay all debt, withdraw all their collateral, and close their Trove.\n * Requires the borrower have a ZUSD balance sufficient to repay their trove's debt, excluding gas compensation - i.e. `(debt - 50)` ZUSD.\n */\n function closeTrove() external;\n\n /**\n * @notice allows a borrower to repay all debt, withdraw all their collateral, and close their Trove.\n * Requires the borrower have a NUE balance sufficient to repay their trove's debt, excluding gas compensation - i.e. `(debt - 50)` NUE.\n * This method is identical to `closeTrove()`, but operates on NUE tokens instead of ZUSD.\n */\n function closeNueTrove(IMassetManager.PermitParams calldata _permitParams) external;\n\n /**\n * @notice enables a borrower to simultaneously change both their collateral and debt, subject to all the restrictions that apply to individual increases/decreases of each quantity with the following particularity:\n * if the adjustment reduces the collateralization ratio of the Trove, the function only executes if the resulting total collateralization ratio is above 150%.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * The parameter is ignored if the debt is not increased with the transaction.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _collWithdrawal collateral amount to withdraw\n * @param _debtChange ZUSD amount to change\n * @param isDebtIncrease indicates if increases debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function adjustTrove(\n uint256 _maxFee,\n uint256 _collWithdrawal,\n uint256 _debtChange,\n bool isDebtIncrease,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /**\n * @notice enables a borrower to simultaneously change both their collateral and debt, subject to all the restrictions that apply to individual increases/decreases of each quantity with the following particularity:\n * if the adjustment reduces the collateralization ratio of the Trove, the function only executes if the resulting total collateralization ratio is above 150%.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * The parameter is ignored if the debt is not increased with the transaction.\n * This method is identical to `adjustTrove()`, but operates on NUE tokens instead of ZUSD.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _collWithdrawal collateral amount to withdraw\n * @param _debtChange ZUSD amount to change\n * @param isDebtIncrease indicates if increases debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function adjustNueTrove(\n uint256 _maxFee,\n uint256 _collWithdrawal,\n uint256 _debtChange,\n bool isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external payable;\n\n /**\n * @notice when a borrower’s Trove has been fully redeemed from and closed, or liquidated in Recovery Mode with a collateralization ratio above 110%,\n * this function allows the borrower to claim their ETH collateral surplus that remains in the system (collateral - debt upon redemption; collateral - 110% of the debt upon liquidation).\n */\n function claimCollateral() external;\n\n function getCompositeDebt(uint256 _debt) external view returns (uint256);\n\n function BORROWING_FEE_FLOOR() external view returns (uint256);\n\n function getMassetManager() external view returns (IMassetManager);\n}\n" + }, + "contracts/Interfaces/ICollSurplusPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface ICollSurplusPool {\n // --- Events ---\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n\n event CollBalanceUpdated(address indexed _account, uint256 _newBalance);\n event EtherSent(address _to, uint256 _amount);\n\n // --- Contract setters ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _borrowerOperationsAddress BorrowerOperations contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _activePoolAddress ActivePool contract address\n */\n function setAddresses(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress\n ) external;\n\n /// @notice Not necessarily equal to the raw ether balance - ether can be forcibly sent to contracts.\n /// @return ETH state variable\n function getETH() external view returns (uint256);\n\n /// @param _account account to retrieve collateral\n /// @return collateral\n function getCollateral(address _account) external view returns (uint256);\n\n /// @notice adds amount to current account balance. Only callable by TroveManager.\n /// @param _account account to add amount\n /// @param _amount amount to add\n function accountSurplus(address _account, uint256 _amount) external;\n\n /// @notice claims collateral for given account. Only callable by BorrowerOperations.\n /// @param _account account to send claimable collateral\n function claimColl(address _account) external;\n}\n" + }, + "contracts/Interfaces/ICommunityIssuance.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface ICommunityIssuance { \n \n // --- Events ---\n \n event SOVTokenAddressSet(address _zeroTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event StabilityPoolAddressSet(address _stabilityPoolAddress);\n event PriceFeedAddressSet(address _priceFeed);\n event RewardManagerAddressSet(address _rewardManagerAddress);\n event APRSet(uint256 _APR);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other contracts. Callable only by owner.\n * @dev initializer function, checks addresses are contracts\n * @param _zeroTokenAddress ZEROToken contract address\n * @param _communityPotAddress CommunityPot contract address\n */\n function initialize\n (\n address _zeroTokenAddress, \n address _communityPotAddress,\n address _fundingWalletAddress\n ) external;\n\n /**\n * @dev setter function to set the APR value in basis points.\n * can only be called by reward manager.\n * @param _APR apr value in basis points.\n */\n function setAPR(uint256 _APR) external;\n\n /**\n * @dev setter function to set the price feed.\n * can only be called by the owner.\n * @param _priceFeedAddress price feed address.\n */\n function setPriceFeed(address _priceFeedAddress) external;\n\n /**\n * @dev setter function to set reward manager.\n * can only be called by the owner.\n * @param _rewardManagerAddress reward manager address.\n */\n function setRewardManager(address _rewardManagerAddress) external;\n\n /// @notice issues SOV tokens based on total zusd is deposited.\n /// @return SOV tokens issuance \n function issueSOV(uint256 _totalZUSDDeposits) external returns (uint256);\n\n /// @notice sends ZERO tokens to given account\n /// @param _account account to receive the tokens\n /// @param _ZEROamount amount of tokens to transfer\n function sendSOV(address _account, uint _ZEROamount) external;\n}\n" + }, + "contracts/Interfaces/IDefaultPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IPool.sol\";\n\ninterface IDefaultPool is IPool {\n // --- Events ---\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event DefaultPoolZUSDDebtUpdated(uint256 _ZUSDDebt);\n event DefaultPoolETHBalanceUpdated(uint256 _ETH);\n\n // --- Functions ---\n\n /// @notice Send ETH to Active Pool\n /// @param _amount ETH to send\n function sendETHToActivePool(uint256 _amount) external;\n}\n" + }, + "contracts/Interfaces/IFeeDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/// Common interface for Fee Distributor.\ninterface IFeeDistributor {\n // --- Events ---\n\n event FeeSharingCollectorAddressChanged(address _feeSharingCollectorAddress);\n event ZeroStakingAddressChanged(address _zeroStakingAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event WrbtcAddressChanged(address _wrbtcAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event ZUSDDistributed(uint256 _zusdDistributedAmount);\n event RBTCistributed(uint256 _rbtcDistributedAmount);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _feeSharingCollectorAddress FeeSharingCollector address\n * @param _zeroStakingAddress ZEROStaking contract address\n * @param _borrowerOperationsAddress borrowerOperations contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _wrbtcAddress wrbtc ERC20 contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _activePoolAddress ActivePool contract address\n */\n function setAddresses(\n address _feeSharingCollectorAddress,\n address _zeroStakingAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _wrbtcAddress,\n address _zusdTokenAddress,\n address _activePoolAddress\n ) external;\n\n function distributeFees() external;\n}\n" + }, + "contracts/Interfaces/IFeeSharingCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\n/**\n * @title Interface for Sovryn protocol fee sharing collector.\n * @dev Interfaces are used to cast a contract address into a callable instance.\n * */\ninterface IFeeSharingCollector {\n\tfunction withdrawFees(address _token) external;\n\n\tfunction transferTokens(address _token, uint96 _amount) external;\n\n\tfunction withdraw(\n\t\taddress _loanPoolToken,\n\t\tuint32 _maxCheckpoints,\n\t\taddress _receiver\n\t) external;\n\n\tfunction transferRBTC() external payable;\n}\n" + }, + "contracts/Interfaces/ILiquityBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IPriceFeed.sol\";\nimport \"./ILiquityBaseParams.sol\";\n\ninterface ILiquityBase {\n /// @return PriceFeed contract\n function priceFeed() external view returns (IPriceFeed);\n\n /// @return LiquityBaseParams contract\n function liquityBaseParams() external view returns (ILiquityBaseParams);\n}\n" + }, + "contracts/Interfaces/ILiquityBaseParams.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface ILiquityBaseParams {\n\n /// Minimum collateral ratio for individual troves\n function MCR() external view returns (uint);\n\n /// Critical system collateral ratio. If the system's total collateral ratio (TCR) falls below the CCR, Recovery Mode is triggered.\n function CCR() external view returns (uint);\n\n function PERCENT_DIVISOR() external view returns (uint);\n\n function BORROWING_FEE_FLOOR() external view returns (uint);\n\n /**\n * Half-life of 12h. 12h = 720 min\n * (1/2) = d^720 => d = (1/2)^(1/720)\n */\n function REDEMPTION_FEE_FLOOR() external view returns (uint);\n\n function MAX_BORROWING_FEE() external view returns (uint);\n\n}" + }, + "contracts/Interfaces/IPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// Common interface for the Pools.\ninterface IPool {\n // --- Events ---\n\n event ETHBalanceUpdated(uint _newBalance);\n event ZUSDBalanceUpdated(uint _newBalance);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n event DefaultPoolAddressChanged(address _newDefaultPoolAddress);\n event StabilityPoolAddressChanged(address _newStabilityPoolAddress);\n event EtherSent(address _to, uint _amount);\n\n // --- Functions ---\n\n /// @notice Not necessarily equal to the raw ether balance - ether can be forcibly sent to contracts.\n /// @return ETH pool balance\n function getETH() external view returns (uint);\n\n /// @return ZUSD debt pool balance\n function getZUSDDebt() external view returns (uint);\n\n /// @notice Increases ZUSD debt of the pool.\n /// @param _amount ZUSD amount to add to the pool debt\n function increaseZUSDDebt(uint _amount) external;\n\n /// @notice Decreases ZUSD debt of the pool.\n /// @param _amount ZUSD amount to subtract to the pool debt\n function decreaseZUSDDebt(uint _amount) external;\n}\n" + }, + "contracts/Interfaces/IPriceFeed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IPriceFeed {\n // --- Events ---\n event LastGoodPriceUpdated(uint256 _lastGoodPrice);\n\n // --- Function ---\n\n /// @notice Returns the latest price obtained from the Oracle. Called by Zero functions that require a current price.\n /// It uses the main price feed and fallback to the backup one in case of an error. If both fail return the last\n /// good price seen.\n /// @dev It's also callable by anyone externally\n /// @return The price\n function fetchPrice() external returns (uint256);\n}\n" + }, + "contracts/Interfaces/IPriceFeedSovryn.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IPriceFeedSovryn {\n function queryRate(address sourceToken, address destToken)\n external\n view\n returns (uint256 rate, uint256 precision);\n\n function queryPrecision(address sourceToken, address destToken)\n external\n view\n returns (uint256 precision);\n\n function queryReturn(\n address sourceToken,\n address destToken,\n uint256 sourceAmount\n ) external view returns (uint256 destAmount);\n\n function checkPriceDisagreement(\n address sourceToken,\n address destToken,\n uint256 sourceAmount,\n uint256 destAmount,\n uint256 maxSlippage\n ) external view returns (uint256 sourceToDestSwapRate);\n\n function amountInEth(address Token, uint256 amount) external view returns (uint256 ethAmount);\n\n function getMaxDrawdown(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount,\n uint256 maintenanceMargin\n ) external view returns (uint256);\n\n function getCurrentMarginAndCollateralSize(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount\n ) external view returns (uint256 currentMargin, uint256 collateralInEthAmount);\n\n function getCurrentMargin(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount\n ) external view returns (uint256 currentMargin, uint256 collateralToLoanRate);\n\n function shouldLiquidate(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount,\n uint256 maintenanceMargin\n ) external view returns (bool);\n\n function getFastGasPrice(address payToken) external view returns (uint256);\n}\n" + }, + "contracts/Interfaces/ISortedTroves.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// Common interface for the SortedTroves Doubly Linked List.\ninterface ISortedTroves {\n // --- Events ---\n\n event SortedTrovesAddressChanged(address _sortedDoublyLLAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event NodeAdded(address _id, uint256 _NICR);\n event NodeRemoved(address _id);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts and size. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _size max size of troves list\n * @param _TroveManagerAddress TroveManager contract address\n * @param _borrowerOperationsAddress BorrowerOperations contract address\n */\n function setParams(\n uint256 _size,\n address _TroveManagerAddress,\n address _borrowerOperationsAddress\n ) external;\n\n /**\n * @dev Add a node to the list\n * @param _id Node's id\n * @param _ICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function insert(\n address _id,\n uint256 _ICR,\n address _prevId,\n address _nextId\n ) external;\n\n /**\n * @dev Remove a node from the list\n * @param _id Node's id\n */\n function remove(address _id) external;\n\n /**\n * @dev Re-insert the node at a new position, based on its new NICR\n * @param _id Node's id\n * @param _newICR Node's new NICR\n * @param _prevId Id of previous node for the new insert position\n * @param _nextId Id of next node for the new insert position\n */\n function reInsert(\n address _id,\n uint256 _newICR,\n address _prevId,\n address _nextId\n ) external;\n\n /**\n * @dev Checks if the list contains a node\n * @param _id Node's id\n * @return true if list contains a node with given id\n */\n function contains(address _id) external view returns (bool);\n\n /**\n * @dev Checks if the list is full\n * @return true if list is full\n */\n function isFull() external view returns (bool);\n\n /**\n * @dev Checks if the list is empty\n * @return true if list is empty\n */\n function isEmpty() external view returns (bool);\n\n /**\n * @return list current size\n */\n function getSize() external view returns (uint256);\n\n /**\n * @return list max size\n */\n function getMaxSize() external view returns (uint256);\n\n /**\n * @return the first node in the list (node with the largest NICR)\n */\n function getFirst() external view returns (address);\n\n /**\n * @return the last node in the list (node with the smallest NICR)\n */\n function getLast() external view returns (address);\n\n /**\n * @param _id Node's id\n * @return the next node (with a smaller NICR) in the list for a given node\n */\n function getNext(address _id) external view returns (address);\n\n /**\n * @param _id Node's id\n * @return the previous node (with a larger NICR) in the list for a given node\n */\n function getPrev(address _id) external view returns (address);\n\n /**\n * @notice Check if a pair of nodes is a valid insertion point for a new node with the given NICR\n * @param _ICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function validInsertPosition(\n uint256 _ICR,\n address _prevId,\n address _nextId\n ) external view returns (bool);\n\n /**\n * @notice Find the insert position for a new node with the given NICR\n * @param _ICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function findInsertPosition(\n uint256 _ICR,\n address _prevId,\n address _nextId\n ) external view returns (address, address);\n}\n" + }, + "contracts/Interfaces/IStabilityPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../Dependencies/Mynt/IMassetManager.sol\";\n\n/*\n * The Stability Pool holds ZUSD tokens deposited by Stability Pool depositors.\n *\n * When a trove is liquidated, then depending on system conditions, some of its ZUSD debt gets offset with\n * ZUSD in the Stability Pool: that is, the offset debt evaporates, and an equal amount of ZUSD tokens in the Stability Pool is burned.\n *\n * Thus, a liquidation causes each depositor to receive a ZUSD loss, in proportion to their deposit as a share of total deposits.\n * They also receive an ETH gain, as the ETH collateral of the liquidated trove is distributed among Stability depositors,\n * in the same proportion.\n *\n * When a liquidation occurs, it depletes every deposit by the same fraction: for example, a liquidation that depletes 40%\n * of the total ZUSD in the Stability Pool, depletes 40% of each deposit.\n *\n * A deposit that has experienced a series of liquidations is termed a \"compounded deposit\": each liquidation depletes the deposit,\n * multiplying it by some factor in range ]0,1[\n *\n * Please see the implementation spec in the proof document, which closely follows on from the compounded deposit / ETH gain derivations:\n * https://github.com/liquity/liquity/blob/master/papers/Scalable_Reward_Distribution_with_Compounding_Stakes.pdf\n *\n * --- SOV ISSUANCE TO STABILITY POOL DEPOSITORS ---\n *\n * An SOV issuance event occurs at every deposit operation, and every liquidation.\n *\n * Each deposit is tagged with the address of the front end through which it was made.\n *\n * All deposits earn a share of the issued SOV in proportion to the deposit as a share of total deposits. The SOV earned\n * by a given deposit, is split between the depositor and the front end through which the deposit was made, based on the front end's kickbackRate.\n *\n * Please see the system Readme for an overview:\n * https://github.com/liquity/dev/blob/main/README.md#zero-issuance-to-stability-providers\n */\ninterface IStabilityPool {\n // --- Events ---\n\n event StabilityPoolETHBalanceUpdated(uint _newBalance);\n event StabilityPoolZUSDBalanceUpdated(uint _newBalance);\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n event DefaultPoolAddressChanged(address _newDefaultPoolAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event SortedTrovesAddressChanged(address _newSortedTrovesAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event CommunityIssuanceAddressChanged(address _newCommunityIssuanceAddress);\n\n event P_Updated(uint _P);\n event S_Updated(uint _S, uint128 _epoch, uint128 _scale);\n event G_Updated(uint _G, uint128 _epoch, uint128 _scale);\n event EpochUpdated(uint128 _currentEpoch);\n event ScaleUpdated(uint128 _currentScale);\n\n event FrontEndRegistered(address indexed _frontEnd, uint _kickbackRate);\n event FrontEndTagSet(address indexed _depositor, address indexed _frontEnd);\n\n event DepositSnapshotUpdated(address indexed _depositor, uint _P, uint _S, uint _G);\n event FrontEndSnapshotUpdated(address indexed _frontEnd, uint _P, uint _G);\n event UserDepositChanged(address indexed _depositor, uint _newDeposit);\n event FrontEndStakeChanged(\n address indexed _frontEnd,\n uint _newFrontEndStake,\n address _depositor\n );\n\n event ETHGainWithdrawn(address indexed _depositor, uint _ETH, uint _ZUSDLoss);\n event SOVPaidToDepositor(address indexed _depositor, uint _SOV);\n event SOVPaidToFrontEnd(address indexed _frontEnd, uint _SOV);\n event EtherSent(address _to, uint _amount);\n\n event WithdrawFromSpAndConvertToDLLR(\n address _depositor,\n uint256 _zusdAmountRequested,\n uint256 _dllrAmountReceived\n );\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Liquity contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _liquityBaseParamsAddress LiquidityBaseParams contract address\n * @param _borrowerOperationsAddress BorrowerOperations contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _activePoolAddress ActivePool contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _sortedTrovesAddress SortedTroves contract address\n * @param _priceFeedAddress PriceFeed contract address\n * @param _communityIssuanceAddress CommunityIssuanceAddress\n */\n function setAddresses(\n address _liquityBaseParamsAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _zusdTokenAddress,\n address _sortedTrovesAddress,\n address _priceFeedAddress,\n address _communityIssuanceAddress\n ) external;\n\n /**\n * @notice Initial checks:\n * - Frontend is registered or zero address\n * - Sender is not a registered frontend\n * - _amount is not zero\n * ---\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Tags the deposit with the provided front end tag param, if it's a new deposit\n * - Sends depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Increases deposit and tagged front end's stake, and takes new snapshots for each.\n * @param _amount amount to provide\n * @param _frontEndTag frontend address to receive accumulated SOV gains\n */\n function provideToSP(uint _amount, address _frontEndTag) external;\n\n /**\n * @notice Initial checks:\n * - _amount is zero or there are no under collateralized troves left in the system\n * - User has a non zero deposit\n * ---\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Removes the deposit's front end tag if it is a full withdrawal\n * - Sends all depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Decreases deposit and tagged front end's stake, and takes new snapshots for each.\n *\n * If _amount > userDeposit, the user withdraws all of their compounded deposit.\n * @param _amount amount to withdraw\n */\n function withdrawFromSP(uint _amount) external;\n\n /**\n * @notice Initial checks:\n * - User has a non zero deposit\n * - User has an open trove\n * - User has some ETH gain\n * ---\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Sends all depositor's SOV gain to depositor\n * - Sends all tagged front end's SOV gain to the tagged front end\n * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove\n * - Leaves their compounded deposit in the Stability Pool\n * - Updates snapshots for deposit and tagged front end stake\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external;\n\n /**\n * @notice Initial checks:\n * - Frontend (sender) not already registered\n * - User (sender) has no deposit\n * - _kickbackRate is in the range [0, 100%]\n * ---\n * Front end makes a one-time selection of kickback rate upon registering\n * @param _kickbackRate kickback rate selected by frontend\n */\n function registerFrontEnd(uint _kickbackRate) external;\n\n /**\n * @notice Initial checks:\n * - Caller is TroveManager\n * ---\n * Cancels out the specified debt against the ZUSD contained in the Stability Pool (as far as possible)\n * and transfers the Trove's ETH collateral from ActivePool to StabilityPool.\n * Only called by liquidation functions in the TroveManager.\n * @param _debt debt to cancel\n * @param _coll collateral to transfer\n */\n function offset(uint _debt, uint _coll) external;\n\n /**\n * @return the total amount of ETH held by the pool, accounted in an internal variable instead of `balance`,\n * to exclude edge cases like ETH received from a self-destruct.\n */\n function getETH() external view returns (uint);\n\n /**\n * @return ZUSD held in the pool. Changes when users deposit/withdraw, and when Trove debt is offset.\n */\n function getTotalZUSDDeposits() external view returns (uint);\n\n /**\n * @notice Calculates the ETH gain earned by the deposit since its last snapshots were taken.\n * @param _depositor address to calculate ETH gain\n * @return ETH gain from given depositor\n */\n function getDepositorETHGain(address _depositor) external view returns (uint);\n\n /**\n * @notice Calculate the SOV gain earned by a deposit since its last snapshots were taken.\n * If not tagged with a front end, the depositor gets a 100% cut of what their deposit earned.\n * Otherwise, their cut of the deposit's earnings is equal to the kickbackRate, set by the front end through\n * which they made their deposit.\n * @param _depositor address to calculate ETH gain\n * @return SOV gain from given depositor\n */\n function getDepositorSOVGain(address _depositor) external view returns (uint);\n\n /**\n * @param _frontEnd front end address\n * @return the SOV gain earned by the front end.\n */\n function getFrontEndSOVGain(address _frontEnd) external view returns (uint);\n\n /**\n * @param _depositor depositor address\n * @return the user's compounded deposit.\n */\n function getCompoundedZUSDDeposit(address _depositor) external view returns (uint);\n\n /**\n * @notice The front end's compounded stake is equal to the sum of its depositors' compounded deposits.\n * @param _frontEnd front end address\n * @return the front end's compounded stake.\n */\n function getCompoundedFrontEndStake(address _frontEnd) external view returns (uint);\n\n //DLLR _owner or _spender can convert a specified amount of DLLR into ZUSD via Sovryn Mynt and deposit the ZUSD into the SOV Stability Pool, all in a single transaction\n function provideToSpFromDLLR(\n uint _dllrAmount,\n IMassetManager.PermitParams calldata _permitParams\n ) external;\n\n /// Stability Pool depositor can withdraw a specified amount of ZUSD from the SOV Stability Pool and optionally convert the ZUSD to DLLR via Sovryn Mynt, all in a single transaction\n function withdrawFromSpAndConvertToDLLR(uint256 _zusdAmount) external;\n\n /**\n * Fallback function\n * Only callable by Active Pool, it just accounts for ETH received\n * receive() external payable;\n */\n}\n" + }, + "contracts/Interfaces/ITroveManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./ILiquityBase.sol\";\nimport \"./IStabilityPool.sol\";\nimport \"./IZUSDToken.sol\";\nimport \"./IZEROToken.sol\";\nimport \"./IZEROStaking.sol\";\nimport \"../Dependencies/Mynt/IMassetManager.sol\";\n\n/// Common interface for the Trove Manager.\ninterface ITroveManager is ILiquityBase {\n // --- Events ---\n\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerRedeemOpsAddressChanged(address _troveManagerRedeemOps);\n event LiquityBaseParamsAddressChanges(address _borrowerOperationsAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZEROTokenAddressChanged(address _zeroTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n\n event Liquidation(\n uint256 _liquidatedDebt,\n uint256 _liquidatedColl,\n uint256 _collGasCompensation,\n uint256 _ZUSDGasCompensation\n );\n event Redemption(\n uint256 _attemptedZUSDAmount,\n uint256 _actualZUSDAmount,\n uint256 _ETHSent,\n uint256 _ETHFee\n );\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 stake,\n uint8 operation\n );\n event TroveLiquidated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint8 operation\n );\n event BaseRateUpdated(uint256 _baseRate);\n event LastFeeOpTimeUpdated(uint256 _lastFeeOpTime);\n event TotalStakesUpdated(uint256 _newTotalStakes);\n event SystemSnapshotsUpdated(uint256 _totalStakesSnapshot, uint256 _totalCollateralSnapshot);\n event LTermsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveSnapshotsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveIndexUpdated(address _borrower, uint256 _newIndex);\n\n struct TroveManagerInitAddressesParams {\n address _feeDistributorAddress;\n address _troveManagerRedeemOps;\n address _liquityBaseParamsAddress;\n address _borrowerOperationsAddress;\n address _activePoolAddress;\n address _defaultPoolAddress;\n address _stabilityPoolAddress;\n address _gasPoolAddress;\n address _collSurplusPoolAddress;\n address _priceFeedAddress;\n address _zusdTokenAddress;\n address _sortedTrovesAddress;\n address _zeroTokenAddress;\n address _zeroStakingAddress;\n }\n\n // --- Functions ---\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _troveManagerInitAddresses addresses list to intialize TroveManager with _\n * _feeDistributorAddress feeDistributor contract address\n * _troveManagerRedeemOps TroveManagerRedeemOps contract address\n * _liquityBaseParamsAddress LiquityBaseParams contract address\n * _borrowerOperationsAddress BorrowerOperations contract address\n * _activePoolAddress ActivePool contract address\n * _defaultPoolAddress DefaultPool contract address\n * _stabilityPoolAddress StabilityPool contract address\n * _gasPoolAddress GasPool contract address\n * _collSurplusPoolAddress CollSurplusPool contract address\n * _priceFeedAddress PriceFeed contract address\n * _zusdTokenAddress ZUSDToken contract address\n * _sortedTrovesAddress SortedTroves contract address\n * _zeroTokenAddress ZEROToken contract address\n * _zeroStakingAddress ZEROStaking contract address\n */\n function setAddresses(\n TroveManagerInitAddressesParams memory _troveManagerInitAddresses\n ) external;\n\n function setTroveManagerRedeemOps(address _troveManagerRedeemOps) external;\n\n /// @return Trove owners count\n function getTroveOwnersCount() external view returns (uint256);\n\n /// @param _index Trove owner index\n /// @return Trove from TroveOwners array in given index\n function getTroveFromTroveOwnersArray(uint256 _index) external view returns (address);\n\n /// @param _borrower borrower address\n /// @return the nominal collateral ratio (ICR) of a given Trove, without the price. Takes a trove's pending coll and debt rewards from redistributions into account.\n function getNominalICR(address _borrower) external view returns (uint256);\n\n /// @notice computes the user’s individual collateralization ratio (ICR) based on their total collateral and total ZUSD debt. Returns 2^256 -1 if they have 0 debt.\n /// @param _borrower borrower address\n /// @param _price ETH price\n /// @return the current collateral ratio (ICR) of a given Trove. Takes a trove's pending coll and debt rewards from redistributions into account.\n function getCurrentICR(address _borrower, uint256 _price) external view returns (uint256);\n\n /// @notice Closes the trove if its ICR is lower than the minimum collateral ratio.\n /// @param _borrower borrower address\n function liquidate(address _borrower) external;\n\n /**\n * @notice Liquidate a sequence of troves. Closes a maximum number of n under-collateralized Troves,\n * starting from the one with the lowest collateral ratio in the system, and moving upwards\n * @param _n max number of under-collateralized Troves to liquidate\n */\n function liquidateTroves(uint256 _n) external;\n\n /**\n * @notice Attempt to liquidate a custom list of troves provided by the caller.\n * @param _troveArray list of trove addresses\n */\n function batchLiquidateTroves(address[] calldata _troveArray) external;\n\n /**\n * @notice Send _ZUSDamount ZUSD to the system and redeem the corresponding amount of collateral from as many Troves as are needed to fill the redemption\n * request. Applies pending rewards to a Trove before reducing its debt and coll.\n *\n * Note that if _amount is very large, this function can run out of gas, specially if traversed troves are small. This can be easily avoided by\n * splitting the total _amount in appropriate chunks and calling the function multiple times.\n *\n * Param `_maxIterations` can also be provided, so the loop through Troves is capped (if it’s zero, it will be ignored).This makes it easier to\n * avoid OOG for the frontend, as only knowing approximately the average cost of an iteration is enough, without needing to know the “topology”\n * of the trove list. It also avoids the need to set the cap in stone in the contract, nor doing gas calculations, as both gas price and opcode\n * costs can vary.\n *\n * All Troves that are redeemed from -- with the likely exception of the last one -- will end up with no debt left, therefore they will be closed.\n * If the last Trove does have some remaining debt, it has a finite ICR, and the reinsertion could be anywhere in the list, therefore it requires a hint.\n * A frontend should use getRedemptionHints() to calculate what the ICR of this Trove will be after redemption, and pass a hint for its position\n * in the sortedTroves list along with the ICR value that the hint was found for.\n *\n * If another transaction modifies the list between calling getRedemptionHints() and passing the hints to redeemCollateral(), it\n * is very likely that the last (partially) redeemed Trove would end up with a different ICR than what the hint is for. In this case the\n * redemption will stop after the last completely redeemed Trove and the sender will keep the remaining ZUSD amount, which they can attempt\n * to redeem later.\n *\n * @param _ZUSDAmount ZUSD amount to send to the system\n * @param _firstRedemptionHint calculated ICR hint of first trove after redemption\n * @param _maxIterations max Troves iterations (can be 0)\n * @param _maxFee max fee percentage to accept\n */\n function redeemCollateral(\n uint256 _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFee\n ) external;\n\n function redeemCollateralViaDLLR(\n uint256 _dllrAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage,\n IMassetManager.PermitParams calldata _permitParams\n ) external;\n\n /// @notice Update borrower's stake based on their latest collateral value\n /// @param _borrower borrower address\n function updateStakeAndTotalStakes(address _borrower) external returns (uint256);\n\n /// @notice Update borrower's snapshots of L_ETH and L_ZUSDDebt to reflect the current values\n /// @param _borrower borrower address\n function updateTroveRewardSnapshots(address _borrower) external;\n\n /// @notice Push the owner's address to the Trove owners list, and record the corresponding array index on the Trove struct\n /// @param _borrower borrower address\n /// @return index where Trove was inserted\n function addTroveOwnerToArray(address _borrower) external returns (uint256 index);\n\n /// @notice Add the borrowers's coll and debt rewards earned from redistributions, to their Trove\n /// @param _borrower borrower address\n function applyPendingRewards(address _borrower) external;\n\n /// @param _borrower borrower address\n /// @return the borrower's pending accumulated ETH reward, earned by their stake\n function getPendingETHReward(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return the borrower's pending accumulated ZUSD reward, earned by their stake\n function getPendingZUSDDebtReward(address _borrower) external view returns (uint256);\n\n /*\n * @notice A Trove has pending rewards if its snapshot is less than the current rewards per-unit-staked sum:\n * this indicates that rewards have occured since the snapshot was made, and the user therefore has\n * pending rewards\n *\n * @param _borrower borrower address\n * @return true if has pending rewards\n */\n function hasPendingRewards(address _borrower) external view returns (bool);\n\n /// @notice returns the Troves entire debt and coll, including pending rewards from redistributions.\n /// @param _borrower borrower address\n function getEntireDebtAndColl(\n address _borrower\n )\n external\n view\n returns (\n uint256 debt,\n uint256 coll,\n uint256 pendingZUSDDebtReward,\n uint256 pendingETHReward\n );\n\n /// @notice Close given trove. Called by BorrowerOperations.\n /// @param _borrower borrower address\n function closeTrove(address _borrower) external;\n\n /// @notice Remove borrower's stake from the totalStakes sum, and set their stake to 0\n /// @param _borrower borrower address\n function removeStake(address _borrower) external;\n\n /// @return calculated redemption rate using baseRate\n function getRedemptionRate() external view returns (uint256);\n\n /// @return calculated redemption rate using calculated decayed as base rate\n function getRedemptionRateWithDecay() external view returns (uint256);\n\n /// @notice The redemption fee is taken as a cut of the total ETH drawn from the system in a redemption. It is based on the current redemption rate.\n /// @param _ETHDrawn ETH drawn\n function getRedemptionFeeWithDecay(uint256 _ETHDrawn) external view returns (uint256);\n\n /// @return borrowing rate\n function getBorrowingRate() external view returns (uint256);\n\n /// @return borrowing rate calculated using decayed as base rate\n function getBorrowingRateWithDecay() external view returns (uint256);\n\n /// @param ZUSDDebt ZUSD debt amount to calculate fee\n /// @return borrowing fee using borrowing rate\n function getBorrowingFee(uint256 ZUSDDebt) external view returns (uint256);\n\n /// @param _ZUSDDebt ZUSD debt amount to calculate fee\n /// @return borrowing fee using borrowing rate with decay\n function getBorrowingFeeWithDecay(uint256 _ZUSDDebt) external view returns (uint256);\n\n /// @notice Updates the baseRate state variable based on time elapsed since the last redemption or ZUSD borrowing operation.\n function decayBaseRateFromBorrowing() external;\n\n /// @param _borrower borrower address\n /// @return Trove status from given trove\n function getTroveStatus(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return Trove stake from given trove\n function getTroveStake(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return Trove debt from given trove\n function getTroveDebt(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return Trove collateral from given trove\n function getTroveColl(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @param num status to set\n function setTroveStatus(address _borrower, uint256 num) external;\n\n /// @param _borrower borrower address\n /// @param _collIncrease amount of collateral to increase\n /// @return new trove collateral\n function increaseTroveColl(\n address _borrower,\n uint256 _collIncrease\n ) external returns (uint256);\n\n /// @param _borrower borrower address\n /// @param _collDecrease amount of collateral to decrease\n /// @return new trove collateral\n function decreaseTroveColl(\n address _borrower,\n uint256 _collDecrease\n ) external returns (uint256);\n\n /// @param _borrower borrower address\n /// @param _debtIncrease amount of debt to increase\n /// @return new trove debt\n function increaseTroveDebt(\n address _borrower,\n uint256 _debtIncrease\n ) external returns (uint256);\n\n /// @param _borrower borrower address\n /// @param _debtDecrease amount of debt to decrease\n /// @return new trove debt\n function decreaseTroveDebt(\n address _borrower,\n uint256 _debtDecrease\n ) external returns (uint256);\n\n /**\n * @param _price ETH price\n * @return the total collateralization ratio (TCR) of the system.\n * The TCR is based on the the entire system debt and collateral (including pending rewards).\n */\n function getTCR(uint256 _price) external view returns (uint256);\n\n function MCR() external view returns (uint256);\n\n function CCR() external view returns (uint256);\n\n /// @notice reveals whether or not the system is in Recovery Mode (i.e. whether the Total Collateralization Ratio (TCR) is below the Critical Collateralization Ratio (CCR)).\n function checkRecoveryMode(uint256 _price) external view returns (bool);\n}\n" + }, + "contracts/Interfaces/IWrbtc.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Dependencies/IERC20.sol\";\n\ninterface IWrbtc is IERC20 {\n\t\n\tfunction deposit() external payable;\n\n\tfunction withdraw(uint256 wad) external;\n\n}\n" + }, + "contracts/Interfaces/IZEROStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IZEROStaking {\n // --- Events --\n\n event ZEROTokenAddressSet(address _zeroTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event FeeDistributorAddressAddressSet(address _feeDistributorAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event StakeChanged(address indexed staker, uint256 newStake);\n event StakingGainsWithdrawn(address indexed staker, uint256 ZUSDGain, uint256 ETHGain);\n event F_ETHUpdated(uint256 _F_ETH);\n event F_ZUSDUpdated(uint256 _F_ZUSD);\n event TotalZEROStakedUpdated(uint256 _totalZEROStaked);\n event EtherSent(address _account, uint256 _amount);\n event StakerSnapshotsUpdated(address _staker, uint256 _F_ETH, uint256 _F_ZUSD);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _zeroTokenAddress ZEROToken contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _feeDistributorAddress FeeDistributorAddress contract address\n * @param _activePoolAddress ActivePool contract address\n */\n function setAddresses(\n address _zeroTokenAddress,\n address _zusdTokenAddress,\n address _feeDistributorAddress,\n address _activePoolAddress\n ) external;\n\n /// @notice If caller has a pre-existing stake, send any accumulated ETH and ZUSD gains to them.\n /// @param _ZEROamount ZERO tokens to stake\n function stake(uint256 _ZEROamount) external;\n\n /**\n * @notice Unstake the ZERO and send the it back to the caller, along with their accumulated ZUSD & ETH gains.\n * If requested amount > stake, send their entire stake.\n * @param _ZEROamount ZERO tokens to unstake\n */\n function unstake(uint256 _ZEROamount) external;\n\n /// @param _ETHFee ETH fee\n /// @notice increase ETH fee\n function increaseF_ETH(uint256 _ETHFee) external;\n\n /// @param _ZEROFee ZUSD fee\n /// @notice increase ZUSD fee\n function increaseF_ZUSD(uint256 _ZEROFee) external;\n\n /// @param _user user address\n /// @return pending ETH gain of given user\n function getPendingETHGain(address _user) external view returns (uint256);\n\n /// @param _user user address\n /// @return pending ZUSD gain of given user\n function getPendingZUSDGain(address _user) external view returns (uint256);\n}\n" + }, + "contracts/Interfaces/IZEROToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Dependencies/IERC2612.sol\";\n\ninterface IZEROToken is IERC20, IERC2612 { \n\n // --- Functions ---\n\n /// @notice send zero tokens to ZEROStaking contract\n /// @param _sender sender address\n /// @param _amount amount to send\n function sendToZEROStaking(address _sender, uint256 _amount) external;\n\n /// @return deployment start time\n function getDeploymentStartTime() external view returns (uint256);\n\n}\n" + }, + "contracts/Interfaces/IZUSDToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Dependencies/IERC2612.sol\";\n\ninterface IZUSDToken is IERC20, IERC2612 { \n \n // --- Events ---\n\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event StabilityPoolAddressChanged(address _newStabilityPoolAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n\n event ZUSDTokenBalanceUpdated(address _user, uint _amount);\n\n // --- Functions ---\n\n function mint(address _account, uint256 _amount) external;\n\n function burn(address _account, uint256 _amount) external;\n\n function sendToPool(address _sender, address poolAddress, uint256 _amount) external;\n\n function returnFromPool(address poolAddress, address user, uint256 _amount ) external;\n}\n" + }, + "contracts/LiquityBaseParams.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ILiquityBaseParams.sol\";\nimport \"./Dependencies/BaseMath.sol\";\nimport \"./Dependencies/LiquityMath.sol\";\n\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/Initializable.sol\";\n\ncontract LiquityBaseParams is ILiquityBaseParams, Ownable, Initializable, BaseMath {\n using SafeMath for uint256;\n\n /// Minimum collateral ratio for individual troves\n uint256 public override MCR;\n\n /// Critical system collateral ratio. If the system's total collateral ratio (TCR) falls below the CCR, Recovery Mode is triggered.\n uint256 public override CCR;\n\n uint256 public override PERCENT_DIVISOR;\n\n uint256 public override BORROWING_FEE_FLOOR;\n\n /**\n * Half-life of 12h. 12h = 720 min\n * (1/2) = d^720 => d = (1/2)^(1/720)\n */\n uint256 public override REDEMPTION_FEE_FLOOR;\n\n uint256 public override MAX_BORROWING_FEE;\n\n function initialize() public initializer onlyOwner {\n MCR = 1100000000000000000; // 110%\n CCR = 1500000000000000000; // 150%\n PERCENT_DIVISOR = 200; // dividing by 200 yields 0.5%\n BORROWING_FEE_FLOOR = (DECIMAL_PRECISION / 1000) * 5; // 0.5%\n REDEMPTION_FEE_FLOOR = (DECIMAL_PRECISION / 1000) * 5; // 0.5%\n MAX_BORROWING_FEE = (DECIMAL_PRECISION / 100) * 5; // 5%\n }\n\n function setMCR(uint256 MCR_) public onlyOwner {\n MCR = MCR_;\n }\n\n function setCCR(uint256 CCR_) public onlyOwner {\n CCR = CCR_;\n }\n\n function setPercentDivisor(uint256 PERCENT_DIVISOR_) public onlyOwner {\n PERCENT_DIVISOR = PERCENT_DIVISOR_;\n }\n\n function setBorrowingFeeFloor(uint256 BORROWING_FEE_FLOOR_) public onlyOwner {\n BORROWING_FEE_FLOOR = BORROWING_FEE_FLOOR_;\n }\n\n function setRedemptionFeeFloor(uint256 REDEMPTION_FEE_FLOOR_) public onlyOwner {\n REDEMPTION_FEE_FLOOR = REDEMPTION_FEE_FLOOR_;\n }\n\n function setMaxBorrowingFee(uint256 MAX_BORROWING_FEE_) public onlyOwner {\n MAX_BORROWING_FEE = MAX_BORROWING_FEE_;\n }\n}\n" + }, + "contracts/MultiTroveGetter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./TroveManager.sol\";\nimport \"./SortedTroves.sol\";\nimport \"./MultiTroveGetterStorage.sol\";\n\n/** Helper contract for grabbing Trove data for the front end. Not part of the core Zero system. */\ncontract MultiTroveGetter is MultiTroveGetterStorage {\n struct CombinedTroveData {\n address owner;\n uint256 debt;\n uint256 coll;\n uint256 stake;\n uint256 snapshotETH;\n uint256 snapshotZUSDDebt;\n }\n\n function setAddresses(TroveManager _troveManager, ISortedTroves _sortedTroves)\n public\n onlyOwner\n {\n troveManager = _troveManager;\n sortedTroves = _sortedTroves;\n }\n\n function getMultipleSortedTroves(int256 _startIdx, uint256 _count)\n external\n view\n returns (CombinedTroveData[] memory _troves)\n {\n uint256 startIdx;\n bool descend;\n\n if (_startIdx >= 0) {\n startIdx = uint256(_startIdx);\n descend = true;\n } else {\n startIdx = uint256(-(_startIdx + 1));\n descend = false;\n }\n\n uint256 sortedTrovesSize = sortedTroves.getSize();\n\n if (startIdx >= sortedTrovesSize) {\n _troves = new CombinedTroveData[](0);\n } else {\n uint256 maxCount = sortedTrovesSize - startIdx;\n\n if (_count > maxCount) {\n _count = maxCount;\n }\n\n if (descend) {\n _troves = _getMultipleSortedTrovesFromHead(startIdx, _count);\n } else {\n _troves = _getMultipleSortedTrovesFromTail(startIdx, _count);\n }\n }\n }\n\n function _getMultipleSortedTrovesFromHead(uint256 _startIdx, uint256 _count)\n internal\n view\n returns (CombinedTroveData[] memory _troves)\n {\n address currentTroveowner = sortedTroves.getFirst();\n\n for (uint256 idx = 0; idx < _startIdx; ++idx) {\n currentTroveowner = sortedTroves.getNext(currentTroveowner);\n }\n\n _troves = new CombinedTroveData[](_count);\n\n for (uint256 idx = 0; idx < _count; ++idx) {\n _troves[idx].owner = currentTroveowner;\n (\n _troves[idx].debt,\n _troves[idx].coll,\n _troves[idx].stake,\n /* status */\n /* arrayIndex */\n ,\n\n ) = troveManager.Troves(currentTroveowner);\n (_troves[idx].snapshotETH, _troves[idx].snapshotZUSDDebt) = troveManager\n .rewardSnapshots(currentTroveowner);\n\n currentTroveowner = sortedTroves.getNext(currentTroveowner);\n }\n }\n\n function _getMultipleSortedTrovesFromTail(uint256 _startIdx, uint256 _count)\n internal\n view\n returns (CombinedTroveData[] memory _troves)\n {\n address currentTroveowner = sortedTroves.getLast();\n\n for (uint256 idx = 0; idx < _startIdx; ++idx) {\n currentTroveowner = sortedTroves.getPrev(currentTroveowner);\n }\n\n _troves = new CombinedTroveData[](_count);\n\n for (uint256 idx = 0; idx < _count; ++idx) {\n _troves[idx].owner = currentTroveowner;\n (\n _troves[idx].debt,\n _troves[idx].coll,\n _troves[idx].stake,\n /* status */\n /* arrayIndex */\n ,\n\n ) = troveManager.Troves(currentTroveowner);\n (_troves[idx].snapshotETH, _troves[idx].snapshotZUSDDebt) = troveManager\n .rewardSnapshots(currentTroveowner);\n\n currentTroveowner = sortedTroves.getPrev(currentTroveowner);\n }\n }\n}\n" + }, + "contracts/MultiTroveGetterStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\nimport \"./TroveManager.sol\";\nimport \"./SortedTroves.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract MultiTroveGetterStorage is Ownable {\n TroveManager public troveManager; // XXX Troves missing from ITroveManager?\n ISortedTroves public sortedTroves;\n}\n" + }, + "contracts/PriceFeed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IPriceFeed.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./PriceFeedStorage.sol\";\n\n/// @title The system price feed adapter\n/// @notice The PriceFeed relies upon a main oracle and a secondary as a fallback in case of error\ncontract PriceFeed is PriceFeedStorage, IPriceFeed {\n event LastGoodPriceUpdated(uint256 _lastGoodPrice);\n event PriceFeedBroken(uint8 index, address priceFeedAddress);\n event PriceFeedUpdated(uint8 index, address newPriceFeedAddress);\n\n // --- Dependency setters ---\n\n function setAddresses(address _mainPriceFeed, address _backupPriceFeed) external onlyOwner {\n uint256 latestPrice = setAddress(0, _mainPriceFeed);\n setAddress(1, _backupPriceFeed);\n\n _storePrice(latestPrice);\n }\n\n // --- Functions ---\n\n /// @notice Returns the latest price obtained from the Oracle. Called by Zero functions that require a current price.\n /// It uses the main price feed and fallback to the backup one in case of an error. If both fail return the last\n /// good price seen.\n /// @dev It's also callable by anyone externally\n /// @return The price\n function fetchPrice() external override returns (uint256) {\n for (uint8 index = 0; index < 2; index++) {\n (uint256 price, bool success) = priceFeeds[index].latestAnswer();\n if (success) {\n _storePrice(price);\n return price;\n } else {\n emit PriceFeedBroken(index, address(priceFeeds[index]));\n }\n }\n return lastGoodPrice;\n }\n\n /// @notice Allows users to setup the main and the backup price feeds\n /// @param _index the oracle to be configured\n /// @param _newPriceFeed address where an IExternalPriceFeed implementation is located\n /// @return price the latest price of the inserted price feed\n function setAddress(uint8 _index, address _newPriceFeed) public onlyOwner returns (uint256) {\n require(_index < priceFeeds.length, \"Out of bounds when setting the price feed\");\n checkContract(_newPriceFeed);\n priceFeeds[_index] = IExternalPriceFeed(_newPriceFeed);\n (uint256 price, bool success) = priceFeeds[_index].latestAnswer();\n require(success, \"PriceFeed: Price feed must be working\");\n emit PriceFeedUpdated(_index, _newPriceFeed);\n return price;\n }\n\n // --- Helper functions ---\n function _storePrice(uint256 _currentPrice) internal {\n lastGoodPrice = _currentPrice;\n emit LastGoodPriceUpdated(_currentPrice);\n }\n}\n" + }, + "contracts/PriceFeedStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IPriceFeed.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/PriceFeed/IExternalPriceFeed.sol\";\nimport \"./Dependencies/CheckContract.sol\";\n\ncontract PriceFeedStorage is Ownable, CheckContract {\n string public constant NAME = \"PriceFeed\";\n\n IExternalPriceFeed[2] priceFeeds;\n\n // The last good price seen from an oracle by Zero\n uint256 public lastGoodPrice;\n}\n" + }, + "contracts/Proxy/BorrowerOperationsScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/IBorrowerOperations.sol\";\n\n\ncontract BorrowerOperationsScript is CheckContract {\n IBorrowerOperations immutable borrowerOperations;\n\n constructor(IBorrowerOperations _borrowerOperations) public {\n checkContract(address(_borrowerOperations));\n borrowerOperations = _borrowerOperations;\n }\n\n function openTrove(uint _maxFee, uint _ZUSDAmount, address _upperHint, address _lowerHint) external payable {\n borrowerOperations.openTrove{ value: msg.value }(_maxFee, _ZUSDAmount, _upperHint, _lowerHint);\n }\n\n function addColl(address _upperHint, address _lowerHint) external payable {\n borrowerOperations.addColl{ value: msg.value }(_upperHint, _lowerHint);\n }\n\n function withdrawColl(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.withdrawColl(_amount, _upperHint, _lowerHint);\n }\n\n function withdrawZUSD(uint _maxFee, uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.withdrawZUSD(_maxFee, _amount, _upperHint, _lowerHint);\n }\n\n function repayZUSD(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.repayZUSD(_amount, _upperHint, _lowerHint);\n }\n\n function closeTrove() external {\n borrowerOperations.closeTrove();\n }\n\n function adjustTrove(uint _maxFee, uint _collWithdrawal, uint _debtChange, bool isDebtIncrease, address _upperHint, address _lowerHint) external payable {\n borrowerOperations.adjustTrove{ value: msg.value }(_maxFee, _collWithdrawal, _debtChange, isDebtIncrease, _upperHint, _lowerHint);\n }\n\n function claimCollateral() external {\n borrowerOperations.claimCollateral();\n }\n}\n" + }, + "contracts/Proxy/BorrowerWrappersScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Interfaces/IBorrowerOperations.sol\";\nimport \"../Interfaces/ITroveManager.sol\";\nimport \"../Interfaces/IStabilityPool.sol\";\nimport \"../Interfaces/IPriceFeed.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\nimport \"./BorrowerOperationsScript.sol\";\nimport \"./ETHTransferScript.sol\";\nimport \"./ZEROStakingScript.sol\";\nimport \"../Dependencies/console.sol\";\n\n\ncontract BorrowerWrappersScript is BorrowerOperationsScript, ETHTransferScript, ZEROStakingScript {\n using SafeMath for uint;\n\n string constant public NAME = \"BorrowerWrappersScript\";\n\n ITroveManager immutable troveManager;\n IStabilityPool immutable stabilityPool;\n IPriceFeed immutable priceFeed;\n IERC20 immutable zusdToken;\n IERC20 immutable zeroToken;\n IZEROStaking immutable zeroStaking;\n\n constructor(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _zeroStakingAddress,\n address _stabilityPoolAddress,\n address _priceFeedAddress,\n address _zusdTokenAddress,\n address _zeroTokenAddress\n )\n BorrowerOperationsScript(IBorrowerOperations(_borrowerOperationsAddress))\n ZEROStakingScript(_zeroStakingAddress)\n public\n {\n checkContract(_troveManagerAddress);\n ITroveManager troveManagerCached = ITroveManager(_troveManagerAddress);\n troveManager = troveManagerCached;\n\n IStabilityPool stabilityPoolCached = IStabilityPool(_stabilityPoolAddress);\n checkContract(_stabilityPoolAddress);\n stabilityPool = stabilityPoolCached;\n\n IPriceFeed priceFeedCached = IPriceFeed(_priceFeedAddress); \n checkContract(_priceFeedAddress);\n priceFeed = priceFeedCached;\n\n checkContract(_zusdTokenAddress);\n zusdToken = IERC20(_zusdTokenAddress);\n\n checkContract(_zeroTokenAddress);\n zeroToken = IERC20(_zeroTokenAddress);\n\n IZEROStaking zeroStakingCached = IZEROStaking(_zeroStakingAddress);\n checkContract(_zeroStakingAddress);\n zeroStaking = zeroStakingCached;\n }\n\n function claimCollateralAndOpenTrove(uint _maxFee, uint _ZUSDAmount, address _upperHint, address _lowerHint) external payable {\n uint balanceBefore = address(this).balance;\n\n // Claim collateral\n borrowerOperations.claimCollateral();\n\n uint balanceAfter = address(this).balance;\n\n // already checked in CollSurplusPool\n assert(balanceAfter > balanceBefore);\n\n uint totalCollateral = balanceAfter.sub(balanceBefore).add(msg.value);\n\n // Open trove with obtained collateral, plus collateral sent by user\n borrowerOperations.openTrove{ value: totalCollateral }(_maxFee, _ZUSDAmount, _upperHint, _lowerHint);\n }\n\n function claimSPRewardsAndRecycle(uint _maxFee, address _upperHint, address _lowerHint) external {\n uint collBalanceBefore = address(this).balance;\n uint zeroBalanceBefore = zeroToken.balanceOf(address(this));\n\n // Claim rewards\n stabilityPool.withdrawFromSP(0);\n\n uint collBalanceAfter = address(this).balance;\n uint zeroBalanceAfter = zeroToken.balanceOf(address(this));\n uint claimedCollateral = collBalanceAfter.sub(collBalanceBefore);\n\n // Add claimed ETH to trove, get more ZUSD and stake it into the Stability Pool\n if (claimedCollateral > 0) {\n _requireUserHasTrove(address(this));\n uint ZUSDAmount = _getNetZUSDAmount(claimedCollateral);\n borrowerOperations.adjustTrove{ value: claimedCollateral }(_maxFee, 0, ZUSDAmount, true, _upperHint, _lowerHint);\n // Provide withdrawn ZUSD to Stability Pool\n if (ZUSDAmount > 0) {\n stabilityPool.provideToSP(ZUSDAmount, address(0));\n }\n }\n\n // Stake claimed ZERO\n uint claimedZERO = zeroBalanceAfter.sub(zeroBalanceBefore);\n if (claimedZERO > 0) {\n zeroStaking.stake(claimedZERO);\n }\n }\n\n function claimStakingGainsAndRecycle(uint _maxFee, address _upperHint, address _lowerHint) external {\n uint collBalanceBefore = address(this).balance;\n uint zusdBalanceBefore = zusdToken.balanceOf(address(this));\n uint zeroBalanceBefore = zeroToken.balanceOf(address(this));\n\n // Claim gains\n zeroStaking.unstake(0);\n\n uint gainedCollateral = address(this).balance.sub(collBalanceBefore); // stack too deep issues :'(\n uint gainedZUSD = zusdToken.balanceOf(address(this)).sub(zusdBalanceBefore);\n\n uint netZUSDAmount;\n // Top up trove and get more ZUSD, keeping ICR constant\n if (gainedCollateral > 0) {\n _requireUserHasTrove(address(this));\n netZUSDAmount = _getNetZUSDAmount(gainedCollateral);\n borrowerOperations.adjustTrove{ value: gainedCollateral }(_maxFee, 0, netZUSDAmount, true, _upperHint, _lowerHint);\n }\n\n uint totalZUSD = gainedZUSD.add(netZUSDAmount);\n if (totalZUSD > 0) {\n stabilityPool.provideToSP(totalZUSD, address(0));\n\n // Providing to Stability Pool also triggers ZERO claim, so stake it if any\n uint zeroBalanceAfter = zeroToken.balanceOf(address(this));\n uint claimedZERO = zeroBalanceAfter.sub(zeroBalanceBefore);\n if (claimedZERO > 0) {\n zeroStaking.stake(claimedZERO);\n }\n }\n\n }\n\n function _getNetZUSDAmount(uint _collateral) internal returns (uint) {\n uint price = priceFeed.fetchPrice();\n uint ICR = troveManager.getCurrentICR(address(this), price);\n\n uint ZUSDAmount = _collateral.mul(price).div(ICR);\n uint borrowingRate = troveManager.getBorrowingRateWithDecay();\n uint netDebt = ZUSDAmount.mul(LiquityMath.DECIMAL_PRECISION).div(LiquityMath.DECIMAL_PRECISION.add(borrowingRate));\n\n return netDebt;\n }\n\n function _requireUserHasTrove(address _depositor) internal view {\n require(troveManager.getTroveStatus(_depositor) == 1, \"BorrowerWrappersScript: caller must have an active trove\");\n }\n}\n" + }, + "contracts/Proxy/ETHTransferScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n\ncontract ETHTransferScript {\n function transferETH(address _recipient, uint256 _amount) external returns (bool) {\n (bool success, ) = _recipient.call{value: _amount}(\"\");\n return success;\n }\n}\n" + }, + "contracts/Proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Dependencies/Ownable.sol\";\n/**\n * @title Base Proxy contract.\n * \n * Adapted version of https://github.com/DistributedCollective/Sovryn-smart-contracts/blob/development/contracts/proxy/Proxy.sol \n *\n * @notice The proxy performs delegated calls to the contract implementation\n * it is pointing to. This way upgradable contracts are possible on blockchain.\n *\n * Delegating proxy contracts are widely used for both upgradeability and gas\n * savings. These proxies rely on a logic contract (also known as implementation\n * contract or master copy) that is called using delegatecall. This allows\n * proxies to keep a persistent state (storage and balance) while the code is\n * delegated to the logic contract.\n *\n * Proxy contract is meant to be inherited and its internal functions\n * _setImplementation and _setOwner to be called when upgrades become\n * neccessary.\n *\n * The loan token (iToken) contract as well as the protocol contract act as\n * proxies, delegating all calls to underlying contracts. Therefore, if you\n * want to interact with them using web3, you need to use the ABIs from the\n * contracts containing the actual logic or the interface contract.\n * ABI for LoanToken contracts: LoanTokenLogicStandard\n * ABI for Protocol contract: ISovryn\n *\n * @dev UpgradableProxy is the contract that inherits Proxy and wraps these\n * functions.\n * */\ncontract Proxy is Ownable {\n bytes32 private constant KEY_IMPLEMENTATION = keccak256(\"key.implementation\");\n\n event ImplementationChanged(\n address indexed _oldImplementation,\n address indexed _newImplementation\n );\n\n /**\n * @notice Set address of the implementation.\n * @param _implementation Address of the implementation.\n * */\n function _setImplementation(address _implementation) internal {\n require(_implementation != address(0), \"Proxy::setImplementation: invalid address\");\n emit ImplementationChanged(getImplementation(), _implementation);\n\n bytes32 key = KEY_IMPLEMENTATION;\n assembly {\n sstore(key, _implementation)\n }\n }\n\n /**\n * @notice Return address of the implementation.\n * @return _implementation Address of the implementation.\n * */\n function getImplementation() public view returns (address _implementation) {\n bytes32 key = KEY_IMPLEMENTATION;\n assembly {\n _implementation := sload(key)\n }\n }\n\n /**\n * @notice Fallback function performs a delegate call\n * to the actual implementation address is pointing this proxy.\n * Returns whatever the implementation call returns.\n * */\n fallback() external payable {\n delegate();\n }\n\n /**\n * @notice Fallback function performs a delegate call\n * to the actual implementation address is pointing this proxy.\n * Returns whatever the implementation call returns.\n * */\n receive() external payable {\n delegate();\n }\n\n function delegate() internal {\n address implementation = getImplementation();\n require(implementation != address(0), \"Proxy::(): implementation not found\");\n\n assembly {\n let pointer := mload(0x40)\n calldatacopy(pointer, 0, calldatasize())\n let result := delegatecall(gas(), implementation, pointer, calldatasize(), 0, 0)\n let size := returndatasize()\n returndatacopy(pointer, 0, size)\n\n switch result\n case 0 {\n revert(pointer, size)\n }\n default {\n return(pointer, size)\n }\n }\n }\n}\n" + }, + "contracts/Proxy/StabilityPoolScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/IStabilityPool.sol\";\n\n\ncontract StabilityPoolScript is CheckContract {\n string constant public NAME = \"StabilityPoolScript\";\n\n IStabilityPool immutable stabilityPool;\n\n constructor(IStabilityPool _stabilityPool) public {\n checkContract(address(_stabilityPool));\n stabilityPool = _stabilityPool;\n }\n\n function provideToSP(uint _amount, address _frontEndTag) external {\n stabilityPool.provideToSP(_amount, _frontEndTag);\n }\n\n function withdrawFromSP(uint _amount) external {\n stabilityPool.withdrawFromSP(_amount);\n }\n\n function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external {\n stabilityPool.withdrawETHGainToTrove(_upperHint, _lowerHint);\n }\n}\n" + }, + "contracts/Proxy/TokenScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/IERC20.sol\";\n\n\ncontract TokenScript is CheckContract {\n string constant public NAME = \"TokenScript\";\n\n IERC20 immutable token;\n\n constructor(address _tokenAddress) public {\n checkContract(_tokenAddress);\n token = IERC20(_tokenAddress);\n }\n\n function transfer(address recipient, uint256 amount) external returns (bool) {\n token.transfer(recipient, amount);\n }\n\n function allowance(address owner, address spender) external view returns (uint256) {\n token.allowance(owner, spender);\n }\n\n function approve(address spender, uint256 amount) external returns (bool) {\n token.approve(spender, amount);\n }\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {\n token.transferFrom(sender, recipient, amount);\n }\n\n function increaseAllowance(address spender, uint256 addedValue) external returns (bool) {\n token.increaseAllowance(spender, addedValue);\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool) {\n token.decreaseAllowance(spender, subtractedValue);\n }\n}\n" + }, + "contracts/Proxy/TroveManagerScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/ITroveManager.sol\";\n\n\ncontract TroveManagerScript is CheckContract {\n string constant public NAME = \"TroveManagerScript\";\n\n ITroveManager immutable troveManager;\n\n constructor(ITroveManager _troveManager) public {\n checkContract(address(_troveManager));\n troveManager = _troveManager;\n }\n\n function redeemCollateral(\n uint _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint _partialRedemptionHintNICR,\n uint _maxIterations,\n uint _maxFee\n ) external returns (uint) {\n troveManager.redeemCollateral(\n _ZUSDAmount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n _maxIterations,\n _maxFee\n );\n }\n}\n" + }, + "contracts/Proxy/UpgradableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Proxy.sol\";\n\n/**\n * @title Upgradable Proxy contract.\n *\n * Adapted version of https://github.com/DistributedCollective/Sovryn-smart-contracts/blob/development/contracts/proxy/UpgradableProxy.sol\n * \n * @notice A disadvantage of the immutable ledger is that nobody can change the\n * source code of a smart contract after it’s been deployed. In order to fix\n * bugs or introduce new features, smart contracts need to be upgradable somehow.\n *\n * Although it is not possible to upgrade the code of an already deployed smart\n * contract, it is possible to set-up a proxy contract architecture that will\n * allow to use new deployed contracts as if the main logic had been upgraded.\n *\n * A proxy architecture pattern is such that all message calls go through a\n * Proxy contract that will redirect them to the latest deployed contract logic.\n * To upgrade, a new version of the contract is deployed, and the Proxy is\n * updated to reference the new contract address.\n * */\ncontract UpgradableProxy is Proxy {\n /**\n * @notice Set address of the implementation.\n * @dev Wrapper for _setImplementation that exposes the function\n * as public for owner to be able to set a new version of the\n * contract as current pointing implementation.\n * @param _implementation Address of the implementation.\n * */\n function setImplementation(address _implementation) public onlyOwner {\n _setImplementation(_implementation);\n }\n\n}\n" + }, + "contracts/Proxy/ZEROStakingScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\n\n\ncontract ZEROStakingScript is CheckContract {\n IZEROStaking immutable ZEROStaking;\n\n constructor(address _zeroStakingAddress) public {\n checkContract(_zeroStakingAddress);\n ZEROStaking = IZEROStaking(_zeroStakingAddress);\n }\n\n function stake(uint _ZEROamount) external {\n ZEROStaking.stake(_ZEROamount);\n }\n}\n" + }, + "contracts/SortedTroves.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./SortedTrovesStorage.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\n\n/**\n * A sorted doubly linked list with nodes sorted in descending order.\n *\n * Nodes map to active Troves in the system - the ID property is the address of a Trove owner.\n * Nodes are ordered according to their current nominal individual collateral ratio (NICR),\n * which is like the ICR but without the price, i.e., just collateral / debt.\n *\n * The list optionally accepts insert position hints.\n *\n * NICRs are computed dynamically at runtime, and not stored on the Node. This is because NICRs of active Troves\n * change dynamically as liquidation events occur.\n *\n * The list relies on the fact that liquidation events preserve ordering: a liquidation decreases the NICRs of all active Troves,\n * but maintains their order. A node inserted based on current NICR will maintain the correct position,\n * relative to it's peers, as rewards accumulate, as long as it's raw collateral and debt have not changed.\n * Thus, Nodes remain sorted by current NICR.\n *\n * Nodes need only be re-inserted upon a Trove operation - when the owner adds or removes collateral or debt\n * to their position.\n *\n * The list is a modification of the following audited SortedDoublyLinkedList:\n * https://github.com/livepeer/protocol/blob/master/contracts/libraries/SortedDoublyLL.sol\n *\n *\n * Changes made in the Zero implementation:\n *\n * - Keys have been removed from nodes\n *\n * - Ordering checks for insertion are performed by comparing an NICR argument to the current NICR, calculated at runtime.\n * The list relies on the property that ordering by ICR is maintained as the ETH:USD price varies.\n *\n * - Public functions with parameters have been made internal to save gas, and given an external wrapper function for external access\n */\ncontract SortedTroves is SortedTrovesStorage, CheckContract, ISortedTroves {\n using SafeMath for uint256;\n\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event NodeAdded(address _id, uint256 _NICR);\n event NodeRemoved(address _id);\n\n // --- Dependency setters ---\n\n function setParams(\n uint256 _size,\n address _troveManagerAddress,\n address _borrowerOperationsAddress\n ) external override onlyOwner {\n require(_size > 0, \"SortedTroves: Size can’t be zero\");\n checkContract(_troveManagerAddress);\n checkContract(_borrowerOperationsAddress);\n\n data.maxSize = _size;\n\n troveManager = ITroveManager(_troveManagerAddress);\n borrowerOperationsAddress = _borrowerOperationsAddress;\n\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n }\n\n /**\n * @dev Add a node to the list\n * @param _id Node's id\n * @param _NICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n\n function insert(\n address _id,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external override {\n ITroveManager troveManagerCached = troveManager;\n\n _requireCallerIsBOorTroveM(troveManagerCached);\n _insert(troveManagerCached, _id, _NICR, _prevId, _nextId);\n }\n\n function _insert(\n ITroveManager _troveManager,\n address _id,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) internal {\n // List must not be full\n require(!isFull(), \"SortedTroves: List is full\");\n // List must not already contain node\n require(!contains(_id), \"SortedTroves: List already contains the node\");\n // Node id must not be null\n require(_id != address(0), \"SortedTroves: Id cannot be zero\");\n // NICR must be non-zero\n require(_NICR > 0, \"SortedTroves: NICR must be positive\");\n\n address prevId = _prevId;\n address nextId = _nextId;\n\n if (!_validInsertPosition(_troveManager, _NICR, prevId, nextId)) {\n // Sender's hint was not a valid insert position\n // Use sender's hint to find a valid insert position\n (prevId, nextId) = _findInsertPosition(_troveManager, _NICR, prevId, nextId);\n }\n\n data.nodes[_id].exists = true;\n\n if (prevId == address(0) && nextId == address(0)) {\n // Insert as head and tail\n data.head = _id;\n data.tail = _id;\n } else if (prevId == address(0)) {\n // Insert before `prevId` as the head\n data.nodes[_id].nextId = data.head;\n data.nodes[data.head].prevId = _id;\n data.head = _id;\n } else if (nextId == address(0)) {\n // Insert after `nextId` as the tail\n data.nodes[_id].prevId = data.tail;\n data.nodes[data.tail].nextId = _id;\n data.tail = _id;\n } else {\n // Insert at insert position between `prevId` and `nextId`\n data.nodes[_id].nextId = nextId;\n data.nodes[_id].prevId = prevId;\n data.nodes[prevId].nextId = _id;\n data.nodes[nextId].prevId = _id;\n }\n\n data.size = data.size.add(1);\n emit NodeAdded(_id, _NICR);\n }\n\n function remove(address _id) external override {\n _requireCallerIsTroveManager();\n _remove(_id);\n }\n\n /**\n * @dev Remove a node from the list\n * @param _id Node's id\n */\n function _remove(address _id) internal {\n // List must contain the node\n require(contains(_id), \"SortedTroves: List does not contain the id\");\n\n if (data.size > 1) {\n // List contains more than a single node\n if (_id == data.head) {\n // The removed node is the head\n // Set head to next node\n data.head = data.nodes[_id].nextId;\n // Set prev pointer of new head to null\n data.nodes[data.head].prevId = address(0);\n } else if (_id == data.tail) {\n // The removed node is the tail\n // Set tail to previous node\n data.tail = data.nodes[_id].prevId;\n // Set next pointer of new tail to null\n data.nodes[data.tail].nextId = address(0);\n } else {\n // The removed node is neither the head nor the tail\n // Set next pointer of previous node to the next node\n data.nodes[data.nodes[_id].prevId].nextId = data.nodes[_id].nextId;\n // Set prev pointer of next node to the previous node\n data.nodes[data.nodes[_id].nextId].prevId = data.nodes[_id].prevId;\n }\n } else {\n // List contains a single node\n // Set the head and tail to null\n data.head = address(0);\n data.tail = address(0);\n }\n\n delete data.nodes[_id];\n data.size = data.size.sub(1);\n NodeRemoved(_id);\n }\n\n /**\n * @dev Re-insert the node at a new position, based on its new NICR\n * @param _id Node's id\n * @param _newNICR Node's new NICR\n * @param _prevId Id of previous node for the new insert position\n * @param _nextId Id of next node for the new insert position\n */\n function reInsert(\n address _id,\n uint256 _newNICR,\n address _prevId,\n address _nextId\n ) external override {\n ITroveManager troveManagerCached = troveManager;\n\n _requireCallerIsBOorTroveM(troveManagerCached);\n // List must contain the node\n require(contains(_id), \"SortedTroves: List does not contain the id\");\n // NICR must be non-zero\n require(_newNICR > 0, \"SortedTroves: NICR must be positive\");\n\n // Remove node from the list\n _remove(_id);\n\n _insert(troveManagerCached, _id, _newNICR, _prevId, _nextId);\n }\n\n /**\n * @dev Checks if the list contains a node\n */\n function contains(address _id) public view override returns (bool) {\n return data.nodes[_id].exists;\n }\n\n /**\n * @dev Checks if the list is full\n */\n function isFull() public view override returns (bool) {\n return data.size == data.maxSize;\n }\n\n /**\n * @dev Checks if the list is empty\n */\n function isEmpty() public view override returns (bool) {\n return data.size == 0;\n }\n\n /**\n * @dev Returns the current size of the list\n */\n function getSize() external view override returns (uint256) {\n return data.size;\n }\n\n /**\n * @dev Returns the maximum size of the list\n */\n function getMaxSize() external view override returns (uint256) {\n return data.maxSize;\n }\n\n /**\n * @dev Returns the first node in the list (node with the largest NICR)\n */\n function getFirst() external view override returns (address) {\n return data.head;\n }\n\n /**\n * @dev Returns the last node in the list (node with the smallest NICR)\n */\n function getLast() external view override returns (address) {\n return data.tail;\n }\n\n /**\n * @dev Returns the next node (with a smaller NICR) in the list for a given node\n * @param _id Node's id\n */\n function getNext(address _id) external view override returns (address) {\n return data.nodes[_id].nextId;\n }\n\n /**\n * @dev Returns the previous node (with a larger NICR) in the list for a given node\n * @param _id Node's id\n */\n function getPrev(address _id) external view override returns (address) {\n return data.nodes[_id].prevId;\n }\n\n /**\n * @dev Check if a pair of nodes is a valid insertion point for a new node with the given NICR\n * @param _NICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function validInsertPosition(\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external view override returns (bool) {\n return _validInsertPosition(troveManager, _NICR, _prevId, _nextId);\n }\n\n function _validInsertPosition(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) internal view returns (bool) {\n if (_prevId == address(0) && _nextId == address(0)) {\n // `(null, null)` is a valid insert position if the list is empty\n return isEmpty();\n } else if (_prevId == address(0)) {\n // `(null, _nextId)` is a valid insert position if `_nextId` is the head of the list\n return data.head == _nextId && _NICR >= _troveManager.getNominalICR(_nextId);\n } else if (_nextId == address(0)) {\n // `(_prevId, null)` is a valid insert position if `_prevId` is the tail of the list\n return data.tail == _prevId && _NICR <= _troveManager.getNominalICR(_prevId);\n } else {\n // `(_prevId, _nextId)` is a valid insert position if they are adjacent nodes and `_NICR` falls between the two nodes' NICRs\n return\n data.nodes[_prevId].nextId == _nextId &&\n _troveManager.getNominalICR(_prevId) >= _NICR &&\n _NICR >= _troveManager.getNominalICR(_nextId);\n }\n }\n\n /**\n * @dev Descend the list (larger NICRs to smaller NICRs) to find a valid insert position\n * @param _troveManager TroveManager contract, passed in as param to save SLOAD’s\n * @param _NICR Node's NICR\n * @param _startId Id of node to start descending the list from\n */\n function _descendList(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _startId\n ) internal view returns (address, address) {\n // If `_startId` is the head, check if the insert position is before the head\n if (data.head == _startId && _NICR >= _troveManager.getNominalICR(_startId)) {\n return (address(0), _startId);\n }\n\n address prevId = _startId;\n address nextId = data.nodes[prevId].nextId;\n\n // Descend the list until we reach the end or until we find a valid insert position\n while (\n prevId != address(0) && !_validInsertPosition(_troveManager, _NICR, prevId, nextId)\n ) {\n prevId = data.nodes[prevId].nextId;\n nextId = data.nodes[prevId].nextId;\n }\n\n return (prevId, nextId);\n }\n\n /**\n * @dev Ascend the list (smaller NICRs to larger NICRs) to find a valid insert position\n * @param _troveManager TroveManager contract, passed in as param to save SLOAD’s\n * @param _NICR Node's NICR\n * @param _startId Id of node to start ascending the list from\n */\n function _ascendList(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _startId\n ) internal view returns (address, address) {\n // If `_startId` is the tail, check if the insert position is after the tail\n if (data.tail == _startId && _NICR <= _troveManager.getNominalICR(_startId)) {\n return (_startId, address(0));\n }\n\n address nextId = _startId;\n address prevId = data.nodes[nextId].prevId;\n\n // Ascend the list until we reach the end or until we find a valid insertion point\n while (\n nextId != address(0) && !_validInsertPosition(_troveManager, _NICR, prevId, nextId)\n ) {\n nextId = data.nodes[nextId].prevId;\n prevId = data.nodes[nextId].prevId;\n }\n\n return (prevId, nextId);\n }\n\n /**\n * @dev Find the insert position for a new node with the given NICR\n * @param _NICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function findInsertPosition(\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external view override returns (address, address) {\n return _findInsertPosition(troveManager, _NICR, _prevId, _nextId);\n }\n\n function _findInsertPosition(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) internal view returns (address, address) {\n address prevId = _prevId;\n address nextId = _nextId;\n\n if (prevId != address(0)) {\n if (!contains(prevId) || _NICR > _troveManager.getNominalICR(prevId)) {\n // `prevId` does not exist anymore or now has a smaller NICR than the given NICR\n prevId = address(0);\n }\n }\n\n if (nextId != address(0)) {\n if (!contains(nextId) || _NICR < _troveManager.getNominalICR(nextId)) {\n // `nextId` does not exist anymore or now has a larger NICR than the given NICR\n nextId = address(0);\n }\n }\n\n if (prevId == address(0) && nextId == address(0)) {\n // No hint - descend list starting from head\n return _descendList(_troveManager, _NICR, data.head);\n } else if (prevId == address(0)) {\n // No `prevId` for hint - ascend list starting from `nextId`\n return _ascendList(_troveManager, _NICR, nextId);\n } else if (nextId == address(0)) {\n // No `nextId` for hint - descend list starting from `prevId`\n return _descendList(_troveManager, _NICR, prevId);\n } else {\n // Descend list starting from `prevId`\n return _descendList(_troveManager, _NICR, prevId);\n }\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsTroveManager() internal view {\n require(\n msg.sender == address(troveManager),\n \"SortedTroves: Caller is not the TroveManager\"\n );\n }\n\n function _requireCallerIsBOorTroveM(ITroveManager _troveManager) internal view {\n require(\n msg.sender == borrowerOperationsAddress || msg.sender == address(_troveManager),\n \"SortedTroves: Caller is neither BO nor TroveM\"\n );\n }\n}\n" + }, + "contracts/SortedTrovesStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\n\ncontract SortedTrovesStorage is Ownable {\n string public constant NAME = \"SortedTroves\";\n\n address public borrowerOperationsAddress;\n\n ITroveManager public troveManager;\n\n // Information for a node in the list\n struct Node {\n bool exists;\n address nextId; // Id of next node (smaller NICR) in the list\n address prevId; // Id of previous node (larger NICR) in the list\n }\n\n // Information for the list\n struct Data {\n address head; // Head of the list. Also the node in the list with the largest NICR\n address tail; // Tail of the list. Also the node in the list with the smallest NICR\n uint256 maxSize; // Maximum size of the list\n uint256 size; // Current size of the list\n mapping(address => Node) nodes; // Track the corresponding ids for each node in the list\n }\n\n Data public data;\n}\n" + }, + "contracts/StabilityPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ICommunityIssuance.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/LiquitySafeMath128.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/Mynt/MyntLib.sol\";\nimport \"./StabilityPoolStorage.sol\";\n\n/**\n * The Stability Pool holds ZUSD tokens deposited by Stability Pool depositors.\n *\n * When a trove is liquidated, then depending on system conditions, some of its ZUSD debt gets offset with\n * ZUSD in the Stability Pool: that is, the offset debt evaporates, and an equal amount of ZUSD tokens in the Stability Pool is burned.\n *\n * Thus, a liquidation causes each depositor to receive a ZUSD loss, in proportion to their deposit as a share of total deposits.\n * They also receive an ETH gain, as the ETH collateral of the liquidated trove is distributed among Stability depositors,\n * in the same proportion.\n *\n * When a liquidation occurs, it depletes every deposit by the same fraction: for example, a liquidation that depletes 40%\n * of the total ZUSD in the Stability Pool, depletes 40% of each deposit.\n *\n * A deposit that has experienced a series of liquidations is termed a \"compounded deposit\": each liquidation depletes the deposit,\n * multiplying it by some factor in range ]0,1[\n *\n *\n * --- IMPLEMENTATION ---\n *\n * We use a highly scalable method of tracking deposits and ETH gains that has O(1) complexity.\n *\n * When a liquidation occurs, rather than updating each depositor's deposit and ETH gain, we simply update two state variables:\n * a product P, and a sum S.\n *\n * A mathematical manipulation allows us to factor out the initial deposit, and accurately track all depositors' compounded deposits\n * and accumulated ETH gains over time, as liquidations occur, using just these two variables P and S. When depositors join the\n * Stability Pool, they get a snapshot of the latest P and S: P_t and S_t, respectively.\n *\n * The formula for a depositor's accumulated ETH gain is derived here:\n * https://github.com/liquity/dev/blob/main/packages/contracts/mathProofs/Scalable%20Compounding%20Stability%20Pool%20Deposits.pdf\n *\n * For a given deposit d_t, the ratio P/P_t tells us the factor by which a deposit has decreased since it joined the Stability Pool,\n * and the term d_t * (S - S_t)/P_t gives us the deposit's total accumulated ETH gain.\n *\n * Each liquidation updates the product P and sum S. After a series of liquidations, a compounded deposit and corresponding ETH gain\n * can be calculated using the initial deposit, the depositor’s snapshots of P and S, and the latest values of P and S.\n *\n * Any time a depositor updates their deposit (withdrawal, top-up) their accumulated ETH gain is paid out, their new deposit is recorded\n * (based on their latest compounded deposit and modified by the withdrawal/top-up), and they receive new snapshots of the latest P and S.\n * Essentially, they make a fresh deposit that overwrites the old one.\n *\n *\n * --- SCALE FACTOR ---\n *\n * Since P is a running product in range ]0,1] that is always-decreasing, it should never reach 0 when multiplied by a number in range ]0,1[.\n * Unfortunately, Solidity floor division always reaches 0, sooner or later.\n *\n * A series of liquidations that nearly empty the Pool (and thus each multiply P by a very small number in range ]0,1[ ) may push P\n * to its 18 digit decimal limit, and round it to 0, when in fact the Pool hasn't been emptied: this would break deposit tracking.\n *\n * So, to track P accurately, we use a scale factor: if a liquidation would cause P to decrease to <1e-9 (and be rounded to 0 by Solidity),\n * we first multiply P by 1e9, and increment a currentScale factor by 1.\n *\n * The added benefit of using 1e9 for the scale factor (rather than 1e18) is that it ensures negligible precision loss close to the\n * scale boundary: when P is at its minimum value of 1e9, the relative precision loss in P due to floor division is only on the\n * order of 1e-9.\n *\n * --- EPOCHS ---\n *\n * Whenever a liquidation fully empties the Stability Pool, all deposits should become 0. However, setting P to 0 would make P be 0\n * forever, and break all future reward calculations.\n *\n * So, every time the Stability Pool is emptied by a liquidation, we reset P = 1 and currentScale = 0, and increment the currentEpoch by 1.\n *\n * --- TRACKING DEPOSIT OVER SCALE CHANGES AND EPOCHS ---\n *\n * When a deposit is made, it gets snapshots of the currentEpoch and the currentScale.\n *\n * When calculating a compounded deposit, we compare the current epoch to the deposit's epoch snapshot. If the current epoch is newer,\n * then the deposit was present during a pool-emptying liquidation, and necessarily has been depleted to 0.\n *\n * Otherwise, we then compare the current scale to the deposit's scale snapshot. If they're equal, the compounded deposit is given by d_t * P/P_t.\n * If it spans one scale change, it is given by d_t * P/(P_t * 1e9). If it spans more than one scale change, we define the compounded deposit\n * as 0, since it is now less than 1e-9'th of its initial value (e.g. a deposit of 1 billion ZUSD has depleted to < 1 ZUSD).\n *\n *\n * --- TRACKING DEPOSITOR'S ETH GAIN OVER SCALE CHANGES AND EPOCHS ---\n *\n * In the current epoch, the latest value of S is stored upon each scale change, and the mapping (scale -> S) is stored for each epoch.\n *\n * This allows us to calculate a deposit's accumulated ETH gain, during the epoch in which the deposit was non-sov and earned ETH.\n *\n * We calculate the depositor's accumulated ETH gain for the scale at which they made the deposit, using the ETH gain formula:\n * e_1 = d_t * (S - S_t) / P_t\n *\n * and also for scale after, taking care to divide the latter by a factor of 1e9:\n * e_2 = d_t * S / (P_t * 1e9)\n *\n * The gain in the second scale will be full, as the starting point was in the previous scale, thus no need to subtract anything.\n * The deposit therefore was present for reward events from the beginning of that second scale.\n *\n * S_i-S_t + S_{i+1}\n * .<--------.------------>\n * . .\n * . S_i . S_{i+1}\n * <--.-------->.<----------->\n * S_t. .\n * <->. .\n * t .\n * |---+---------|-------------|-----...\n * i i+1\n *\n * The sum of (e_1 + e_2) captures the depositor's total accumulated ETH gain, handling the case where their\n * deposit spanned one scale change. We only care about gains across one scale change, since the compounded\n * deposit is defined as being 0 once it has spanned more than one scale change.\n *\n *\n * --- UPDATING P WHEN A LIQUIDATION OCCURS ---\n *\n * Please see the implementation spec in the proof document, which closely follows on from the compounded deposit / ETH gain derivations:\n * https://github.com/liquity/liquity/blob/master/papers/Scalable_Reward_Distribution_with_Compounding_Stakes.pdf\n *\n *\n * --- SOV ISSUANCE TO STABILITY POOL DEPOSITORS ---\n *\n * An SOV issuance event occurs at every deposit operation, and every liquidation.\n *\n * Each deposit is tagged with the address of the front end through which it was made.\n *\n * All deposits earn a share of the issued SOV in proportion to the deposit as a share of total deposits. The SOV earned\n * by a given deposit, is split between the depositor and the front end through which the deposit was made, based on the front end's kickbackRate.\n *\n * Please see the system Readme for an overview:\n * https://github.com/liquity/dev/blob/main/README.md#zero-issuance-to-stability-providers\n *\n * We use the same mathematical product-sum approach to track SOV gains for depositors, where 'G' is the sum corresponding to SOV gains.\n * The product P (and snapshot P_t) is re-used, as the ratio P/P_t tracks a deposit's depletion due to liquidations.\n *\n */\ncontract StabilityPool is LiquityBase, StabilityPoolStorage, CheckContract, IStabilityPool {\n using LiquitySafeMath128 for uint128;\n address private constant ADDRESS_ZERO = address(0);\n\n // --- Events ---\n\n event StabilityPoolETHBalanceUpdated(uint256 _newBalance);\n event StabilityPoolZUSDBalanceUpdated(uint256 _newBalance);\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n event DefaultPoolAddressChanged(address _newDefaultPoolAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event SortedTrovesAddressChanged(address _newSortedTrovesAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event CommunityIssuanceAddressChanged(address _newCommunityIssuanceAddress);\n\n event P_Updated(uint256 _P);\n event S_Updated(uint256 _S, uint128 _epoch, uint128 _scale);\n event G_Updated(uint256 _G, uint128 _epoch, uint128 _scale);\n event EpochUpdated(uint128 _currentEpoch);\n event ScaleUpdated(uint128 _currentScale);\n\n event FrontEndRegistered(address indexed _frontEnd, uint256 _kickbackRate);\n event FrontEndTagSet(address indexed _depositor, address indexed _frontEnd);\n\n event DepositSnapshotUpdated(address indexed _depositor, uint256 _P, uint256 _S, uint256 _G);\n event FrontEndSnapshotUpdated(address indexed _frontEnd, uint256 _P, uint256 _G);\n event UserDepositChanged(address indexed _depositor, uint256 _newDeposit);\n event FrontEndStakeChanged(\n address indexed _frontEnd,\n uint256 _newFrontEndStake,\n address _depositor\n );\n\n event ETHGainWithdrawn(address indexed _depositor, uint256 _ETH, uint256 _ZUSDLoss);\n event SOVPaidToDepositor(address indexed _depositor, uint256 _SOV);\n event SOVPaidToFrontEnd(address indexed _frontEnd, uint256 _SOV);\n event EtherSent(address _to, uint256 _amount);\n\n // --- Contract setters ---\n\n function setAddresses(\n address _liquityBaseParamsAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _zusdTokenAddress,\n address _sortedTrovesAddress,\n address _priceFeedAddress,\n address _communityIssuanceAddress\n ) external override onlyOwner {\n checkContract(_liquityBaseParamsAddress);\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_sortedTrovesAddress);\n checkContract(_priceFeedAddress);\n checkContract(_communityIssuanceAddress);\n\n P = DECIMAL_PRECISION;\n\n liquityBaseParams = ILiquityBaseParams(_liquityBaseParamsAddress);\n borrowerOperations = IBorrowerOperations(_borrowerOperationsAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n activePool = IActivePool(_activePoolAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n priceFeed = IPriceFeed(_priceFeedAddress);\n communityIssuance = ICommunityIssuance(_communityIssuanceAddress);\n\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n emit ZUSDTokenAddressChanged(_zusdTokenAddress);\n emit SortedTrovesAddressChanged(_sortedTrovesAddress);\n emit PriceFeedAddressChanged(_priceFeedAddress);\n emit CommunityIssuanceAddressChanged(_communityIssuanceAddress);\n }\n\n /**\n * @dev setter function specific for community issuance contract.\n * @param _communityIssuanceAddress address of new community issuance contract.\n */\n function setCommunityIssuanceAddress(address _communityIssuanceAddress) external onlyOwner {\n checkContract(_communityIssuanceAddress);\n communityIssuance = ICommunityIssuance(_communityIssuanceAddress);\n emit CommunityIssuanceAddressChanged(_communityIssuanceAddress);\n }\n\n // --- Getters for public variables. Required by IPool interface ---\n\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n function getTotalZUSDDeposits() external view override returns (uint256) {\n return totalZUSDDeposits;\n }\n\n // --- External Depositor Functions ---\n\n /** provideToSP():\n *\n * - Triggers a SOV issuance, based on time passed since the last issuance and total amount of ZUSD is deposited. The SOV issuance is shared between *all* depositors and front ends\n * - Tags the deposit with the provided front end tag param, if it's a new deposit\n * - Sends depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Increases deposit and tagged front end's stake, and takes new snapshots for each.\n */\n function provideToSP(uint256 _amount, address _frontEndTag) external override {\n _provideToSP(_amount, _frontEndTag);\n }\n\n function _provideToSP(uint256 _amount, address _frontEndTag) internal {\n _requireFrontEndIsRegisteredOrZero(_frontEndTag);\n _requireFrontEndNotRegistered(msg.sender);\n _requireNonZeroAmount(_amount);\n\n uint256 initialDeposit = deposits[msg.sender].initialValue;\n\n ICommunityIssuance communityIssuanceCached = communityIssuance;\n\n _triggerSOVIssuance(communityIssuanceCached);\n\n if (initialDeposit == 0) {\n _setFrontEndTag(msg.sender, _frontEndTag);\n }\n uint256 depositorETHGain = getDepositorETHGain(msg.sender);\n uint256 compoundedZUSDDeposit = getCompoundedZUSDDeposit(msg.sender);\n uint256 ZUSDLoss = initialDeposit.sub(compoundedZUSDDeposit); // Needed only for event log\n\n // First pay out any SOV gains\n address frontEnd = deposits[msg.sender].frontEndTag;\n _payOutSOVGains(communityIssuanceCached, msg.sender, frontEnd);\n\n // Update front end stake\n uint256 compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd);\n uint256 newFrontEndStake = compoundedFrontEndStake.add(_amount);\n _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake);\n emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender);\n\n _sendZUSDtoStabilityPool(msg.sender, _amount);\n\n uint256 newDeposit = compoundedZUSDDeposit.add(_amount);\n _updateDepositAndSnapshots(msg.sender, newDeposit);\n emit UserDepositChanged(msg.sender, newDeposit);\n\n emit ETHGainWithdrawn(msg.sender, depositorETHGain, ZUSDLoss); // ZUSD Loss required for event log\n\n _sendETHGainToDepositor(depositorETHGain);\n }\n\n ///DLLR _owner or _spender can convert a specified amount of DLLR into ZUSD via Sovryn Mynt and deposit the ZUSD into the SOV Stability Pool, all in a single transaction\n function provideToSpFromDLLR(\n uint256 _dllrAmount,\n IMassetManager.PermitParams calldata _permitParams\n ) external override {\n uint256 _ZUSDAmount = MyntLib.redeemZusdFromDllrWithPermit(\n borrowerOperations.getMassetManager(),\n _dllrAmount,\n address(zusdToken),\n _permitParams\n );\n\n _provideToSP(_ZUSDAmount, ADDRESS_ZERO);\n }\n\n /** withdrawFromSP():\n *\n * - Triggers a SOV issuance, based on time passed since the last issuance and total amount of ZUSD is deposited. The SOV issuance is shared between *all* depositors and front ends\n * - Removes the deposit's front end tag if it is a full withdrawal\n * - Sends all depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Decreases deposit and tagged front end's stake, and takes new snapshots for each.\n *\n * If _amount > userDeposit, the user withdraws all of their compounded deposit.\n */\n function withdrawFromSP(uint256 _amount) external override {\n _withdrawFromSpTo(_amount, msg.sender);\n }\n\n ///@return actual ZUSD amount withdrawn\n function _withdrawFromSpTo(uint256 _amount, address _receiver) internal returns (uint256) {\n require(_receiver != address(0), \"SP::_withdrawFromSpTo: _receiver is zero address\");\n if (_amount != 0) {\n _requireNoUnderCollateralizedTroves();\n }\n uint256 initialDeposit = deposits[msg.sender].initialValue;\n _requireUserHasDeposit(initialDeposit);\n\n ICommunityIssuance communityIssuanceCached = communityIssuance;\n\n _triggerSOVIssuance(communityIssuanceCached);\n\n uint256 depositorETHGain = getDepositorETHGain(msg.sender);\n\n uint256 compoundedZUSDDeposit = getCompoundedZUSDDeposit(msg.sender);\n uint256 ZUSDtoWithdraw = LiquityMath._min(_amount, compoundedZUSDDeposit);\n uint256 ZUSDLoss = initialDeposit.sub(compoundedZUSDDeposit); // Needed only for event log\n\n // First pay out any SOV gains\n address frontEnd = deposits[msg.sender].frontEndTag;\n _payOutSOVGains(communityIssuanceCached, msg.sender, frontEnd);\n\n // Update front end stake\n uint256 compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd);\n uint256 newFrontEndStake = compoundedFrontEndStake.sub(ZUSDtoWithdraw);\n _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake);\n emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender);\n\n _sendZUSDToDepositor(_receiver, ZUSDtoWithdraw);\n\n // Update deposit\n uint256 newDeposit = compoundedZUSDDeposit.sub(ZUSDtoWithdraw);\n _updateDepositAndSnapshots(msg.sender, newDeposit);\n emit UserDepositChanged(msg.sender, newDeposit);\n\n emit ETHGainWithdrawn(msg.sender, depositorETHGain, ZUSDLoss); // ZUSD Loss required for event log\n\n _sendETHGainTo(depositorETHGain, msg.sender);\n\n return ZUSDtoWithdraw;\n }\n\n ///Stability Pool depositor can withdraw a specified amount of ZUSD from the SOV Stability Pool and convert the ZUSD to DLLR via Sovryn Mynt, all in a single transaction\n function withdrawFromSpAndConvertToDLLR(uint256 _zusdAmountRequested) external override {\n IMassetManager massetManager = borrowerOperations.getMassetManager();\n uint256 amountWithdrawn = _withdrawFromSpTo(_zusdAmountRequested, address(this));\n require(\n zusdToken.approve(address(massetManager), amountWithdrawn),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n massetManager.mintTo(address(zusdToken), amountWithdrawn, msg.sender);\n emit WithdrawFromSpAndConvertToDLLR(msg.sender, _zusdAmountRequested, amountWithdrawn);\n }\n\n /** withdrawETHGainToTrove:\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Sends all depositor's SOV gain to depositor\n * - Sends all tagged front end's SOV gain to the tagged front end\n * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove\n * - Leaves their compounded deposit in the Stability Pool\n * - Updates snapshots for deposit and tagged front end stake */\n function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external override {\n uint256 initialDeposit = deposits[msg.sender].initialValue;\n _requireUserHasDeposit(initialDeposit);\n _requireUserHasTrove(msg.sender);\n _requireUserHasETHGain(msg.sender);\n\n ICommunityIssuance communityIssuanceCached = communityIssuance;\n\n _triggerSOVIssuance(communityIssuanceCached);\n\n uint256 depositorETHGain = getDepositorETHGain(msg.sender);\n\n uint256 compoundedZUSDDeposit = getCompoundedZUSDDeposit(msg.sender);\n uint256 ZUSDLoss = initialDeposit.sub(compoundedZUSDDeposit); // Needed only for event log\n\n // First pay out any SOV gains\n address frontEnd = deposits[msg.sender].frontEndTag;\n _payOutSOVGains(communityIssuanceCached, msg.sender, frontEnd);\n\n // Update front end stake\n uint256 compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd);\n uint256 newFrontEndStake = compoundedFrontEndStake;\n _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake);\n emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender);\n\n _updateDepositAndSnapshots(msg.sender, compoundedZUSDDeposit);\n\n /* Emit events before transferring ETH gain to Trove.\n This lets the event log make more sense (i.e. so it appears that first the ETH gain is withdrawn\n and then it is deposited into the Trove, not the other way around). */\n emit ETHGainWithdrawn(msg.sender, depositorETHGain, ZUSDLoss);\n emit UserDepositChanged(msg.sender, compoundedZUSDDeposit);\n\n ETH = ETH.sub(depositorETHGain);\n emit StabilityPoolETHBalanceUpdated(ETH);\n emit EtherSent(msg.sender, depositorETHGain);\n\n borrowerOperations.moveETHGainToTrove{ value: depositorETHGain }(\n msg.sender,\n _upperHint,\n _lowerHint\n );\n }\n\n // --- SOV issuance functions ---\n\n function _triggerSOVIssuance(ICommunityIssuance _communityIssuance) internal {\n uint256 SOVIssuance = _communityIssuance.issueSOV(totalZUSDDeposits);\n _updateG(SOVIssuance);\n }\n\n function _updateG(uint256 _SOVIssuance) internal {\n uint256 totalZUSD = totalZUSDDeposits; // cached to save an SLOAD\n /*\n * When total deposits is 0, G is not updated. In this case, the SOV issued can not be obtained by later\n * depositors - it is missed out on, and remains in the balanceof the CommunityIssuance contract.\n *\n */\n if (totalZUSD == 0 || _SOVIssuance == 0) {\n return;\n }\n\n uint256 SOVPerUnitStaked;\n SOVPerUnitStaked = _computeSOVPerUnitStaked(_SOVIssuance, totalZUSD);\n\n uint256 marginalSOVGain = SOVPerUnitStaked.mul(P);\n epochToScaleToG[currentEpoch][currentScale] = epochToScaleToG[currentEpoch][currentScale]\n .add(marginalSOVGain);\n\n emit G_Updated(epochToScaleToG[currentEpoch][currentScale], currentEpoch, currentScale);\n }\n\n function _computeSOVPerUnitStaked(uint256 _SOVIssuance, uint256 _totalZUSDDeposits)\n internal\n returns (uint256)\n {\n /*\n * Calculate the SOV-per-unit staked. Division uses a \"feedback\" error correction, to keep the\n * cumulative error low in the running total G:\n *\n * 1) Form a numerator which compensates for the floor division error that occurred the last time this\n * function was called.\n * 2) Calculate \"per-unit-staked\" ratio.\n * 3) Multiply the ratio back by its denominator, to reveal the current floor division error.\n * 4) Store this error for use in the next correction when this function is called.\n * 5) Note: static analysis tools complain about this \"division before multiplication\", however, it is intended.\n */\n uint256 SOVNumerator = _SOVIssuance.mul(DECIMAL_PRECISION).add(lastSOVError);\n\n uint256 SOVPerUnitStaked = SOVNumerator.div(_totalZUSDDeposits);\n lastSOVError = SOVNumerator.sub(SOVPerUnitStaked.mul(_totalZUSDDeposits));\n\n return SOVPerUnitStaked;\n }\n\n // --- Liquidation functions ---\n\n /**\n * Cancels out the specified debt against the ZUSD contained in the Stability Pool (as far as possible)\n * and transfers the Trove's ETH collateral from ActivePool to StabilityPool.\n * Only called by liquidation functions in the TroveManager.\n */\n function offset(uint256 _debtToOffset, uint256 _collToAdd) external override {\n _requireCallerIsTroveManager();\n uint256 totalZUSD = totalZUSDDeposits; // cached to save an SLOAD\n if (totalZUSD == 0 || _debtToOffset == 0) {\n return;\n }\n\n _triggerSOVIssuance(communityIssuance);\n\n (\n uint256 ETHGainPerUnitStaked,\n uint256 ZUSDLossPerUnitStaked\n ) = _computeRewardsPerUnitStaked(_collToAdd, _debtToOffset, totalZUSD);\n\n _updateRewardSumAndProduct(ETHGainPerUnitStaked, ZUSDLossPerUnitStaked); // updates S and P\n\n _moveOffsetCollAndDebt(_collToAdd, _debtToOffset);\n }\n\n // --- Offset helper functions ---\n\n function _computeRewardsPerUnitStaked(\n uint256 _collToAdd,\n uint256 _debtToOffset,\n uint256 _totalZUSDDeposits\n ) internal returns (uint256 ETHGainPerUnitStaked, uint256 ZUSDLossPerUnitStaked) {\n /*\n * Compute the ZUSD and ETH rewards. Uses a \"feedback\" error correction, to keep\n * the cumulative error in the P and S state variables low:\n *\n * 1) Form numerators which compensate for the floor division errors that occurred the last time this\n * function was called.\n * 2) Calculate \"per-unit-staked\" ratios.\n * 3) Multiply each ratio back by its denominator, to reveal the current floor division error.\n * 4) Store these errors for use in the next correction when this function is called.\n * 5) Note: static analysis tools complain about this \"division before multiplication\", however, it is intended.\n */\n uint256 ETHNumerator = _collToAdd.mul(DECIMAL_PRECISION).add(lastETHError_Offset);\n\n assert(_debtToOffset <= _totalZUSDDeposits);\n if (_debtToOffset == _totalZUSDDeposits) {\n ZUSDLossPerUnitStaked = DECIMAL_PRECISION; // When the Pool depletes to 0, so does each deposit\n lastZUSDLossError_Offset = 0;\n } else {\n uint256 ZUSDLossNumerator = _debtToOffset.mul(DECIMAL_PRECISION).sub(\n lastZUSDLossError_Offset\n );\n /*\n * Add 1 to make error in quotient positive. We want \"slightly too much\" ZUSD loss,\n * which ensures the error in any given compoundedZUSDDeposit favors the Stability Pool.\n */\n ZUSDLossPerUnitStaked = (ZUSDLossNumerator.div(_totalZUSDDeposits)).add(1);\n lastZUSDLossError_Offset = (ZUSDLossPerUnitStaked.mul(_totalZUSDDeposits)).sub(\n ZUSDLossNumerator\n );\n }\n\n ETHGainPerUnitStaked = ETHNumerator.div(_totalZUSDDeposits);\n lastETHError_Offset = ETHNumerator.sub(ETHGainPerUnitStaked.mul(_totalZUSDDeposits));\n\n return (ETHGainPerUnitStaked, ZUSDLossPerUnitStaked);\n }\n\n /// Update the Stability Pool reward sum S and product P\n function _updateRewardSumAndProduct(\n uint256 _ETHGainPerUnitStaked,\n uint256 _ZUSDLossPerUnitStaked\n ) internal {\n uint256 currentP = P;\n uint256 newP;\n\n assert(_ZUSDLossPerUnitStaked <= DECIMAL_PRECISION);\n /*\n * The newProductFactor is the factor by which to change all deposits, due to the depletion of Stability Pool ZUSD in the liquidation.\n * We make the product factor 0 if there was a pool-emptying. Otherwise, it is (1 - ZUSDLossPerUnitStaked)\n */\n uint256 newProductFactor = uint256(DECIMAL_PRECISION).sub(_ZUSDLossPerUnitStaked);\n\n uint128 currentScaleCached = currentScale;\n uint128 currentEpochCached = currentEpoch;\n uint256 currentS = epochToScaleToSum[currentEpochCached][currentScaleCached];\n\n /*\n * Calculate the new S first, before we update P.\n * The ETH gain for any given depositor from a liquidation depends on the value of their deposit\n * (and the value of totalDeposits) prior to the Stability being depleted by the debt in the liquidation.\n *\n * Since S corresponds to ETH gain, and P to deposit loss, we update S first.\n */\n uint256 marginalETHGain = _ETHGainPerUnitStaked.mul(currentP);\n uint256 newS = currentS.add(marginalETHGain);\n epochToScaleToSum[currentEpochCached][currentScaleCached] = newS;\n emit S_Updated(newS, currentEpochCached, currentScaleCached);\n\n // If the Stability Pool was emptied, increment the epoch, and reset the scale and product P\n if (newProductFactor == 0) {\n currentEpoch = currentEpochCached.add(1);\n emit EpochUpdated(currentEpoch);\n currentScale = 0;\n emit ScaleUpdated(currentScale);\n newP = DECIMAL_PRECISION;\n\n // If multiplying P by a non-sov product factor would reduce P below the scale boundary, increment the scale\n } else if (currentP.mul(newProductFactor).div(DECIMAL_PRECISION) < SCALE_FACTOR) {\n newP = currentP.mul(newProductFactor).mul(SCALE_FACTOR).div(DECIMAL_PRECISION);\n currentScale = currentScaleCached.add(1);\n emit ScaleUpdated(currentScale);\n } else {\n newP = currentP.mul(newProductFactor).div(DECIMAL_PRECISION);\n }\n\n assert(newP > 0);\n P = newP;\n\n emit P_Updated(newP);\n }\n\n function _moveOffsetCollAndDebt(uint256 _collToAdd, uint256 _debtToOffset) internal {\n IActivePool activePoolCached = activePool;\n\n // Cancel the liquidated ZUSD debt with the ZUSD in the stability pool\n activePoolCached.decreaseZUSDDebt(_debtToOffset);\n _decreaseZUSD(_debtToOffset);\n\n // Burn the debt that was successfully offset\n zusdToken.burn(address(this), _debtToOffset);\n\n activePoolCached.sendETH(address(this), _collToAdd);\n }\n\n function _decreaseZUSD(uint256 _amount) internal {\n uint256 newTotalZUSDDeposits = totalZUSDDeposits.sub(_amount);\n totalZUSDDeposits = newTotalZUSDDeposits;\n emit StabilityPoolZUSDBalanceUpdated(newTotalZUSDDeposits);\n }\n\n // --- Reward calculator functions for depositor and front end ---\n\n /** Calculates the ETH gain earned by the deposit since its last snapshots were taken.\n * Given by the formula: E = d0 * (S - S(0))/P(0)\n * where S(0) and P(0) are the depositor's snapshots of the sum S and product P, respectively.\n * d0 is the last recorded deposit value.\n */\n function getDepositorETHGain(address _depositor) public view override returns (uint256) {\n uint256 initialDeposit = deposits[_depositor].initialValue;\n\n if (initialDeposit == 0) {\n return 0;\n }\n\n Snapshots memory snapshots = depositSnapshots[_depositor];\n\n uint256 ETHGain = _getETHGainFromSnapshots(initialDeposit, snapshots);\n return ETHGain;\n }\n\n function _getETHGainFromSnapshots(uint256 initialDeposit, Snapshots memory snapshots)\n internal\n view\n returns (uint256)\n {\n /*\n * Grab the sum 'S' from the epoch at which the stake was made. The ETH gain may span up to one scale change.\n * If it does, the second portion of the ETH gain is scaled by 1e9.\n * If the gain spans no scale change, the second portion will be 0.\n */\n uint128 epochSnapshot = snapshots.epoch;\n uint128 scaleSnapshot = snapshots.scale;\n uint256 S_Snapshot = snapshots.S;\n uint256 P_Snapshot = snapshots.P;\n\n uint256 firstPortion = epochToScaleToSum[epochSnapshot][scaleSnapshot].sub(S_Snapshot);\n uint256 secondPortion = epochToScaleToSum[epochSnapshot][scaleSnapshot.add(1)].div(\n SCALE_FACTOR\n );\n\n uint256 ETHGain = initialDeposit.mul(firstPortion.add(secondPortion)).div(P_Snapshot).div(\n DECIMAL_PRECISION\n );\n\n return ETHGain;\n }\n\n /**\n * Calculate the SOV gain earned by a deposit since its last snapshots were taken.\n * Given by the formula: SOV = d0 * (G - G(0))/P(0)\n * where G(0) and P(0) are the depositor's snapshots of the sum G and product P, respectively.\n * d0 is the last recorded deposit value.\n */\n function getDepositorSOVGain(address _depositor) public view override returns (uint256) {\n uint256 initialDeposit = deposits[_depositor].initialValue;\n if (initialDeposit == 0) {\n return 0;\n }\n\n address frontEndTag = deposits[_depositor].frontEndTag;\n\n /*\n * If not tagged with a front end, the depositor gets a 100% cut of what their deposit earned.\n * Otherwise, their cut of the deposit's earnings is equal to the kickbackRate, set by the front end through\n * which they made their deposit.\n */\n uint256 kickbackRate = frontEndTag == ADDRESS_ZERO\n ? DECIMAL_PRECISION\n : frontEnds[frontEndTag].kickbackRate;\n\n Snapshots memory snapshots = depositSnapshots[_depositor];\n\n uint256 SOVGain = kickbackRate\n .mul(_getSOVGainFromSnapshots(initialDeposit, snapshots))\n .div(DECIMAL_PRECISION);\n\n return SOVGain;\n }\n\n /**\n * Return the SOV gain earned by the front end. Given by the formula: E = D0 * (G - G(0))/P(0)\n * where G(0) and P(0) are the depositor's snapshots of the sum G and product P, respectively.\n *\n * D0 is the last recorded value of the front end's total tagged deposits.\n */\n function getFrontEndSOVGain(address _frontEnd) public view override returns (uint256) {\n uint256 frontEndStake = frontEndStakes[_frontEnd];\n if (frontEndStake == 0) {\n return 0;\n }\n\n uint256 kickbackRate = frontEnds[_frontEnd].kickbackRate;\n uint256 frontEndShare = uint256(DECIMAL_PRECISION).sub(kickbackRate);\n\n Snapshots memory snapshots = frontEndSnapshots[_frontEnd];\n\n uint256 SOVGain = frontEndShare\n .mul(_getSOVGainFromSnapshots(frontEndStake, snapshots))\n .div(DECIMAL_PRECISION);\n return SOVGain;\n }\n\n function _getSOVGainFromSnapshots(uint256 initialStake, Snapshots memory snapshots)\n internal\n view\n returns (uint256)\n {\n /*\n * Grab the sum 'G' from the epoch at which the stake was made. The SOV gain may span up to one scale change.\n * If it does, the second portion of the SOV gain is scaled by 1e9.\n * If the gain spans no scale change, the second portion will be 0.\n */\n uint128 epochSnapshot = snapshots.epoch;\n uint128 scaleSnapshot = snapshots.scale;\n uint256 G_Snapshot = snapshots.G;\n uint256 P_Snapshot = snapshots.P;\n\n uint256 firstPortion = epochToScaleToG[epochSnapshot][scaleSnapshot].sub(G_Snapshot);\n uint256 secondPortion = epochToScaleToG[epochSnapshot][scaleSnapshot.add(1)].div(\n SCALE_FACTOR\n );\n\n uint256 SOVGain = initialStake.mul(firstPortion.add(secondPortion)).div(P_Snapshot).div(\n DECIMAL_PRECISION\n );\n\n return SOVGain;\n }\n\n // --- Compounded deposit and compounded front end stake ---\n\n /**\n * Return the user's compounded deposit. Given by the formula: d = d0 * P/P(0)\n * where P(0) is the depositor's snapshot of the product P, taken when they last updated their deposit.\n */\n function getCompoundedZUSDDeposit(address _depositor) public view override returns (uint256) {\n uint256 initialDeposit = deposits[_depositor].initialValue;\n if (initialDeposit == 0) {\n return 0;\n }\n\n Snapshots memory snapshots = depositSnapshots[_depositor];\n\n uint256 compoundedDeposit = _getCompoundedStakeFromSnapshots(initialDeposit, snapshots);\n return compoundedDeposit;\n }\n\n /**\n * Return the front end's compounded stake. Given by the formula: D = D0 * P/P(0)\n * where P(0) is the depositor's snapshot of the product P, taken at the last time\n * when one of the front end's tagged deposits updated their deposit.\n *\n * The front end's compounded stake is equal to the sum of its depositors' compounded deposits.\n */\n function getCompoundedFrontEndStake(address _frontEnd) public view override returns (uint256) {\n uint256 frontEndStake = frontEndStakes[_frontEnd];\n if (frontEndStake == 0) {\n return 0;\n }\n\n Snapshots memory snapshots = frontEndSnapshots[_frontEnd];\n\n uint256 compoundedFrontEndStake = _getCompoundedStakeFromSnapshots(\n frontEndStake,\n snapshots\n );\n return compoundedFrontEndStake;\n }\n\n // Internal function, used to calculcate compounded deposits and compounded front end stakes.\n function _getCompoundedStakeFromSnapshots(uint256 initialStake, Snapshots memory snapshots)\n internal\n view\n returns (uint256)\n {\n uint256 snapshot_P = snapshots.P;\n uint128 scaleSnapshot = snapshots.scale;\n uint128 epochSnapshot = snapshots.epoch;\n\n // If stake was made before a pool-emptying event, then it has been fully cancelled with debt -- so, return 0\n if (epochSnapshot < currentEpoch) {\n return 0;\n }\n\n uint256 compoundedStake;\n uint128 scaleDiff = currentScale.sub(scaleSnapshot);\n\n /* Compute the compounded stake. If a scale change in P was made during the stake's lifetime,\n * account for it. If more than one scale change was made, then the stake has decreased by a factor of\n * at least 1e-9 -- so return 0.\n */\n if (scaleDiff == 0) {\n compoundedStake = initialStake.mul(P).div(snapshot_P);\n } else if (scaleDiff == 1) {\n compoundedStake = initialStake.mul(P).div(snapshot_P).div(SCALE_FACTOR);\n } else {\n // if scaleDiff >= 2\n compoundedStake = 0;\n }\n\n /*\n * If compounded deposit is less than a billionth of the initial deposit, return 0.\n *\n * NOTE: originally, this line was in place to stop rounding errors making the deposit too large. However, the error\n * corrections should ensure the error in P \"favors the Pool\", i.e. any given compounded deposit should slightly less\n * than it's theoretical value.\n *\n * Thus it's unclear whether this line is still really needed.\n */\n if (compoundedStake < initialStake.div(1e9)) {\n return 0;\n }\n\n return compoundedStake;\n }\n\n // --- Sender functions for ZUSD deposit, ETH gains and SOV gains ---\n\n /// Transfer the ZUSD tokens from the user to the Stability Pool's address, and update its recorded ZUSD\n function _sendZUSDtoStabilityPool(address _address, uint256 _amount) internal {\n zusdToken.sendToPool(_address, address(this), _amount);\n uint256 newTotalZUSDDeposits = totalZUSDDeposits.add(_amount);\n totalZUSDDeposits = newTotalZUSDDeposits;\n emit StabilityPoolZUSDBalanceUpdated(newTotalZUSDDeposits);\n }\n\n function _sendETHGainToDepositor(uint256 _amount) internal {\n _sendETHGainTo(_amount, msg.sender);\n }\n\n function _sendETHGainTo(uint256 _amount, address _receiver) internal {\n require(_receiver != address(0), \"SP::_sendETHGainTo: _receiver is zero address\");\n if (_amount == 0) {\n return;\n }\n uint256 newETH = ETH.sub(_amount);\n ETH = newETH;\n emit StabilityPoolETHBalanceUpdated(newETH);\n emit EtherSent(msg.sender, _amount);\n\n (bool success, ) = msg.sender.call{ value: _amount }(\"\");\n require(success, \"StabilityPool: sending ETH failed\");\n }\n\n /// Send ZUSD to user and decrease ZUSD in Pool\n function _sendZUSDToDepositor(address _depositor, uint256 ZUSDWithdrawal) internal {\n if (ZUSDWithdrawal == 0) {\n return;\n }\n\n zusdToken.returnFromPool(address(this), _depositor, ZUSDWithdrawal);\n _decreaseZUSD(ZUSDWithdrawal);\n }\n\n // --- External Front End functions ---\n\n /// Front end makes a one-time selection of kickback rate upon registering\n function registerFrontEnd(uint256 _kickbackRate) external override {\n _requireFrontEndNotRegistered(msg.sender);\n _requireUserHasNoDeposit(msg.sender);\n _requireValidKickbackRate(_kickbackRate);\n\n frontEnds[msg.sender].kickbackRate = _kickbackRate;\n frontEnds[msg.sender].registered = true;\n\n emit FrontEndRegistered(msg.sender, _kickbackRate);\n }\n\n // --- Stability Pool Deposit Functionality ---\n\n function _setFrontEndTag(address _depositor, address _frontEndTag) internal {\n deposits[_depositor].frontEndTag = _frontEndTag;\n emit FrontEndTagSet(_depositor, _frontEndTag);\n }\n\n function _updateDepositAndSnapshots(address _depositor, uint256 _newValue) internal {\n deposits[_depositor].initialValue = _newValue;\n\n if (_newValue == 0) {\n delete deposits[_depositor].frontEndTag;\n delete depositSnapshots[_depositor];\n emit DepositSnapshotUpdated(_depositor, 0, 0, 0);\n return;\n }\n uint128 currentScaleCached = currentScale;\n uint128 currentEpochCached = currentEpoch;\n uint256 currentP = P;\n\n // Get S and G for the current epoch and current scale\n uint256 currentS = epochToScaleToSum[currentEpochCached][currentScaleCached];\n uint256 currentG = epochToScaleToG[currentEpochCached][currentScaleCached];\n\n // Record new snapshots of the latest running product P, sum S, and sum G, for the depositor\n depositSnapshots[_depositor].P = currentP;\n depositSnapshots[_depositor].S = currentS;\n depositSnapshots[_depositor].G = currentG;\n depositSnapshots[_depositor].scale = currentScaleCached;\n depositSnapshots[_depositor].epoch = currentEpochCached;\n\n emit DepositSnapshotUpdated(_depositor, currentP, currentS, currentG);\n }\n\n function _updateFrontEndStakeAndSnapshots(address _frontEnd, uint256 _newValue) internal {\n frontEndStakes[_frontEnd] = _newValue;\n\n if (_newValue == 0) {\n delete frontEndSnapshots[_frontEnd];\n emit FrontEndSnapshotUpdated(_frontEnd, 0, 0);\n return;\n }\n\n uint128 currentScaleCached = currentScale;\n uint128 currentEpochCached = currentEpoch;\n uint256 currentP = P;\n\n // Get G for the current epoch and current scale\n uint256 currentG = epochToScaleToG[currentEpochCached][currentScaleCached];\n\n // Record new snapshots of the latest running product P and sum G for the front end\n frontEndSnapshots[_frontEnd].P = currentP;\n frontEndSnapshots[_frontEnd].G = currentG;\n frontEndSnapshots[_frontEnd].scale = currentScaleCached;\n frontEndSnapshots[_frontEnd].epoch = currentEpochCached;\n\n emit FrontEndSnapshotUpdated(_frontEnd, currentP, currentG);\n }\n\n function _payOutSOVGains(\n ICommunityIssuance _communityIssuance,\n address _depositor,\n address _frontEnd\n ) internal {\n // Pay out front end's SOV gain\n if (_frontEnd != ADDRESS_ZERO) {\n uint256 frontEndSOVGain = getFrontEndSOVGain(_frontEnd);\n _communityIssuance.sendSOV(_frontEnd, frontEndSOVGain);\n emit SOVPaidToFrontEnd(_frontEnd, frontEndSOVGain);\n }\n\n // Pay out depositor's SOV gain\n uint256 depositorSOVGain = getDepositorSOVGain(_depositor);\n _communityIssuance.sendSOV(_depositor, depositorSOVGain);\n emit SOVPaidToDepositor(_depositor, depositorSOVGain);\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == address(activePool), \"StabilityPool: Caller is not ActivePool\");\n }\n\n function _requireCallerIsTroveManager() internal view {\n require(msg.sender == address(troveManager), \"StabilityPool: Caller is not TroveManager\");\n }\n\n function _requireNoUnderCollateralizedTroves() internal {\n uint256 price = priceFeed.fetchPrice();\n address lowestTrove = sortedTroves.getLast();\n uint256 ICR = troveManager.getCurrentICR(lowestTrove, price);\n require(\n ICR >= liquityBaseParams.MCR(),\n \"StabilityPool: Cannot withdraw while there are troves with ICR < MCR\"\n );\n }\n\n function _requireUserHasDeposit(uint256 _initialDeposit) internal pure {\n require(_initialDeposit > 0, \"StabilityPool: User must have a non-zero deposit\");\n }\n\n function _requireUserHasNoDeposit(address _address) internal view {\n uint256 initialDeposit = deposits[_address].initialValue;\n require(initialDeposit == 0, \"StabilityPool: User must have no deposit\");\n }\n\n function _requireNonZeroAmount(uint256 _amount) internal pure {\n require(_amount > 0, \"StabilityPool: Amount must be non-zero\");\n }\n\n function _requireUserHasTrove(address _depositor) internal view {\n require(\n troveManager.getTroveStatus(_depositor) == 1,\n \"StabilityPool: caller must have an active trove to withdraw ETHGain to\"\n );\n }\n\n function _requireUserHasETHGain(address _depositor) internal view {\n uint256 ETHGain = getDepositorETHGain(_depositor);\n require(ETHGain > 0, \"StabilityPool: caller must have non-zero ETH Gain\");\n }\n\n function _requireFrontEndNotRegistered(address _address) internal view {\n require(\n !frontEnds[_address].registered,\n \"StabilityPool: must not already be a registered front end\"\n );\n }\n\n function _requireFrontEndIsRegisteredOrZero(address _address) internal view {\n require(\n frontEnds[_address].registered || _address == ADDRESS_ZERO,\n \"StabilityPool: Tag must be a registered front end, or the zero address\"\n );\n }\n\n function _requireValidKickbackRate(uint256 _kickbackRate) internal pure {\n require(\n _kickbackRate <= DECIMAL_PRECISION,\n \"StabilityPool: Kickback rate must be in range [0,1]\"\n );\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsActivePool();\n ETH = ETH.add(msg.value);\n StabilityPoolETHBalanceUpdated(ETH);\n }\n}\n" + }, + "contracts/StabilityPoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ICommunityIssuance.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/BaseMath.sol\";\n\ncontract StabilityPoolStorage is Ownable, BaseMath {\n string public constant NAME = \"StabilityPool\";\n\n IBorrowerOperations public borrowerOperations;\n\n ITroveManager public troveManager;\n\n IZUSDToken public zusdToken;\n\n // Needed to check if there are pending liquidations\n ISortedTroves public sortedTroves;\n\n ICommunityIssuance public communityIssuance;\n\n uint256 internal ETH; // deposited ether tracker\n\n // Tracker for ZUSD held in the pool. Changes when users deposit/withdraw, and when Trove debt is offset.\n uint256 internal totalZUSDDeposits;\n\n // --- Data structures ---\n\n struct FrontEnd {\n uint256 kickbackRate;\n bool registered;\n }\n\n struct Deposit {\n uint256 initialValue;\n address frontEndTag;\n }\n\n struct Snapshots {\n uint256 S;\n uint256 P;\n uint256 G;\n uint128 scale;\n uint128 epoch;\n }\n\n mapping(address => Deposit) public deposits; // depositor address -> Deposit struct\n mapping(address => Snapshots) public depositSnapshots; // depositor address -> snapshots struct\n\n mapping(address => FrontEnd) public frontEnds; // front end address -> FrontEnd struct\n mapping(address => uint256) public frontEndStakes; // front end address -> last recorded total deposits, tagged with that front end\n mapping(address => Snapshots) public frontEndSnapshots; // front end address -> snapshots struct\n\n /* Product 'P': Running product by which to multiply an initial deposit, in order to find the current compounded deposit,\n * after a series of liquidations have occurred, each of which cancel some ZUSD debt with the deposit.\n *\n * During its lifetime, a deposit's value evolves from d_t to d_t * P / P_t , where P_t\n * is the snapshot of P taken at the instant the deposit was made. 18-digit decimal.\n */\n uint256 public P;\n\n uint256 public constant SCALE_FACTOR = 1e9;\n\n // Each time the scale of P shifts by SCALE_FACTOR, the scale is incremented by 1\n uint128 public currentScale;\n\n // With each offset that fully empties the Pool, the epoch is incremented by 1\n uint128 public currentEpoch;\n\n /* ETH Gain sum 'S': During its lifetime, each deposit d_t earns an ETH gain of ( d_t * [S - S_t] )/P_t, where S_t\n * is the depositor's snapshot of S taken at the time t when the deposit was made.\n *\n * The 'S' sums are stored in a nested mapping (epoch => scale => sum):\n *\n * - The inner mapping records the sum S at different scales\n * - The outer mapping records the (scale => sum) mappings, for different epochs.\n */\n mapping(uint128 => mapping(uint128 => uint256)) public epochToScaleToSum;\n\n /*\n * Similarly, the sum 'G' is used to calculate SOV gains. During it's lifetime, each deposit d_t earns a SOV gain of\n * ( d_t * [G - G_t] )/P_t, where G_t is the depositor's snapshot of G taken at time t when the deposit was made.\n *\n * SOV reward events occur are triggered by depositor operations (new deposit, topup, withdrawal), and liquidations.\n * In each case, the SOV reward is issued (i.e. G is updated), before other state changes are made.\n */\n mapping(uint128 => mapping(uint128 => uint256)) public epochToScaleToG;\n\n // Error tracker for the error correction in the SOV issuance calculation\n uint256 public lastSOVError;\n // Error trackers for the error correction in the offset calculation\n uint256 public lastETHError_Offset;\n uint256 public lastZUSDLossError_Offset;\n}\n" + }, + "contracts/TestContracts/ActivePoolTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ActivePool.sol\";\n\ncontract ActivePoolTester is ActivePool {\n \n function unprotectedIncreaseZUSDDebt(uint _amount) external {\n ZUSDDebt = ZUSDDebt.add(_amount);\n }\n\n function unprotectedPayable() external payable {\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/TestContracts/BorrowerOperationsTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../BorrowerOperations.sol\";\n\n/* Tester contract inherits from BorrowerOperations, and provides external functions \nfor testing the parent's internal functions. */\ncontract BorrowerOperationsTester is BorrowerOperations {\n\n function getNewICRFromTroveChange\n (\n uint _coll, \n uint _debt, \n uint _collChange, \n bool isCollIncrease, \n uint _debtChange, \n bool isDebtIncrease, \n uint _price\n ) \n external\n pure\n returns (uint)\n {\n return _getNewICRFromTroveChange(_coll, _debt, _collChange, isCollIncrease, _debtChange, isDebtIncrease, _price);\n }\n\n function getNewTCRFromTroveChange\n (\n uint _collChange, \n bool isCollIncrease, \n uint _debtChange, \n bool isDebtIncrease, \n uint _price\n ) \n external \n view\n returns (uint) \n {\n return _getNewTCRFromTroveChange(_collChange, isCollIncrease, _debtChange, isDebtIncrease, _price);\n }\n\n function getUSDValue(uint _coll, uint _price) external pure returns (uint) {\n return _getUSDValue(_coll, _price);\n }\n\n function callInternalAdjustLoan\n (\n address _borrower, \n uint _collWithdrawal, \n uint _debtChange, \n bool _isDebtIncrease, \n address _upperHint,\n address _lowerHint)\n external \n {\n _adjustTrove(_borrower, _collWithdrawal, _debtChange, _isDebtIncrease, _upperHint, _lowerHint, 0);\n }\n\n\n // Payable fallback function\n receive() external payable { }\n}\n" + }, + "contracts/TestContracts/CommunityIssuanceTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/CommunityIssuance.sol\";\n\ncontract CommunityIssuanceTester is CommunityIssuance {\n function obtainSOV(uint _amount) external {\n sovToken.transfer(msg.sender, _amount);\n }\n\n function unprotectedIssueSOV(uint256 _totalZUSDDeposits) external returns (uint) {\n // No checks on caller address\n \n uint256 timePassedSinceLastIssuance = (block.timestamp.sub(lastIssuanceTime));\n uint256 latestTotalSOVIssued = _ZUSDToSOV(_totalZUSDDeposits.mul(APR).div(MAX_BPS).mul(timePassedSinceLastIssuance).div(365 days));\n \n uint256 issuance = latestTotalSOVIssued.sub(totalSOVIssued);\n\n totalSOVIssued = latestTotalSOVIssued;\n lastIssuanceTime = block.timestamp;\n emit TotalSOVIssuedUpdated(latestTotalSOVIssued);\n\n return issuance;\n }\n}\n" + }, + "contracts/TestContracts/DefaultPoolTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../DefaultPool.sol\";\n\ncontract DefaultPoolTester is DefaultPool {\n \n function unprotectedIncreaseZUSDDebt(uint _amount) external {\n ZUSDDebt = ZUSDDebt.add(_amount);\n }\n\n function unprotectedPayable() external payable {\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/TestContracts/EchidnaProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../TroveManager.sol\";\nimport \"../BorrowerOperations.sol\";\nimport \"../StabilityPool.sol\";\nimport \"../ZUSDToken.sol\";\n\ncontract EchidnaProxy {\n TroveManager troveManager;\n BorrowerOperations borrowerOperations;\n StabilityPool stabilityPool;\n ZUSDToken zusdToken;\n\n constructor(\n TroveManager _troveManager,\n BorrowerOperations _borrowerOperations,\n StabilityPool _stabilityPool,\n ZUSDToken _zusdToken\n ) public {\n troveManager = _troveManager;\n borrowerOperations = _borrowerOperations;\n stabilityPool = _stabilityPool;\n zusdToken = _zusdToken;\n }\n\n receive() external payable {\n // do nothing\n }\n\n // TroveManager\n\n function liquidatePrx(address _user) external {\n troveManager.liquidate(_user);\n }\n\n function liquidateTrovesPrx(uint _n) external {\n troveManager.liquidateTroves(_n);\n }\n\n function batchLiquidateTrovesPrx(address[] calldata _troveArray) external {\n troveManager.batchLiquidateTroves(_troveArray);\n }\n\n function redeemCollateralPrx(\n uint _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint _partialRedemptionHintNICR,\n uint _maxIterations,\n uint _maxFee\n ) external {\n troveManager.redeemCollateral(_ZUSDAmount, _firstRedemptionHint, _upperPartialRedemptionHint, _lowerPartialRedemptionHint, _partialRedemptionHintNICR, _maxIterations, _maxFee);\n }\n\n // Borrower Operations\n function openTrovePrx(uint _ETH, uint _ZUSDAmount, address _upperHint, address _lowerHint, uint _maxFee) external payable {\n borrowerOperations.openTrove{value: _ETH}(_maxFee, _ZUSDAmount, _upperHint, _lowerHint);\n }\n\n function addCollPrx(uint _ETH, address _upperHint, address _lowerHint) external payable {\n borrowerOperations.addColl{value: _ETH}(_upperHint, _lowerHint);\n }\n\n function withdrawCollPrx(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.withdrawColl(_amount, _upperHint, _lowerHint);\n }\n\n function withdrawZUSDPrx(uint _amount, address _upperHint, address _lowerHint, uint _maxFee) external {\n borrowerOperations.withdrawZUSD(_maxFee, _amount, _upperHint, _lowerHint);\n }\n\n function repayZUSDPrx(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.repayZUSD(_amount, _upperHint, _lowerHint);\n }\n\n function closeTrovePrx() external {\n borrowerOperations.closeTrove();\n }\n\n function adjustTrovePrx(uint _ETH, uint _collWithdrawal, uint _debtChange, bool _isDebtIncrease, address _upperHint, address _lowerHint, uint _maxFee) external payable {\n borrowerOperations.adjustTrove{value: _ETH}(_maxFee, _collWithdrawal, _debtChange, _isDebtIncrease, _upperHint, _lowerHint);\n }\n\n // Pool Manager\n function provideToSPPrx(uint _amount, address _frontEndTag) external {\n stabilityPool.provideToSP(_amount, _frontEndTag);\n }\n\n function withdrawFromSPPrx(uint _amount) external {\n stabilityPool.withdrawFromSP(_amount);\n }\n\n // ZUSD Token\n\n function transferPrx(address recipient, uint256 amount) external returns (bool) {\n return zusdToken.transfer(recipient, amount);\n }\n\n function approvePrx(address spender, uint256 amount) external returns (bool) {\n return zusdToken.approve(spender, amount);\n }\n\n function transferFromPrx(address sender, address recipient, uint256 amount) external returns (bool) {\n return zusdToken.transferFrom(sender, recipient, amount);\n }\n\n function increaseAllowancePrx(address spender, uint256 addedValue) external returns (bool) {\n return zusdToken.increaseAllowance(spender, addedValue);\n }\n\n function decreaseAllowancePrx(address spender, uint256 subtractedValue) external returns (bool) {\n return zusdToken.decreaseAllowance(spender, subtractedValue);\n }\n}\n" + }, + "contracts/TestContracts/EchidnaTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../LiquityBaseParams.sol\";\nimport \"../Interfaces/ITroveManager.sol\";\nimport \"../TroveManager.sol\";\nimport \"../TroveManagerStorage.sol\";\nimport \"../Dependencies/TroveManagerRedeemOps.sol\";\nimport \"../BorrowerOperations.sol\";\nimport \"../ActivePool.sol\";\nimport \"../DefaultPool.sol\";\nimport \"../StabilityPool.sol\";\nimport \"../GasPool.sol\";\nimport \"../CollSurplusPool.sol\";\nimport \"../ZUSDToken.sol\";\nimport \"./PriceFeedTestnet.sol\";\nimport \"../SortedTroves.sol\";\nimport \"./EchidnaProxy.sol\";\n\n//import \"../Dependencies/console.sol\";\n\n// Run with:\n// rm -f fuzzTests/corpus/* # (optional)\n// ~/.local/bin/echidna-test contracts/TestContracts/EchidnaTester.sol --contract EchidnaTester --config fuzzTests/echidna_config.yaml\n\ncontract EchidnaTester {\n using SafeMath for uint;\n\n uint private constant NUMBER_OF_ACTORS = 100;\n uint private constant INITIAL_BALANCE = 1e24;\n uint private MCR;\n uint private CCR;\n uint private ZUSD_GAS_COMPENSATION;\n\n LiquityBaseParams public liquityBaseParams;\n TroveManagerRedeemOps public troveManagerRedeemOps;\n TroveManager public troveManager;\n BorrowerOperations public borrowerOperations;\n ActivePool public activePool;\n DefaultPool public defaultPool;\n StabilityPool public stabilityPool;\n GasPool public gasPool;\n CollSurplusPool public collSurplusPool;\n ZUSDToken public zusdToken;\n PriceFeedTestnet priceFeedTestnet;\n SortedTroves sortedTroves;\n\n EchidnaProxy[NUMBER_OF_ACTORS] public echidnaProxies;\n\n uint private numberOfTroves;\n\n constructor() public payable {\n liquityBaseParams = new LiquityBaseParams();\n troveManagerRedeemOps = new TroveManagerRedeemOps(14 * 86400);\n troveManager = new TroveManager(14 days);\n borrowerOperations = new BorrowerOperations();\n activePool = new ActivePool();\n defaultPool = new DefaultPool();\n stabilityPool = new StabilityPool();\n gasPool = new GasPool();\n zusdToken = new ZUSDToken();\n zusdToken.initialize(\n address(troveManager),\n address(stabilityPool),\n address(borrowerOperations)\n );\n\n collSurplusPool = new CollSurplusPool();\n priceFeedTestnet = new PriceFeedTestnet();\n\n sortedTroves = new SortedTroves();\n\n troveManager.setAddresses(\n ITroveManager.TroveManagerInitAddressesParams(\n address(0),\n address(troveManagerRedeemOps),\n address(liquityBaseParams),\n address(borrowerOperations),\n address(activePool),\n address(defaultPool),\n address(stabilityPool),\n address(gasPool),\n address(collSurplusPool),\n address(priceFeedTestnet),\n address(zusdToken),\n address(sortedTroves),\n address(0),\n address(0)\n )\n );\n\n borrowerOperations.setAddresses(\n address(0),\n address(liquityBaseParams),\n address(troveManager),\n address(activePool),\n address(defaultPool),\n address(stabilityPool),\n address(gasPool),\n address(collSurplusPool),\n address(priceFeedTestnet),\n address(sortedTroves),\n address(zusdToken),\n address(0)\n );\n\n activePool.setAddresses(\n address(borrowerOperations),\n address(troveManager),\n address(stabilityPool),\n address(defaultPool)\n );\n\n defaultPool.setAddresses(address(troveManager), address(activePool));\n\n stabilityPool.setAddresses(\n address(liquityBaseParams),\n address(borrowerOperations),\n address(troveManager),\n address(activePool),\n address(zusdToken),\n address(sortedTroves),\n address(priceFeedTestnet),\n address(0)\n );\n\n collSurplusPool.setAddresses(\n address(borrowerOperations),\n address(troveManager),\n address(activePool)\n );\n\n sortedTroves.setParams(1e18, address(troveManager), address(borrowerOperations));\n\n for (uint i = 0; i < NUMBER_OF_ACTORS; i++) {\n echidnaProxies[i] = new EchidnaProxy(\n troveManager,\n borrowerOperations,\n stabilityPool,\n zusdToken\n );\n (bool success, ) = address(echidnaProxies[i]).call{ value: INITIAL_BALANCE }(\"\");\n require(success);\n }\n\n MCR = borrowerOperations.liquityBaseParams().MCR();\n CCR = borrowerOperations.liquityBaseParams().CCR();\n ZUSD_GAS_COMPENSATION = borrowerOperations.ZUSD_GAS_COMPENSATION();\n require(MCR > 0);\n require(CCR > 0);\n\n // TODO:\n priceFeedTestnet.setPrice(1e22);\n }\n\n // TroveManager\n\n function liquidateExt(uint _i, address _user) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].liquidatePrx(_user);\n }\n\n function liquidateTrovesExt(uint _i, uint _n) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].liquidateTrovesPrx(_n);\n }\n\n function batchLiquidateTrovesExt(uint _i, address[] calldata _troveArray) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].batchLiquidateTrovesPrx(_troveArray);\n }\n\n function redeemCollateralExt(\n uint _i,\n uint _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint _partialRedemptionHintNICR\n ) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].redeemCollateralPrx(\n _ZUSDAmount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n 0,\n 0\n );\n }\n\n // Borrower Operations\n\n function getAdjustedETH(\n uint actorBalance,\n uint _ETH,\n uint ratio\n ) internal view returns (uint) {\n uint price = priceFeedTestnet.getPrice();\n require(price > 0);\n uint minETH = ratio.mul(ZUSD_GAS_COMPENSATION).div(price);\n require(actorBalance > minETH);\n uint ETH = minETH + (_ETH % (actorBalance - minETH));\n return ETH;\n }\n\n function getAdjustedZUSD(uint ETH, uint _ZUSDAmount, uint ratio) internal view returns (uint) {\n uint price = priceFeedTestnet.getPrice();\n uint ZUSDAmount = _ZUSDAmount;\n uint compositeDebt = ZUSDAmount.add(ZUSD_GAS_COMPENSATION);\n uint ICR = LiquityMath._computeCR(ETH, compositeDebt, price);\n if (ICR < ratio) {\n compositeDebt = ETH.mul(price).div(ratio);\n ZUSDAmount = compositeDebt.sub(ZUSD_GAS_COMPENSATION);\n }\n return ZUSDAmount;\n }\n\n function openTroveExt(uint _i, uint _ETH, uint _ZUSDAmount) public payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n EchidnaProxy echidnaProxy = echidnaProxies[actor];\n uint actorBalance = address(echidnaProxy).balance;\n\n // we pass in CCR instead of MCR in case it’s the first one\n uint ETH = getAdjustedETH(actorBalance, _ETH, CCR);\n uint ZUSDAmount = getAdjustedZUSD(ETH, _ZUSDAmount, CCR);\n\n echidnaProxy.openTrovePrx(ETH, ZUSDAmount, address(0), address(0), 0);\n\n numberOfTroves = troveManager.getTroveOwnersCount();\n assert(numberOfTroves > 0);\n // canary\n //assert(numberOfTroves == 0);\n }\n\n function openTroveRawExt(\n uint _i,\n uint _ETH,\n uint _ZUSDAmount,\n address _upperHint,\n address _lowerHint,\n uint _maxFee\n ) public payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].openTrovePrx(_ETH, _ZUSDAmount, _upperHint, _lowerHint, _maxFee);\n }\n\n function addCollExt(uint _i, uint _ETH) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n EchidnaProxy echidnaProxy = echidnaProxies[actor];\n uint actorBalance = address(echidnaProxy).balance;\n\n uint ETH = getAdjustedETH(actorBalance, _ETH, MCR);\n\n echidnaProxy.addCollPrx(ETH, address(0), address(0));\n }\n\n function addCollRawExt(\n uint _i,\n uint _ETH,\n address _upperHint,\n address _lowerHint\n ) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].addCollPrx(_ETH, _upperHint, _lowerHint);\n }\n\n function withdrawCollExt(\n uint _i,\n uint _amount,\n address _upperHint,\n address _lowerHint\n ) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].withdrawCollPrx(_amount, _upperHint, _lowerHint);\n }\n\n function withdrawZUSDExt(\n uint _i,\n uint _amount,\n address _upperHint,\n address _lowerHint,\n uint _maxFee\n ) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].withdrawZUSDPrx(_amount, _upperHint, _lowerHint, _maxFee);\n }\n\n function repayZUSDExt(uint _i, uint _amount, address _upperHint, address _lowerHint) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].repayZUSDPrx(_amount, _upperHint, _lowerHint);\n }\n\n function closeTroveExt(uint _i) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].closeTrovePrx();\n }\n\n function adjustTroveExt(\n uint _i,\n uint _ETH,\n uint _collWithdrawal,\n uint _debtChange,\n bool _isDebtIncrease\n ) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n EchidnaProxy echidnaProxy = echidnaProxies[actor];\n uint actorBalance = address(echidnaProxy).balance;\n\n uint ETH = getAdjustedETH(actorBalance, _ETH, MCR);\n uint debtChange = _debtChange;\n if (_isDebtIncrease) {\n // TODO: add current amount already withdrawn:\n debtChange = getAdjustedZUSD(ETH, uint(_debtChange), MCR);\n }\n // TODO: collWithdrawal, debtChange\n echidnaProxy.adjustTrovePrx(\n ETH,\n _collWithdrawal,\n debtChange,\n _isDebtIncrease,\n address(0),\n address(0),\n 0\n );\n }\n\n function adjustTroveRawExt(\n uint _i,\n uint _ETH,\n uint _collWithdrawal,\n uint _debtChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n uint _maxFee\n ) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].adjustTrovePrx(\n _ETH,\n _collWithdrawal,\n _debtChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFee\n );\n }\n\n // Pool Manager\n\n function provideToSPExt(uint _i, uint _amount, address _frontEndTag) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].provideToSPPrx(_amount, _frontEndTag);\n }\n\n function withdrawFromSPExt(uint _i, uint _amount) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].withdrawFromSPPrx(_amount);\n }\n\n // ZUSD Token\n\n function transferExt(uint _i, address recipient, uint256 amount) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].transferPrx(recipient, amount);\n }\n\n function approveExt(uint _i, address spender, uint256 amount) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].approvePrx(spender, amount);\n }\n\n function transferFromExt(\n uint _i,\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].transferFromPrx(sender, recipient, amount);\n }\n\n function increaseAllowanceExt(\n uint _i,\n address spender,\n uint256 addedValue\n ) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].increaseAllowancePrx(spender, addedValue);\n }\n\n function decreaseAllowanceExt(\n uint _i,\n address spender,\n uint256 subtractedValue\n ) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].decreaseAllowancePrx(spender, subtractedValue);\n }\n\n // PriceFeed\n\n function setPriceExt(uint256 _price) external {\n bool result = priceFeedTestnet.setPrice(_price);\n assert(result);\n }\n\n // --------------------------\n // Invariants and properties\n // --------------------------\n\n function echidna_canary_number_of_troves() public view returns (bool) {\n if (numberOfTroves > 20) {\n return false;\n }\n\n return true;\n }\n\n function echidna_canary_active_pool_balance() public view returns (bool) {\n if (address(activePool).balance > 0) {\n return false;\n }\n return true;\n }\n\n function echidna_troves_order() external view returns (bool) {\n address currentTrove = sortedTroves.getFirst();\n address nextTrove = sortedTroves.getNext(currentTrove);\n\n while (currentTrove != address(0) && nextTrove != address(0)) {\n if (troveManager.getNominalICR(nextTrove) > troveManager.getNominalICR(currentTrove)) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n currentTrove = nextTrove;\n nextTrove = sortedTroves.getNext(currentTrove);\n }\n\n return true;\n }\n\n /**\n * Status\n * Minimum debt (gas compensation)\n * Stake > 0\n */\n function echidna_trove_properties() public view returns (bool) {\n address currentTrove = sortedTroves.getFirst();\n while (currentTrove != address(0)) {\n // Status\n if (\n TroveManagerStorage.Status(troveManager.getTroveStatus(currentTrove)) !=\n TroveManagerStorage.Status.active\n ) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n // Minimum debt (gas compensation)\n if (troveManager.getTroveDebt(currentTrove) < ZUSD_GAS_COMPENSATION) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n // Stake > 0\n if (troveManager.getTroveStake(currentTrove) == 0) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n currentTrove = sortedTroves.getNext(currentTrove);\n }\n return true;\n }\n\n function echidna_ETH_balances() public view returns (bool) {\n if (address(troveManager).balance > 0) {\n return false;\n }\n\n if (address(borrowerOperations).balance > 0) {\n return false;\n }\n\n if (address(activePool).balance != activePool.getETH()) {\n return false;\n }\n\n if (address(defaultPool).balance != defaultPool.getETH()) {\n return false;\n }\n\n if (address(stabilityPool).balance != stabilityPool.getETH()) {\n return false;\n }\n\n if (address(zusdToken).balance > 0) {\n return false;\n }\n\n if (address(priceFeedTestnet).balance > 0) {\n return false;\n }\n\n if (address(sortedTroves).balance > 0) {\n return false;\n }\n\n return true;\n }\n\n // TODO: What should we do with this? Should it be allowed? Should it be a canary?\n function echidna_price() public view returns (bool) {\n uint price = priceFeedTestnet.getPrice();\n\n if (price == 0) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n return true;\n }\n\n // Total ZUSD matches\n function echidna_ZUSD_global_balances() public view returns (bool) {\n uint totalSupply = zusdToken.totalSupply();\n uint gasPoolBalance = zusdToken.balanceOf(address(gasPool));\n\n uint activePoolBalance = activePool.getZUSDDebt();\n uint defaultPoolBalance = defaultPool.getZUSDDebt();\n if (totalSupply != activePoolBalance + defaultPoolBalance) {\n return false;\n }\n\n uint stabilityPoolBalance = stabilityPool.getTotalZUSDDeposits();\n address currentTrove = sortedTroves.getFirst();\n uint trovesBalance;\n while (currentTrove != address(0)) {\n trovesBalance += zusdToken.balanceOf(address(currentTrove));\n currentTrove = sortedTroves.getNext(currentTrove);\n }\n // we cannot state equality because tranfers are made to external addresses too\n if (totalSupply <= stabilityPoolBalance + trovesBalance + gasPoolBalance) {\n return false;\n }\n\n return true;\n }\n\n /*\n function echidna_test() public view returns(bool) {\n return true;\n }\n */\n}\n" + }, + "contracts/TestContracts/ExternalPriceFeedTester.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Dependencies/PriceFeed/IExternalPriceFeed.sol\";\n\ninterface IMoCBaseOracle {\n function peek() external view returns (bytes32, bool);\n}\n\ncontract ExternalPriceFeedTester is IExternalPriceFeed {\n uint256 price;\n bool success;\n\n function setLatestAnswer(uint256 _price, bool _success) external {\n price = _price;\n success = _success;\n }\n\n function latestAnswer() external view override returns (uint256, bool) {\n return (price, success);\n }\n}\n" + }, + "contracts/TestContracts/FunctionCaller.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/ITroveManager.sol\";\nimport \"../Interfaces/ISortedTroves.sol\";\nimport \"../Interfaces/IPriceFeed.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\n\n/* Wrapper contract - used for calculating gas of read-only and internal functions. \nNot part of the Zero application. */\ncontract FunctionCaller {\n ITroveManager troveManager;\n address public troveManagerAddress;\n\n ISortedTroves sortedTroves;\n address public sortedTrovesAddress;\n\n IPriceFeed priceFeed;\n address public priceFeedAddress;\n\n // --- Dependency setters ---\n\n function setTroveManagerAddress(address _troveManagerAddress) external {\n troveManagerAddress = _troveManagerAddress;\n troveManager = ITroveManager(_troveManagerAddress);\n }\n\n function setSortedTrovesAddress(address _sortedTrovesAddress) external {\n troveManagerAddress = _sortedTrovesAddress;\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n }\n\n function setPriceFeedAddress(address _priceFeedAddress) external {\n priceFeedAddress = _priceFeedAddress;\n priceFeed = IPriceFeed(_priceFeedAddress);\n }\n\n // --- Non-view wrapper functions used for calculating gas ---\n\n function troveManager_getCurrentICR(address _address, uint256 _price)\n external\n returns (uint256)\n {\n return troveManager.getCurrentICR(_address, _price);\n }\n\n function sortedTroves_findInsertPosition(\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external returns (address, address) {\n return sortedTroves.findInsertPosition(_NICR, _prevId, _nextId);\n }\n}\n" + }, + "contracts/TestContracts/LiquityMathTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/LiquityMath.sol\";\n\n/* Tester contract for math functions in Math.sol library. */\n\ncontract LiquityMathTester {\n\n function callMax(uint _a, uint _b) external pure returns (uint) {\n return LiquityMath._max(_a, _b);\n }\n\n // Non-view wrapper for gas test\n function callDecPowTx(uint _base, uint _n) external returns (uint) {\n return LiquityMath._decPow(_base, _n);\n }\n\n // External wrapper\n function callDecPow(uint _base, uint _n) external pure returns (uint) {\n return LiquityMath._decPow(_base, _n);\n }\n}\n" + }, + "contracts/TestContracts/LiquitySafeMath128Tester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/LiquitySafeMath128.sol\";\n\n/* Tester contract for math functions in LiquitySafeMath128.sol library. */\n\ncontract LiquitySafeMath128Tester {\n using LiquitySafeMath128 for uint128;\n\n function add(uint128 a, uint128 b) external pure returns (uint128) {\n return a.add(b);\n }\n\n function sub(uint128 a, uint128 b) external pure returns (uint128) {\n return a.sub(b);\n }\n}\n" + }, + "contracts/TestContracts/MassetManagerTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { ERC20Permit } from \"@openzeppelin/contracts/drafts/ERC20Permit.sol\";\nimport \"../BorrowerOperationsStorage.sol\";\nimport \"hardhat/console.sol\";\n\n//TODO: rename NueMockToken to contract DLLRMockToken is ERC20(\"Sovryn Dollar\", \"DLLR\")\ncontract NueMockToken is ERC20(\"Nuestro\", \"NUE\"), ERC20Permit(\"Nuestro\"), Ownable {\n constructor() public {}\n\n function mint(address _account, uint256 _amount) public onlyOwner {\n _mint(_account, _amount);\n }\n\n function burn(address _account, uint256 _amount) public onlyOwner {\n _burn(_account, _amount);\n }\n\n function getChainId() external pure returns (uint256 chainID) {\n //return _chainID(); // it’s private\n assembly {\n chainID := chainid()\n }\n }\n\n function transferWithPermit(\n address _from,\n address _to,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external {\n permit(_from, msg.sender, _amount, _deadline, _v, _r, _s);\n transferFrom(_from, _to, _amount);\n }\n\n //TODO: add EIP-2612 Permit functionality\n}\n\ncontract MassetManagerTester is IMassetManager {\n NueMockToken public nueMockToken;\n\n constructor() public {\n nueMockToken = new NueMockToken();\n }\n\n function mintTo(\n address _bAsset,\n uint256 _bAssetQuantity,\n address _recipient\n ) external override returns (uint256) {\n IERC20(_bAsset).transferFrom(msg.sender, address(this), _bAssetQuantity);\n uint256 nueBalanceOfRecipientBeforeMint = nueMockToken.balanceOf(_recipient);\n nueMockToken.mint(_recipient, _bAssetQuantity);\n return nueMockToken.balanceOf(_recipient) - nueBalanceOfRecipientBeforeMint;\n }\n\n function getToken() external view override returns (address) {\n return address(nueMockToken);\n }\n\n /// @dev Transfer 'bAsset' to the recipient then burn the 'aggregator' nueMockToken\n function redeemTo(\n address _bAsset, //ZUSD nueMockToken\n uint256 _massetQuantity,\n address _recipient //user\n ) external override returns (uint256 massetRedeemed) {\n ERC20(_bAsset).transfer(_recipient, _massetQuantity);\n // nueMockToken.burn(_recipient, _massetQuantity); // _recipient used to be for the previous bridge-like implementation\n nueMockToken.burn(msg.sender, _massetQuantity);\n\n return _massetQuantity;\n }\n}\n" + }, + "contracts/TestContracts/MockFeeSharingCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/ZEROToken.sol\";\n\ninterface MockIFeeSharingCollector {\n\tfunction transferTokens(address _token, uint96 _amount) external;\n}\n\n/// @dev Simple contract that will receive ZERO tokens issued to the SOV stakers.\ncontract MockFeeSharingCollector is MockIFeeSharingCollector {\n\tfunction transferTokens(address _token, uint96 _amount) override external {\n\t\t/// Just a fake function to receive the tokens\n\t\tZEROToken(_token).transferFrom(msg.sender, address(this), _amount);\n\t}\n\n\tfunction transferRBTC() external payable {}\n}\n" + }, + "contracts/TestContracts/PriceFeedSovryn.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IPriceFeedSovryn.sol\";\nimport \"../Dependencies/SafeMath.sol\";\n\n/*\n* PriceFeed placeholder for testnet and development. The price is simply set manually and saved in a state \n* variable. The contract does not connect to a live Chainlink price feed. \n*/\ncontract PriceFeedSovryn {\n using SafeMath for uint256;\n\n mapping(address => mapping(address => uint256)) public prices;\n\n // --- Functions ---\n // Manual external price setter.\n function setPrice(address sourceToken, address destToken, uint256 price) external {\n prices[sourceToken][destToken] = price;\n }\n\n function queryRate(address sourceToken, address destToken) public view returns(uint256 rate, uint256 precision) {\n return (prices[sourceToken][destToken], 1e18);\n }\n\n function queryReturn(\n address sourceToken,\n address destToken,\n uint256 sourceAmount\n ) public view returns (uint256 destAmount) {\n (uint256 rate, uint256 precision) = queryRate(sourceToken, destToken);\n return sourceAmount.mul(rate).div(precision);\n }\n}\n" + }, + "contracts/TestContracts/PriceFeedTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../PriceFeed.sol\";\n\ncontract PriceFeedTester is PriceFeed {\n function setLastGoodPrice(uint256 _lastGoodPrice) external {\n lastGoodPrice = _lastGoodPrice;\n }\n}\n" + }, + "contracts/TestContracts/PriceFeedTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IPriceFeed.sol\";\n\n/*\n* PriceFeed placeholder for testnet and development. The price is simply set manually and saved in a state \n* variable. The contract does not connect to a live Chainlink price feed. \n*/\ncontract PriceFeedTestnet is IPriceFeed {\n \n uint256 private _price = 200 * 1e18;\n\n // --- Functions ---\n\n // View price getter for simplicity in tests\n function getPrice() external view returns (uint256) {\n return _price;\n }\n\n function fetchPrice() external override returns (uint256) {\n // Fire an event just like the mainnet version would.\n // This lets the subgraph rely on events to get the latest price even when developing locally.\n emit LastGoodPriceUpdated(_price);\n return _price;\n }\n\n // Manual external price setter.\n function setPrice(uint256 price) external returns (bool) {\n _price = price;\n return true;\n }\n}\n" + }, + "contracts/TestContracts/SortedTrovesTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/ISortedTroves.sol\";\n\n\ncontract SortedTrovesTester {\n ISortedTroves sortedTroves;\n\n function setSortedTroves(address _sortedTrovesAddress) external {\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n }\n\n function insert(address _id, uint256 _NICR, address _prevId, address _nextId) external {\n sortedTroves.insert(_id, _NICR, _prevId, _nextId);\n }\n\n function remove(address _id) external {\n sortedTroves.remove(_id);\n }\n\n function reInsert(address _id, uint256 _newNICR, address _prevId, address _nextId) external {\n sortedTroves.reInsert(_id, _newNICR, _prevId, _nextId);\n }\n\n function getNominalICR(address) external pure returns (uint) {\n return 1;\n }\n\n function getCurrentICR(address, uint) external pure returns (uint) {\n return 1;\n }\n}\n" + }, + "contracts/TestContracts/StabilityPoolTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../StabilityPool.sol\";\n\ncontract StabilityPoolTester is StabilityPool {\n \n function unprotectedPayable() external payable {\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/TestContracts/TroveManagerTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../TroveManager.sol\";\n\n/* Tester contract inherits from TroveManager, and provides external functions \nfor testing the parent's internal functions. */\n\ncontract TroveManagerTester is TroveManager(14 days) {\n function computeICR(uint _coll, uint _debt, uint _price) external pure returns (uint) {\n return LiquityMath._computeCR(_coll, _debt, _price);\n }\n\n function getCollGasCompensation(uint _coll) external view returns (uint) {\n return _getCollGasCompensation(_coll);\n }\n\n function getZUSDGasCompensation() external pure returns (uint) {\n return ZUSD_GAS_COMPENSATION;\n }\n\n function getCompositeDebt(uint _debt) external pure returns (uint) {\n return _getCompositeDebt(_debt);\n }\n\n function unprotectedDecayBaseRateFromBorrowing() external returns (uint) {\n baseRate = _calcDecayedBaseRate();\n assert(baseRate >= 0 && baseRate <= DECIMAL_PRECISION);\n\n _updateLastFeeOpTime();\n return baseRate;\n }\n\n function minutesPassedSinceLastFeeOp() external view returns (uint) {\n return _minutesPassedSinceLastFeeOp();\n }\n\n function setLastFeeOpTimeToNow() external {\n lastFeeOperationTime = block.timestamp;\n }\n\n function setBaseRate(uint _baseRate) external {\n baseRate = _baseRate;\n }\n\n function callGetRedemptionFee(uint _ETHDrawn) external view returns (uint) {\n _getRedemptionFee(_ETHDrawn);\n }\n\n function getActualDebtFromComposite(uint _debtVal) external pure returns (uint) {\n return _getNetDebt(_debtVal);\n }\n\n function callInternalRemoveTroveOwner(address _troveOwner) external {\n uint troveOwnersArrayLength = TroveOwners.length;\n _removeTroveOwner(_troveOwner, troveOwnersArrayLength);\n }\n}\n" + }, + "contracts/TestContracts/UpgradableProxyTester.sol": { + "content": "\n// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Proxy/UpgradableProxy.sol\";\ncontract Storage {\n uint someVar;\n}\n\ncontract ProxiableContract is Storage {\n\n function getSomeVar() public view returns (uint) {\n return someVar;\n }\n\n function setSomeVar(uint value) public {\n someVar = value;\n }\n}\n\ncontract Storage2 {\n uint anotherVar;\n}\n\ncontract ProxiableContract2 is ProxiableContract, Storage2 {\n\n function getAnotherVar() public view returns (uint) {\n return anotherVar;\n }\n\n function setAnotherVar(uint value) public {\n anotherVar = value;\n }\n\n function mulVars() public view returns (uint) {\n return someVar * anotherVar;\n }\n}\n\ncontract UpgradableProxyTester is UpgradableProxy, Storage {}\n" + }, + "contracts/TestContracts/ZEROStakingTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/ZEROStaking.sol\";\n\n\ncontract ZEROStakingTester is ZEROStaking {\n function requireCallerIsFeeDistributor() external view {\n _requireCallerIsFeeDistributor();\n }\n}\n" + }, + "contracts/TestContracts/ZEROTokenTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/ZEROToken.sol\";\n\ncontract ZEROTokenTester is ZEROToken {\n constructor\n (\n address _zeroStakingAddress,\n address _marketMakerAddress,\n address _presaleAddress\n ) \n public \n {\n initialize(\n _zeroStakingAddress,\n _marketMakerAddress,\n _presaleAddress\n );\n } \n\n function unprotectedMint(address account, uint256 amount) external {\n // No check for the caller here\n\n _mint(account, amount);\n }\n\n function unprotectedSendToZEROStaking(address _sender, uint256 _amount) external {\n // No check for the caller here\n \n _transfer(_sender, zeroStakingAddress, _amount);\n }\n\n function callInternalApprove(address owner, address spender, uint256 amount) external returns (bool) {\n _approve(owner, spender, amount);\n }\n\n function callInternalTransfer(address sender, address recipient, uint256 amount) external returns (bool) {\n _transfer(sender, recipient, amount);\n }\n\n function getChainId() external pure returns (uint256 chainID) {\n //return _chainID(); // it’s private\n assembly {\n chainID := chainid()\n }\n }\n}" + }, + "contracts/TestContracts/ZUSDTokenCaller.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IZUSDToken.sol\";\n\ncontract ZUSDTokenCaller {\n IZUSDToken ZUSD;\n\n function setZUSD(IZUSDToken _ZUSD) external {\n ZUSD = _ZUSD;\n }\n\n function zusdMint(address _account, uint _amount) external {\n ZUSD.mint(_account, _amount);\n }\n\n function zusdBurn(address _account, uint _amount) external {\n ZUSD.burn(_account, _amount);\n }\n\n function zusdSendToPool(address _sender, address _poolAddress, uint256 _amount) external {\n ZUSD.sendToPool(_sender, _poolAddress, _amount);\n }\n\n function zusdReturnFromPool(address _poolAddress, address _receiver, uint256 _amount ) external {\n ZUSD.returnFromPool(_poolAddress, _receiver, _amount);\n }\n}\n" + }, + "contracts/TestContracts/ZUSDTokenTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZUSDToken.sol\";\n\ncontract ZUSDTokenTester is ZUSDToken {\n \n constructor( \n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) public {\n initialize(_troveManagerAddress, _stabilityPoolAddress, _borrowerOperationsAddress);\n }\n \n function unprotectedMint(address _account, uint256 _amount) external {\n // No check on caller here\n\n _mint(_account, _amount);\n }\n\n function unprotectedBurn(address _account, uint _amount) external {\n // No check on caller here\n \n _burn(_account, _amount);\n }\n\n function unprotectedSendToPool(address _sender, address _poolAddress, uint256 _amount) external {\n // No check on caller here\n\n _transfer(_sender, _poolAddress, _amount);\n }\n\n function unprotectedReturnFromPool(address _poolAddress, address _receiver, uint256 _amount ) external {\n // No check on caller here\n\n _transfer(_poolAddress, _receiver, _amount);\n }\n\n function callInternalApprove(address owner, address spender, uint256 amount) external returns (bool) {\n _approve(owner, spender, amount);\n }\n\n function getChainId() external pure returns (uint256 chainID) {\n //return _chainID(); // it’s private\n assembly {\n chainID := chainid()\n }\n }\n\n function getDigest(address owner, address spender, uint amount, uint nonce, uint deadline) external view returns (bytes32) {\n return keccak256(abi.encodePacked(\n uint16(0x1901),\n domainSeparator(),\n keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, amount, nonce, deadline))\n )\n );\n }\n\n function recoverAddress(bytes32 digest, uint8 v, bytes32 r, bytes32 s) external pure returns (address) {\n return ecrecover(digest, v, r, s);\n }\n}\n" + }, + "contracts/TestContracts/ZUSDTokenTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IZUSDToken.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/console.sol\";\nimport \"../ZUSDToken.sol\";\n\n/**\n *\n * Based upon OpenZeppelin's ERC20 contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol\n *\n * and their EIP2612 (ERC20Permit / ERC712) functionality:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\n *\n *\n * --- Functionality added specific to the ZUSDToken ---\n *\n * 1) Transfer protection: blacklist of addresses that are invalid recipients (i.e. core Zero contracts) in external\n * transfer() and transferFrom() calls. The purpose is to protect users from losing tokens by mistakenly sending ZUSD directly to a Zero\n * core contract, when they should rather call the right function.\n *\n * 2) sendToPool() and returnFromPool(): functions callable only Zero core contracts, which move ZUSD tokens between Zero <-> user.\n */\n\n/// @dev ZUSDTokenTestnet has unptotected initialize function to bypass initializer() modifier validation\n/// @notice use if need to redeploy the token logic AND run initialize() again on the proxy\ncontract ZUSDTokenTestnet is ZUSDToken {\n function initialize(\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) public override onlyOwner {\n _initialize(_troveManagerAddress, _stabilityPoolAddress, _borrowerOperationsAddress);\n }\n}\n" + }, + "contracts/TroveManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROToken.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./Dependencies/TroveManagerBase.sol\";\nimport \"./TroveManagerStorage.sol\";\n\ncontract TroveManager is TroveManagerBase, CheckContract, ITroveManager {\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerRedeemOpsAddressChanged(address _troveManagerRedeemOps);\n event LiquityBaseParamsAddressChanges(address _borrowerOperationsAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZEROTokenAddressChanged(address _zeroTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n\n ///@param _bootstrapPeriod During bootsrap period redemptions are not allowed\n constructor(uint256 _bootstrapPeriod) public TroveManagerBase(_bootstrapPeriod) {}\n\n // --- Dependency setter ---\n function setAddresses(\n TroveManagerInitAddressesParams memory _troveManagerInitAddressesParams\n ) external override onlyOwner {\n {\n checkContract(_troveManagerInitAddressesParams._feeDistributorAddress);\n checkContract(_troveManagerInitAddressesParams._troveManagerRedeemOps);\n checkContract(_troveManagerInitAddressesParams._liquityBaseParamsAddress);\n checkContract(_troveManagerInitAddressesParams._borrowerOperationsAddress);\n checkContract(_troveManagerInitAddressesParams._activePoolAddress);\n checkContract(_troveManagerInitAddressesParams._defaultPoolAddress);\n checkContract(_troveManagerInitAddressesParams._stabilityPoolAddress);\n checkContract(_troveManagerInitAddressesParams._gasPoolAddress);\n checkContract(_troveManagerInitAddressesParams._collSurplusPoolAddress);\n checkContract(_troveManagerInitAddressesParams._priceFeedAddress);\n checkContract(_troveManagerInitAddressesParams._zusdTokenAddress);\n checkContract(_troveManagerInitAddressesParams._sortedTrovesAddress);\n checkContract(_troveManagerInitAddressesParams._zeroTokenAddress);\n checkContract(_troveManagerInitAddressesParams._zeroStakingAddress);\n }\n\n feeDistributor = IFeeDistributor(_troveManagerInitAddressesParams._feeDistributorAddress);\n troveManagerRedeemOps = _troveManagerInitAddressesParams._troveManagerRedeemOps;\n liquityBaseParams = ILiquityBaseParams(\n _troveManagerInitAddressesParams._liquityBaseParamsAddress\n );\n {\n borrowerOperationsAddress = _troveManagerInitAddressesParams\n ._borrowerOperationsAddress;\n activePool = IActivePool(_troveManagerInitAddressesParams._activePoolAddress);\n defaultPool = IDefaultPool(_troveManagerInitAddressesParams._defaultPoolAddress);\n _stabilityPool = IStabilityPool(\n _troveManagerInitAddressesParams._stabilityPoolAddress\n );\n gasPoolAddress = _troveManagerInitAddressesParams._gasPoolAddress;\n collSurplusPool = ICollSurplusPool(\n _troveManagerInitAddressesParams._collSurplusPoolAddress\n );\n priceFeed = IPriceFeed(_troveManagerInitAddressesParams._priceFeedAddress);\n _zusdToken = IZUSDToken(_troveManagerInitAddressesParams._zusdTokenAddress);\n sortedTroves = ISortedTroves(_troveManagerInitAddressesParams._sortedTrovesAddress);\n _zeroToken = IZEROToken(_troveManagerInitAddressesParams._zeroTokenAddress);\n _zeroStaking = IZEROStaking(_troveManagerInitAddressesParams._zeroStakingAddress);\n }\n\n emit FeeDistributorAddressChanged(_troveManagerInitAddressesParams._feeDistributorAddress);\n emit TroveManagerRedeemOpsAddressChanged(\n _troveManagerInitAddressesParams._troveManagerRedeemOps\n );\n emit LiquityBaseParamsAddressChanges(\n _troveManagerInitAddressesParams._borrowerOperationsAddress\n );\n emit BorrowerOperationsAddressChanged(\n _troveManagerInitAddressesParams._borrowerOperationsAddress\n );\n emit ActivePoolAddressChanged(_troveManagerInitAddressesParams._activePoolAddress);\n emit DefaultPoolAddressChanged(_troveManagerInitAddressesParams._defaultPoolAddress);\n emit StabilityPoolAddressChanged(_troveManagerInitAddressesParams._stabilityPoolAddress);\n emit GasPoolAddressChanged(_troveManagerInitAddressesParams._gasPoolAddress);\n emit CollSurplusPoolAddressChanged(\n _troveManagerInitAddressesParams._collSurplusPoolAddress\n );\n emit PriceFeedAddressChanged(_troveManagerInitAddressesParams._priceFeedAddress);\n emit ZUSDTokenAddressChanged(_troveManagerInitAddressesParams._zusdTokenAddress);\n emit SortedTrovesAddressChanged(_troveManagerInitAddressesParams._sortedTrovesAddress);\n emit ZEROTokenAddressChanged(_troveManagerInitAddressesParams._zeroTokenAddress);\n emit ZEROStakingAddressChanged(_troveManagerInitAddressesParams._zeroStakingAddress);\n }\n\n function setTroveManagerRedeemOps(address _troveManagerRedeemOps) external override onlyOwner {\n checkContract(_troveManagerRedeemOps);\n troveManagerRedeemOps = _troveManagerRedeemOps;\n emit TroveManagerRedeemOpsAddressChanged(_troveManagerRedeemOps);\n }\n\n // --- Getters ---\n\n function getTroveOwnersCount() external view override returns (uint256) {\n return TroveOwners.length;\n }\n\n function getTroveFromTroveOwnersArray(\n uint256 _index\n ) external view override returns (address) {\n return TroveOwners[_index];\n }\n\n // --- Trove Liquidation functions ---\n\n /// Single liquidation function. Closes the trove if its ICR is lower than the minimum collateral ratio.\n function liquidate(address _borrower) external override {\n _requireTroveIsActive(_borrower);\n\n address[] memory borrowers = new address[](1);\n borrowers[0] = _borrower;\n batchLiquidateTroves(borrowers);\n }\n\n // --- Inner single liquidation functions ---\n\n /// Liquidate one trove, in Normal Mode.\n function _liquidateNormalMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n address _borrower,\n uint256 _ZUSDInStabPool\n ) internal returns (LiquidationValues memory singleLiquidation) {\n LocalVariables_InnerSingleLiquidateFunction memory vars;\n\n (\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n vars.pendingDebtReward,\n vars.pendingCollReward\n ) = getEntireDebtAndColl(_borrower);\n\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n _removeStake(_borrower);\n\n singleLiquidation.collGasCompensation = _getCollGasCompensation(\n singleLiquidation.entireTroveColl\n );\n singleLiquidation.ZUSDGasCompensation = ZUSD_GAS_COMPENSATION;\n uint256 collToLiquidate = singleLiquidation.entireTroveColl.sub(\n singleLiquidation.collGasCompensation\n );\n\n (\n singleLiquidation.debtToOffset,\n singleLiquidation.collToSendToSP,\n singleLiquidation.debtToRedistribute,\n singleLiquidation.collToRedistribute\n ) = _getOffsetAndRedistributionVals(\n singleLiquidation.entireTroveDebt,\n collToLiquidate,\n _ZUSDInStabPool\n );\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n TroveManagerOperation.liquidateInNormalMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInNormalMode);\n return singleLiquidation;\n }\n\n /// Liquidate one trove, in Recovery Mode.\n function _liquidateRecoveryMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n address _borrower,\n uint256 _ICR,\n uint256 _ZUSDInStabPool,\n uint256 _TCR,\n uint256 _price\n ) internal returns (LiquidationValues memory singleLiquidation) {\n LocalVariables_InnerSingleLiquidateFunction memory vars;\n if (TroveOwners.length <= 1) {\n return singleLiquidation;\n } // don't liquidate if last trove\n (\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n vars.pendingDebtReward,\n vars.pendingCollReward\n ) = getEntireDebtAndColl(_borrower);\n\n singleLiquidation.collGasCompensation = _getCollGasCompensation(\n singleLiquidation.entireTroveColl\n );\n singleLiquidation.ZUSDGasCompensation = ZUSD_GAS_COMPENSATION;\n vars.collToLiquidate = singleLiquidation.entireTroveColl.sub(\n singleLiquidation.collGasCompensation\n );\n\n // If ICR <= 100%, purely redistribute the Trove across all active Troves\n if (_ICR <= _100pct) {\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n _removeStake(_borrower);\n\n singleLiquidation.debtToOffset = 0;\n singleLiquidation.collToSendToSP = 0;\n singleLiquidation.debtToRedistribute = singleLiquidation.entireTroveDebt;\n singleLiquidation.collToRedistribute = vars.collToLiquidate;\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n TroveManagerOperation.liquidateInRecoveryMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode);\n\n // If 100% < ICR < MCR, offset as much as possible, and redistribute the remainder\n } else if ((_ICR > _100pct) && (_ICR < liquityBaseParams.MCR())) {\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n _removeStake(_borrower);\n\n (\n singleLiquidation.debtToOffset,\n singleLiquidation.collToSendToSP,\n singleLiquidation.debtToRedistribute,\n singleLiquidation.collToRedistribute\n ) = _getOffsetAndRedistributionVals(\n singleLiquidation.entireTroveDebt,\n vars.collToLiquidate,\n _ZUSDInStabPool\n );\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n TroveManagerOperation.liquidateInRecoveryMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode);\n /*\n * If 110% <= ICR < current TCR (accounting for the preceding liquidations in the current sequence)\n * and there is ZUSD in the Stability Pool, only offset, with no redistribution,\n * but at a capped rate of 1.1 and only if the whole debt can be liquidated.\n * The remainder due to the capped rate will be claimable as collateral surplus.\n */\n } else if (\n (_ICR >= liquityBaseParams.MCR()) &&\n (_ICR < _TCR) &&\n (singleLiquidation.entireTroveDebt <= _ZUSDInStabPool)\n ) {\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n assert(_ZUSDInStabPool != 0);\n\n _removeStake(_borrower);\n singleLiquidation = _getCappedOffsetVals(\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n _price\n );\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n if (singleLiquidation.collSurplus > 0) {\n collSurplusPool.accountSurplus(_borrower, singleLiquidation.collSurplus);\n }\n\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.collToSendToSP,\n TroveManagerOperation.liquidateInRecoveryMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode);\n } else {\n // if (_ICR >= liquityBaseParams.MCR() && ( _ICR >= _TCR || singleLiquidation.entireTroveDebt > _ZUSDInStabPool))\n LiquidationValues memory zeroVals;\n return zeroVals;\n }\n\n return singleLiquidation;\n }\n\n /** In a full liquidation, returns the values for a trove's coll and debt to be offset, and coll and debt to be\n * redistributed to active troves.\n */\n function _getOffsetAndRedistributionVals(\n uint256 _debt,\n uint256 _coll,\n uint256 _ZUSDInStabPool\n )\n internal\n pure\n returns (\n uint256 debtToOffset,\n uint256 collToSendToSP,\n uint256 debtToRedistribute,\n uint256 collToRedistribute\n )\n {\n if (_ZUSDInStabPool > 0) {\n /*\n * Offset as much debt & collateral as possible against the Stability Pool, and redistribute the remainder\n * between all active troves.\n *\n * If the trove's debt is larger than the deposited ZUSD in the Stability Pool:\n *\n * - Offset an amount of the trove's debt equal to the ZUSD in the Stability Pool\n * - Send a fraction of the trove's collateral to the Stability Pool, equal to the fraction of its offset debt\n *\n */\n debtToOffset = LiquityMath._min(_debt, _ZUSDInStabPool);\n collToSendToSP = _coll.mul(debtToOffset).div(_debt);\n debtToRedistribute = _debt.sub(debtToOffset);\n collToRedistribute = _coll.sub(collToSendToSP);\n } else {\n debtToOffset = 0;\n collToSendToSP = 0;\n debtToRedistribute = _debt;\n collToRedistribute = _coll;\n }\n }\n\n /**\n * Get its offset coll/debt and ETH gas comp, and close the trove.\n */\n function _getCappedOffsetVals(\n uint256 _entireTroveDebt,\n uint256 _entireTroveColl,\n uint256 _price\n ) internal view returns (LiquidationValues memory singleLiquidation) {\n singleLiquidation.entireTroveDebt = _entireTroveDebt;\n singleLiquidation.entireTroveColl = _entireTroveColl;\n uint256 collToOffset = _entireTroveDebt.mul(liquityBaseParams.MCR()).div(_price);\n\n singleLiquidation.collGasCompensation = _getCollGasCompensation(collToOffset);\n singleLiquidation.ZUSDGasCompensation = ZUSD_GAS_COMPENSATION;\n\n singleLiquidation.debtToOffset = _entireTroveDebt;\n singleLiquidation.collToSendToSP = collToOffset.sub(singleLiquidation.collGasCompensation);\n singleLiquidation.collSurplus = _entireTroveColl.sub(collToOffset);\n singleLiquidation.debtToRedistribute = 0;\n singleLiquidation.collToRedistribute = 0;\n }\n\n /**\n * Liquidate a sequence of troves. Closes a maximum number of n under-collateralized Troves,\n * starting from the one with the lowest collateral ratio in the system, and moving upwards\n */\n function liquidateTroves(uint256 _n) external override {\n ContractsCache memory contractsCache = ContractsCache(\n activePool,\n defaultPool,\n IZUSDToken(address(0)),\n IZEROStaking(address(0)),\n sortedTroves,\n ICollSurplusPool(address(0)),\n address(0)\n );\n IStabilityPool stabilityPoolCached = _stabilityPool;\n\n LocalVariables_OuterLiquidationFunction memory vars;\n\n LiquidationTotals memory totals;\n\n vars.price = priceFeed.fetchPrice();\n vars.ZUSDInStabPool = stabilityPoolCached.getTotalZUSDDeposits();\n vars.recoveryModeAtStart = _checkRecoveryMode(vars.price);\n\n // Perform the appropriate liquidation sequence - tally the values, and obtain their totals\n if (vars.recoveryModeAtStart) {\n totals = _getTotalsFromLiquidateTrovesSequence_RecoveryMode(\n contractsCache,\n vars.price,\n vars.ZUSDInStabPool,\n _n\n );\n } else {\n // if !vars.recoveryModeAtStart\n totals = _getTotalsFromLiquidateTrovesSequence_NormalMode(\n contractsCache.activePool,\n contractsCache.defaultPool,\n vars.price,\n vars.ZUSDInStabPool,\n _n\n );\n }\n\n require(totals.totalDebtInSequence > 0, \"TroveManager: nothing to liquidate\");\n\n // Move liquidated ETH and ZUSD to the appropriate pools\n stabilityPoolCached.offset(totals.totalDebtToOffset, totals.totalCollToSendToSP);\n _redistributeDebtAndColl(\n contractsCache.activePool,\n contractsCache.defaultPool,\n totals.totalDebtToRedistribute,\n totals.totalCollToRedistribute\n );\n if (totals.totalCollSurplus > 0) {\n contractsCache.activePool.sendETH(address(collSurplusPool), totals.totalCollSurplus);\n }\n\n // Update system snapshots\n _updateSystemSnapshots_excludeCollRemainder(\n contractsCache.activePool,\n totals.totalCollGasCompensation\n );\n\n vars.liquidatedDebt = totals.totalDebtInSequence;\n vars.liquidatedColl = totals.totalCollInSequence.sub(totals.totalCollGasCompensation).sub(\n totals.totalCollSurplus\n );\n emit Liquidation(\n vars.liquidatedDebt,\n vars.liquidatedColl,\n totals.totalCollGasCompensation,\n totals.totalZUSDGasCompensation\n );\n\n // Send gas compensation to caller\n _sendGasCompensation(\n contractsCache.activePool,\n msg.sender,\n totals.totalZUSDGasCompensation,\n totals.totalCollGasCompensation\n );\n }\n\n /**\n * This function is used when the liquidateTroves sequence starts during Recovery Mode. However, it\n * handle the case where the system *leaves* Recovery Mode, part way through the liquidation sequence\n */\n function _getTotalsFromLiquidateTrovesSequence_RecoveryMode(\n ContractsCache memory _contractsCache,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n uint256 _n\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n vars.backToNormalMode = false;\n vars.entireSystemDebt = getEntireSystemDebt();\n vars.entireSystemColl = getEntireSystemColl();\n\n vars.user = _contractsCache.sortedTroves.getLast();\n address firstUser = _contractsCache.sortedTroves.getFirst();\n for (vars.i = 0; vars.i < _n && vars.user != firstUser; vars.i++) {\n // we need to cache it, because current user is likely going to be deleted\n address nextUser = _contractsCache.sortedTroves.getPrev(vars.user);\n\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (!vars.backToNormalMode) {\n // Break the loop if ICR is greater than liquityBaseParams.MCR() and Stability Pool is empty\n if (vars.ICR >= liquityBaseParams.MCR() && vars.remainingZUSDInStabPool == 0) {\n break;\n }\n\n uint256 TCR = LiquityMath._computeCR(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n\n singleLiquidation = _liquidateRecoveryMode(\n _contractsCache.activePool,\n _contractsCache.defaultPool,\n vars.user,\n vars.ICR,\n vars.remainingZUSDInStabPool,\n TCR,\n _price\n );\n\n // Update aggregate trackers\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n vars.entireSystemDebt = vars.entireSystemDebt.sub(singleLiquidation.debtToOffset);\n vars.entireSystemColl = vars\n .entireSystemColl\n .sub(singleLiquidation.collToSendToSP)\n .sub(singleLiquidation.collSurplus);\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n\n vars.backToNormalMode = !_checkPotentialRecoveryMode(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n } else if (vars.backToNormalMode && vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _contractsCache.activePool,\n _contractsCache.defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n } else break; // break if the loop reaches a Trove with ICR >= MCR\n\n vars.user = nextUser;\n }\n }\n\n function _getTotalsFromLiquidateTrovesSequence_NormalMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n uint256 _n\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n ISortedTroves sortedTrovesCached = sortedTroves;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n\n for (vars.i = 0; vars.i < _n; vars.i++) {\n vars.user = sortedTrovesCached.getLast();\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n } else break; // break if the loop reaches a Trove with ICR >= MCR\n }\n }\n\n /**\n * Attempt to liquidate a custom list of troves provided by the caller.\n */\n function batchLiquidateTroves(address[] memory _troveArray) public override {\n require(_troveArray.length != 0, \"TroveManager: Calldata address array must not be empty\");\n\n IActivePool activePoolCached = activePool;\n IDefaultPool defaultPoolCached = defaultPool;\n IStabilityPool stabilityPoolCached = _stabilityPool;\n\n LocalVariables_OuterLiquidationFunction memory vars;\n LiquidationTotals memory totals;\n\n vars.price = priceFeed.fetchPrice();\n vars.ZUSDInStabPool = stabilityPoolCached.getTotalZUSDDeposits();\n vars.recoveryModeAtStart = _checkRecoveryMode(vars.price);\n\n // Perform the appropriate liquidation sequence - tally values and obtain their totals.\n if (vars.recoveryModeAtStart) {\n totals = _getTotalFromBatchLiquidate_RecoveryMode(\n activePoolCached,\n defaultPoolCached,\n vars.price,\n vars.ZUSDInStabPool,\n _troveArray\n );\n } else {\n // if !vars.recoveryModeAtStart\n totals = _getTotalsFromBatchLiquidate_NormalMode(\n activePoolCached,\n defaultPoolCached,\n vars.price,\n vars.ZUSDInStabPool,\n _troveArray\n );\n }\n\n require(totals.totalDebtInSequence > 0, \"TroveManager: nothing to liquidate\");\n\n // Move liquidated ETH and ZUSD to the appropriate pools\n stabilityPoolCached.offset(totals.totalDebtToOffset, totals.totalCollToSendToSP);\n _redistributeDebtAndColl(\n activePoolCached,\n defaultPoolCached,\n totals.totalDebtToRedistribute,\n totals.totalCollToRedistribute\n );\n if (totals.totalCollSurplus > 0) {\n activePoolCached.sendETH(address(collSurplusPool), totals.totalCollSurplus);\n }\n\n // Update system snapshots\n _updateSystemSnapshots_excludeCollRemainder(\n activePoolCached,\n totals.totalCollGasCompensation\n );\n\n vars.liquidatedDebt = totals.totalDebtInSequence;\n vars.liquidatedColl = totals.totalCollInSequence.sub(totals.totalCollGasCompensation).sub(\n totals.totalCollSurplus\n );\n emit Liquidation(\n vars.liquidatedDebt,\n vars.liquidatedColl,\n totals.totalCollGasCompensation,\n totals.totalZUSDGasCompensation\n );\n\n // Send gas compensation to caller\n _sendGasCompensation(\n activePoolCached,\n msg.sender,\n totals.totalZUSDGasCompensation,\n totals.totalCollGasCompensation\n );\n }\n\n /**\n * This function is used when the batch liquidation sequence starts during Recovery Mode. However, it\n * handle the case where the system *leaves* Recovery Mode, part way through the liquidation sequence\n */\n function _getTotalFromBatchLiquidate_RecoveryMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n address[] memory _troveArray\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n vars.backToNormalMode = false;\n vars.entireSystemDebt = getEntireSystemDebt();\n vars.entireSystemColl = getEntireSystemColl();\n\n for (vars.i = 0; vars.i < _troveArray.length; vars.i++) {\n vars.user = _troveArray[vars.i];\n // Skip non-active troves\n if (Troves[vars.user].status != Status.active) {\n continue;\n }\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (!vars.backToNormalMode) {\n // Skip this trove if ICR is greater than liquityBaseParams.MCR() and Stability Pool is empty\n if (vars.ICR >= liquityBaseParams.MCR() && vars.remainingZUSDInStabPool == 0) {\n continue;\n }\n\n uint256 TCR = LiquityMath._computeCR(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n\n singleLiquidation = _liquidateRecoveryMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.ICR,\n vars.remainingZUSDInStabPool,\n TCR,\n _price\n );\n\n // Update aggregate trackers\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n vars.entireSystemDebt = vars.entireSystemDebt.sub(singleLiquidation.debtToOffset);\n vars.entireSystemColl = vars.entireSystemColl.sub(\n singleLiquidation.collToSendToSP\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n\n vars.backToNormalMode = !_checkPotentialRecoveryMode(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n } else if (vars.backToNormalMode && vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n } else continue; // In Normal Mode skip troves with ICR >= MCR\n }\n }\n\n function _getTotalsFromBatchLiquidate_NormalMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n address[] memory _troveArray\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n\n for (vars.i = 0; vars.i < _troveArray.length; vars.i++) {\n vars.user = _troveArray[vars.i];\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n }\n }\n }\n\n // --- Liquidation helper functions ---\n\n function _addLiquidationValuesToTotals(\n LiquidationTotals memory oldTotals,\n LiquidationValues memory singleLiquidation\n ) internal pure returns (LiquidationTotals memory newTotals) {\n // Tally all the values with their respective running totals\n newTotals.totalCollGasCompensation = oldTotals.totalCollGasCompensation.add(\n singleLiquidation.collGasCompensation\n );\n newTotals.totalZUSDGasCompensation = oldTotals.totalZUSDGasCompensation.add(\n singleLiquidation.ZUSDGasCompensation\n );\n newTotals.totalDebtInSequence = oldTotals.totalDebtInSequence.add(\n singleLiquidation.entireTroveDebt\n );\n newTotals.totalCollInSequence = oldTotals.totalCollInSequence.add(\n singleLiquidation.entireTroveColl\n );\n newTotals.totalDebtToOffset = oldTotals.totalDebtToOffset.add(\n singleLiquidation.debtToOffset\n );\n newTotals.totalCollToSendToSP = oldTotals.totalCollToSendToSP.add(\n singleLiquidation.collToSendToSP\n );\n newTotals.totalDebtToRedistribute = oldTotals.totalDebtToRedistribute.add(\n singleLiquidation.debtToRedistribute\n );\n newTotals.totalCollToRedistribute = oldTotals.totalCollToRedistribute.add(\n singleLiquidation.collToRedistribute\n );\n newTotals.totalCollSurplus = oldTotals.totalCollSurplus.add(singleLiquidation.collSurplus);\n\n return newTotals;\n }\n\n function _sendGasCompensation(\n IActivePool _activePool,\n address _liquidator,\n uint256 _ZUSD,\n uint256 _ETH\n ) internal {\n if (_ZUSD > 0) {\n _zusdToken.returnFromPool(gasPoolAddress, _liquidator, _ZUSD);\n }\n\n if (_ETH > 0) {\n _activePool.sendETH(_liquidator, _ETH);\n }\n }\n\n // --- Helper functions ---\n\n /// @return the nominal collateral ratio (ICR) of a given Trove, without the price. Takes a trove's pending coll and debt rewards from redistributions into account.\n function getNominalICR(address _borrower) public view override returns (uint256) {\n (uint256 currentETH, uint256 currentZUSDDebt) = _getCurrentTroveAmounts(_borrower);\n\n uint256 NICR = LiquityMath._computeNominalCR(currentETH, currentZUSDDebt);\n return NICR;\n }\n\n function applyPendingRewards(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _applyPendingRewards(activePool, defaultPool, _borrower);\n }\n\n /// Update borrower's snapshots of L_ETH and L_ZUSDDebt to reflect the current values\n function updateTroveRewardSnapshots(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _updateTroveRewardSnapshots(_borrower);\n }\n\n /// Return the Troves entire debt and coll, including pending rewards from redistributions.\n function getEntireDebtAndColl(\n address _borrower\n )\n public\n view\n override\n returns (\n uint256 debt,\n uint256 coll,\n uint256 pendingZUSDDebtReward,\n uint256 pendingETHReward\n )\n {\n debt = Troves[_borrower].debt;\n coll = Troves[_borrower].coll;\n\n pendingZUSDDebtReward = getPendingZUSDDebtReward(_borrower);\n pendingETHReward = getPendingETHReward(_borrower);\n\n debt = debt.add(pendingZUSDDebtReward);\n coll = coll.add(pendingETHReward);\n }\n\n function removeStake(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _removeStake(_borrower);\n }\n\n function updateStakeAndTotalStakes(address _borrower) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n return _updateStakeAndTotalStakes(_borrower);\n }\n\n function _redistributeDebtAndColl(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _debt,\n uint256 _coll\n ) internal {\n if (_debt == 0) {\n return;\n }\n\n /*\n * Add distributed coll and debt rewards-per-unit-staked to the running totals. Division uses a \"feedback\"\n * error correction, to keep the cumulative error low in the running totals L_ETH and L_ZUSDDebt:\n *\n * 1) Form numerators which compensate for the floor division errors that occurred the last time this\n * function was called.\n * 2) Calculate \"per-unit-staked\" ratios.\n * 3) Multiply each ratio back by its denominator, to reveal the current floor division error.\n * 4) Store these errors for use in the next correction when this function is called.\n * 5) Note: static analysis tools complain about this \"division before multiplication\", however, it is intended.\n */\n uint256 ETHNumerator = _coll.mul(DECIMAL_PRECISION).add(lastETHError_Redistribution);\n uint256 ZUSDDebtNumerator = _debt.mul(DECIMAL_PRECISION).add(\n lastZUSDDebtError_Redistribution\n );\n\n // Get the per-unit-staked terms\n uint256 ETHRewardPerUnitStaked = ETHNumerator.div(totalStakes);\n uint256 ZUSDDebtRewardPerUnitStaked = ZUSDDebtNumerator.div(totalStakes);\n\n lastETHError_Redistribution = ETHNumerator.sub(ETHRewardPerUnitStaked.mul(totalStakes));\n lastZUSDDebtError_Redistribution = ZUSDDebtNumerator.sub(\n ZUSDDebtRewardPerUnitStaked.mul(totalStakes)\n );\n\n // Add per-unit-staked terms to the running totals\n L_ETH = L_ETH.add(ETHRewardPerUnitStaked);\n L_ZUSDDebt = L_ZUSDDebt.add(ZUSDDebtRewardPerUnitStaked);\n\n emit LTermsUpdated(L_ETH, L_ZUSDDebt);\n\n // Transfer coll and debt from ActivePool to DefaultPool\n _activePool.decreaseZUSDDebt(_debt);\n _defaultPool.increaseZUSDDebt(_debt);\n _activePool.sendETH(address(_defaultPool), _coll);\n }\n\n function closeTrove(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _closeTrove(_borrower, Status.closedByOwner);\n }\n\n /**\n * Updates snapshots of system total stakes and total collateral, excluding a given collateral remainder from the calculation.\n * Used in a liquidation sequence.\n *\n * The calculation excludes a portion of collateral that is in the ActivePool:\n *\n * the total ETH gas compensation from the liquidation sequence\n *\n * The ETH as compensation must be excluded as it is always sent out at the very end of the liquidation sequence.\n */\n function _updateSystemSnapshots_excludeCollRemainder(\n IActivePool _activePool,\n uint256 _collRemainder\n ) internal {\n totalStakesSnapshot = totalStakes;\n\n uint256 activeColl = _activePool.getETH();\n uint256 liquidatedColl = defaultPool.getETH();\n totalCollateralSnapshot = activeColl.sub(_collRemainder).add(liquidatedColl);\n\n emit SystemSnapshotsUpdated(totalStakesSnapshot, totalCollateralSnapshot);\n }\n\n /// Push the owner's address to the Trove owners list, and record the corresponding array index on the Trove struct\n function addTroveOwnerToArray(address _borrower) external override returns (uint256 index) {\n _requireCallerIsBorrowerOperations();\n return _addTroveOwnerToArray(_borrower);\n }\n\n function _addTroveOwnerToArray(address _borrower) internal returns (uint128 index) {\n /* Max array size is 2**128 - 1, i.e. ~3e30 troves. No risk of overflow, since troves have minimum ZUSD\n debt of liquidation reserve plus MIN_NET_DEBT. 3e30 ZUSD dwarfs the value of all wealth in the world ( which is < 1e15 USD). */\n\n // Push the Troveowner to the array\n TroveOwners.push(_borrower);\n\n // Record the index of the new Troveowner on their Trove struct\n index = uint128(TroveOwners.length.sub(1));\n Troves[_borrower].arrayIndex = index;\n\n return index;\n }\n\n // --- Recovery Mode and TCR functions ---\n\n function getTCR(uint256 _price) external view override returns (uint256) {\n return _getTCR(_price);\n }\n\n function MCR() external view override returns (uint256) {\n return liquityBaseParams.MCR();\n }\n\n function CCR() external view override returns (uint256) {\n return liquityBaseParams.CCR();\n }\n\n function checkRecoveryMode(uint256 _price) external view override returns (bool) {\n return _checkRecoveryMode(_price);\n }\n\n // Check whether or not the system *would be* in Recovery Mode, given an ETH:USD price, and the entire system coll and debt.\n function _checkPotentialRecoveryMode(\n uint256 _entireSystemColl,\n uint256 _entireSystemDebt,\n uint256 _price\n ) internal view returns (bool) {\n uint256 TCR = LiquityMath._computeCR(_entireSystemColl, _entireSystemDebt, _price);\n\n return TCR < liquityBaseParams.CCR();\n }\n\n function getRedemptionRateWithDecay() public view override returns (uint256) {\n return _calcRedemptionRate(_calcDecayedBaseRate());\n }\n\n function getRedemptionFeeWithDecay(\n uint256 _ETHDrawn\n ) external view override returns (uint256) {\n return _calcRedemptionFee(getRedemptionRateWithDecay(), _ETHDrawn);\n }\n\n // --- Borrowing fee functions ---\n\n function getBorrowingRate() public view override returns (uint256) {\n return _calcBorrowingRate(baseRate);\n }\n\n function getBorrowingRateWithDecay() public view override returns (uint256) {\n return _calcBorrowingRate(_calcDecayedBaseRate());\n }\n\n function _calcBorrowingRate(uint256 _baseRate) internal view returns (uint256) {\n return\n LiquityMath._min(\n liquityBaseParams.BORROWING_FEE_FLOOR().add(_baseRate),\n liquityBaseParams.MAX_BORROWING_FEE()\n );\n }\n\n function getBorrowingFee(uint256 _ZUSDDebt) external view override returns (uint256) {\n return _calcBorrowingFee(getBorrowingRate(), _ZUSDDebt);\n }\n\n function getBorrowingFeeWithDecay(uint256 _ZUSDDebt) external view override returns (uint256) {\n return _calcBorrowingFee(getBorrowingRateWithDecay(), _ZUSDDebt);\n }\n\n function _calcBorrowingFee(\n uint256 _borrowingRate,\n uint256 _ZUSDDebt\n ) internal pure returns (uint256) {\n return _borrowingRate.mul(_ZUSDDebt).div(DECIMAL_PRECISION);\n }\n\n /// Updates the baseRate state variable based on time elapsed since the last redemption or ZUSD borrowing operation.\n function decayBaseRateFromBorrowing() external override {\n _requireCallerIsBorrowerOperations();\n\n uint256 decayedBaseRate = _calcDecayedBaseRate();\n assert(decayedBaseRate <= DECIMAL_PRECISION); // The baseRate can decay to 0\n\n baseRate = decayedBaseRate;\n emit BaseRateUpdated(decayedBaseRate);\n\n _updateLastFeeOpTime();\n }\n\n // --- Internal fee functions ---\n\n // --- Trove property getters ---\n\n function getTroveStatus(address _borrower) external view override returns (uint256) {\n return uint256(Troves[_borrower].status);\n }\n\n function getTroveStake(address _borrower) external view override returns (uint256) {\n return Troves[_borrower].stake;\n }\n\n function getTroveDebt(address _borrower) external view override returns (uint256) {\n return Troves[_borrower].debt;\n }\n\n function getTroveColl(address _borrower) external view override returns (uint256) {\n return Troves[_borrower].coll;\n }\n\n // --- Trove property setters, called by BorrowerOperations ---\n\n function setTroveStatus(address _borrower, uint256 _num) external override {\n _requireCallerIsBorrowerOperations();\n Troves[_borrower].status = Status(_num);\n }\n\n function increaseTroveColl(\n address _borrower,\n uint256 _collIncrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newColl = Troves[_borrower].coll.add(_collIncrease);\n Troves[_borrower].coll = newColl;\n return newColl;\n }\n\n function decreaseTroveColl(\n address _borrower,\n uint256 _collDecrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newColl = Troves[_borrower].coll.sub(_collDecrease);\n Troves[_borrower].coll = newColl;\n return newColl;\n }\n\n function increaseTroveDebt(\n address _borrower,\n uint256 _debtIncrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newDebt = Troves[_borrower].debt.add(_debtIncrease);\n Troves[_borrower].debt = newDebt;\n return newDebt;\n }\n\n function decreaseTroveDebt(\n address _borrower,\n uint256 _debtDecrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newDebt = Troves[_borrower].debt.sub(_debtDecrease);\n Troves[_borrower].debt = newDebt;\n return newDebt;\n }\n\n function getCurrentICR(\n address _borrower,\n uint256 _price\n ) external view override returns (uint256) {\n return _getCurrentICR(_borrower, _price);\n }\n\n function getPendingETHReward(address _borrower) public view override returns (uint256) {\n return _getPendingETHReward(_borrower);\n }\n\n function getPendingZUSDDebtReward(address _borrower) public view override returns (uint256) {\n return _getPendingZUSDDebtReward(_borrower);\n }\n\n function hasPendingRewards(address _borrower) public view override returns (bool) {\n return _hasPendingRewards(_borrower);\n }\n\n function getRedemptionRate() public view override returns (uint256) {\n return _getRedemptionRate();\n }\n\n /// @dev this function forwards the call to the troveManagerRedeemOps in a delegate call fashion\n /// so the parameters are not needed\n function redeemCollateral(\n uint256 _ZUSDamount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage\n ) external override {\n (bool success, bytes memory returndata) = troveManagerRedeemOps.delegatecall(msg.data);\n require(success, string(returndata));\n }\n\n /// @dev this function forwards the call to the troveManagerRedeemOps in a delegate call fashion\n /// so the parameters are not needed\n ///DLLR _owner or _spender can use Sovryn Mynt to convert DLLR to ZUSD, then use the Zero redemption mechanism to redeem ZUSD for RBTC, all in a single transaction\n function redeemCollateralViaDLLR(\n uint256 _dllrAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage,\n IMassetManager.PermitParams calldata _permitParams\n ) external override {\n (bool success, bytes memory returndata) = troveManagerRedeemOps.delegatecall(msg.data);\n require(success, string(returndata));\n }\n}\n" + }, + "contracts/TroveManagerStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROToken.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/BaseMath.sol\";\nimport \"./Dependencies/console.sol\";\n\ncontract TroveManagerStorage is Ownable, BaseMath {\n string public constant NAME = \"TroveManager\";\n\n // --- Connected contract declarations ---\n\n address public troveManagerRedeemOps;\n\n address public borrowerOperationsAddress;\n\n IStabilityPool public _stabilityPool;\n\n address gasPoolAddress;\n\n ICollSurplusPool collSurplusPool;\n\n IZUSDToken public _zusdToken;\n\n IZEROToken public _zeroToken;\n\n IZEROStaking public _zeroStaking;\n\n IFeeDistributor public feeDistributor;\n\n // A doubly linked list of Troves, sorted by their sorted by their collateral ratios\n ISortedTroves public sortedTroves;\n\n // --- Data structures ---\n\n uint256 public baseRate;\n\n // The timestamp of the latest fee operation (redemption or new ZUSD issuance)\n uint256 public lastFeeOperationTime;\n\n enum Status {\n nonExistent,\n active,\n closedByOwner,\n closedByLiquidation,\n closedByRedemption\n }\n\n // Store the necessary data for a trove\n struct Trove {\n uint256 debt;\n uint256 coll;\n uint256 stake;\n Status status;\n uint128 arrayIndex;\n }\n\n mapping(address => Trove) public Troves;\n\n uint256 public totalStakes;\n\n // Snapshot of the value of totalStakes, taken immediately after the latest liquidation\n uint256 public totalStakesSnapshot;\n\n // Snapshot of the total collateral across the ActivePool and DefaultPool, immediately after the latest liquidation.\n uint256 public totalCollateralSnapshot;\n\n /*\n * L_ETH and L_ZUSDDebt track the sums of accumulated liquidation rewards per unit staked. During its lifetime, each stake earns:\n *\n * An ETH gain of ( stake * [L_ETH - L_ETH(0)] )\n * A ZUSDDebt increase of ( stake * [L_ZUSDDebt - L_ZUSDDebt(0)] )\n *\n * Where L_ETH(0) and L_ZUSDDebt(0) are snapshots of L_ETH and L_ZUSDDebt for the active Trove taken at the instant the stake was made\n */\n uint256 public L_ETH;\n uint256 public L_ZUSDDebt;\n\n // Map addresses with active troves to their RewardSnapshot\n mapping(address => RewardSnapshot) public rewardSnapshots;\n\n // Object containing the ETH and ZUSD snapshots for a given active trove\n struct RewardSnapshot {\n uint256 ETH;\n uint256 ZUSDDebt;\n }\n\n // Array of all active trove addresses - used to to compute an approximate hint off-chain, for the sorted list insertion\n address[] public TroveOwners;\n\n // Error trackers for the trove redistribution calculation\n uint256 public lastETHError_Redistribution;\n uint256 public lastZUSDDebtError_Redistribution;\n}\n" + }, + "contracts/ZERO/CommunityIssuance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Interfaces/ICommunityIssuance.sol\";\nimport \"../Dependencies/BaseMath.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"./CommunityIssuanceStorage.sol\";\nimport \"../Interfaces/IStabilityPool.sol\";\n\ncontract CommunityIssuance is\n CommunityIssuanceStorage,\n CheckContract,\n BaseMath\n{\n using SafeMath for uint256;\n\n // --- Events ---\n\n event SOVTokenAddressSet(address _sovTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event StabilityPoolAddressSet(address _stabilityPoolAddress);\n event PriceFeedAddressSet(address _priceFeed);\n event RewardManagerAddressSet(address _rewardManagerAddress);\n event TotalSOVIssuedUpdated(uint256 _latestSOVIssued);\n event APRSet(uint256 _APR);\n\n // --- Modifier ---\n modifier onlyRewardManager() {\n require(msg.sender == rewardManager, \"Permission::rewardManager: access denied\");\n _;\n }\n\n // --- Functions ---\n\n /**\n * @dev initialization function to set configs.\n * can only be initialized by owner.\n * @param _sovTokenAddress sov token address.\n * @param _zusdTokenAddress zero token address.\n * @param _stabilityPoolAddress stability pool address.\n * @param _priceFeed price feed address.\n * @param _APR apr in basis points.\n */\n function initialize(\n address _sovTokenAddress,\n address _zusdTokenAddress,\n address _stabilityPoolAddress,\n address _priceFeed,\n uint256 _APR\n ) external initializer onlyOwner {\n checkContract(_sovTokenAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_priceFeed);\n\n _validateAPR(_APR);\n\n sovToken = IERC20(_sovTokenAddress);\n zusdToken = IERC20(_zusdTokenAddress);\n stabilityPoolAddress = _stabilityPoolAddress;\n priceFeed = IPriceFeedSovryn(_priceFeed);\n APR = _APR;\n lastIssuanceTime = block.timestamp;\n\n emit SOVTokenAddressSet(_sovTokenAddress);\n emit StabilityPoolAddressSet(_stabilityPoolAddress);\n emit PriceFeedAddressSet(_priceFeed);\n emit APRSet(_APR);\n }\n\n /**\n * @dev setter function to set the APR value in basis points.\n * can only be called by reward manager.\n * @param _APR apr value in basis points.\n */\n function setAPR(uint256 _APR) external onlyRewardManager {\n _validateAPR(_APR);\n\n // We need to trigger issueSOV function before set the new APR\n // because otherwise, we will change the APR retrospectively for the time passed since last issuance.\n uint256 _totalZUSDDeposits = IStabilityPool(stabilityPoolAddress).getTotalZUSDDeposits();\n _issueSOV(_totalZUSDDeposits);\n\n APR = _APR;\n\n emit APRSet(_APR);\n }\n\n /**\n * @dev setter function to set the price feed.\n * can only be called by the owner.\n * @param _priceFeedAddress price feed address.\n */\n function setPriceFeed(address _priceFeedAddress) external onlyOwner {\n checkContract(_priceFeedAddress);\n\n priceFeed = IPriceFeedSovryn(_priceFeedAddress);\n\n emit PriceFeedAddressSet(_priceFeedAddress);\n }\n\n /**\n * @dev setter function to set reward manager.\n * can only be called by the owner.\n * @param _rewardManagerAddress reward manager address.\n */\n function setRewardManager(address _rewardManagerAddress) external onlyOwner {\n require(_rewardManagerAddress != address(0), \"Account cannot be zero address\");\n\n rewardManager = _rewardManagerAddress;\n\n emit RewardManagerAddressSet(_rewardManagerAddress);\n }\n\n /**\n * @dev validate the APR value.\n * the value must be >= 0 <= MAX_BPS (10000)\n */\n function _validateAPR(uint256 _APR) private {\n require(_APR <= MAX_BPS, \"APR must be less than 10000\");\n }\n\n\n function issueSOV(uint256 _totalZUSDDeposits) public returns (uint256) {\n _requireCallerIsStabilityPool();\n\n return _issueSOV(_totalZUSDDeposits);\n }\n\n function _issueSOV(uint256 _totalZUSDDeposits) private returns (uint256) {\n uint256 timePassedSinceLastIssuance = (block.timestamp.sub(lastIssuanceTime));\n uint256 issuance = _ZUSDToSOV(_totalZUSDDeposits.mul(APR).div(MAX_BPS).mul(timePassedSinceLastIssuance).div(365 days));\n\n totalSOVIssued = totalSOVIssued + issuance;\n lastIssuanceTime = block.timestamp;\n emit TotalSOVIssuedUpdated(totalSOVIssued);\n\n return issuance;\n }\n\n function sendSOV(address _account, uint256 _SOVamount) public {\n _requireCallerIsStabilityPool();\n\n bool success = sovToken.transfer(_account, _SOVamount);\n require(success, \"Failed to send ZERO\");\n }\n\n function _requireCallerIsStabilityPool() internal view {\n require(msg.sender == stabilityPoolAddress, \"CommunityIssuance: caller is not SP\");\n }\n\n /**\n * @dev get the ZUSD to SOV rate conversion. Mostly will be using Sovryn's PriceFeed.\n * @param _zusdAmount zusd amount to get the rate conversion\n * @return the total SOV will be returned.\n */\n function _ZUSDToSOV(uint256 _zusdAmount) internal view returns (uint256) {\n return priceFeed.queryReturn(address(zusdToken), address(sovToken), _zusdAmount);\n }\n}\n" + }, + "contracts/ZERO/CommunityIssuanceStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Interfaces/IPriceFeedSovryn.sol\";\nimport \"../Dependencies/Initializable.sol\";\n\ncontract CommunityIssuanceStorage is Ownable, Initializable {\n // --- Data ---\n\n string constant public NAME = \"CommunityIssuance\";\n\n uint256 constant MAX_BPS = 10000;\n\n IERC20 public sovToken;\n\n IERC20 public zusdToken;\n\n address public stabilityPoolAddress;\n\n uint256 public totalSOVIssued;\n\n uint256 public lastIssuanceTime;\n\n uint256 public APR; //in basis points\n\n address public rewardManager;\n\n IPriceFeedSovryn public priceFeed;\n}\n" + }, + "contracts/ZERO/ZEROStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/BaseMath.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/console.sol\";\nimport \"../Interfaces/IZEROToken.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\nimport \"../Interfaces/IZUSDToken.sol\";\nimport \"./ZEROStakingStorage.sol\";\n\ncontract ZEROStaking is ZEROStakingStorage, IZEROStaking, CheckContract, BaseMath {\n using SafeMath for uint256;\n\n // --- Events ---\n\n event ZEROTokenAddressSet(address _zeroTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event FeeDistributorAddressSet(address _feeDistributorAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event StakeChanged(address indexed staker, uint256 newStake);\n event StakingGainsWithdrawn(address indexed staker, uint256 ZUSDGain, uint256 ETHGain);\n event F_ETHUpdated(uint256 _F_ETH);\n event F_ZUSDUpdated(uint256 _F_ZUSD);\n event TotalZEROStakedUpdated(uint256 _totalZEROStaked);\n event EtherSent(address _account, uint256 _amount);\n event StakerSnapshotsUpdated(address _staker, uint256 _F_ETH, uint256 _F_ZUSD);\n\n // --- Functions ---\n\n function setAddresses(\n address _zeroTokenAddress,\n address _zusdTokenAddress,\n address _feeDistributorAddress,\n address _activePoolAddress\n ) external override onlyOwner {\n checkContract(_zeroTokenAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_feeDistributorAddress);\n checkContract(_activePoolAddress);\n\n zeroToken = IZEROToken(_zeroTokenAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n feeDistributorAddress = _feeDistributorAddress;\n activePoolAddress = _activePoolAddress;\n\n emit ZEROTokenAddressSet(_zeroTokenAddress);\n emit ZEROTokenAddressSet(_zusdTokenAddress);\n emit FeeDistributorAddressSet(_feeDistributorAddress);\n emit ActivePoolAddressSet(_activePoolAddress);\n }\n\n // If caller has a pre-existing stake, send any accumulated ETH and ZUSD gains to them.\n function stake(uint256 _ZEROamount) external override {\n _requireNonZeroAmount(_ZEROamount);\n\n uint256 currentStake = stakes[msg.sender];\n\n uint256 ETHGain;\n uint256 ZUSDGain;\n // Grab any accumulated ETH and ZUSD gains from the current stake\n if (currentStake != 0) {\n ETHGain = _getPendingETHGain(msg.sender);\n ZUSDGain = _getPendingZUSDGain(msg.sender);\n }\n\n _updateUserSnapshots(msg.sender);\n\n uint256 newStake = currentStake.add(_ZEROamount);\n\n // Increase user’s stake and total ZERO staked\n stakes[msg.sender] = newStake;\n totalZEROStaked = totalZEROStaked.add(_ZEROamount);\n emit TotalZEROStakedUpdated(totalZEROStaked);\n\n // Transfer ZERO from caller to this contract\n zeroToken.sendToZEROStaking(msg.sender, _ZEROamount);\n\n emit StakeChanged(msg.sender, newStake);\n emit StakingGainsWithdrawn(msg.sender, ZUSDGain, ETHGain);\n\n // Send accumulated ZUSD and ETH gains to the caller\n if (currentStake != 0) {\n require(zusdToken.transfer(msg.sender, ZUSDGain), \"Coudn't execute ZUSD transfer\");\n _sendETHGainToUser(ETHGain);\n }\n }\n\n /// Unstake the ZERO and send the it back to the caller, along with their accumulated ZUSD & ETH gains.\n /// If requested amount > stake, send their entire stake.\n function unstake(uint256 _ZEROamount) external override {\n uint256 currentStake = stakes[msg.sender];\n _requireUserHasStake(currentStake);\n\n // Grab any accumulated ETH and ZUSD gains from the current stake\n uint256 ETHGain = _getPendingETHGain(msg.sender);\n uint256 ZUSDGain = _getPendingZUSDGain(msg.sender);\n\n _updateUserSnapshots(msg.sender);\n\n if (_ZEROamount > 0) {\n uint256 ZEROToWithdraw = LiquityMath._min(_ZEROamount, currentStake);\n\n uint256 newStake = currentStake.sub(ZEROToWithdraw);\n\n // Decrease user's stake and total ZERO staked\n stakes[msg.sender] = newStake;\n totalZEROStaked = totalZEROStaked.sub(ZEROToWithdraw);\n emit TotalZEROStakedUpdated(totalZEROStaked);\n\n // Transfer unstaked ZERO to user\n require(\n zeroToken.transfer(msg.sender, ZEROToWithdraw),\n \"Couldn't execute ZUSD transfer\"\n );\n\n emit StakeChanged(msg.sender, newStake);\n }\n\n emit StakingGainsWithdrawn(msg.sender, ZUSDGain, ETHGain);\n\n // Send accumulated ZUSD and ETH gains to the caller\n require(zusdToken.transfer(msg.sender, ZUSDGain), \"Couldn't execute ZUSD transfer\");\n _sendETHGainToUser(ETHGain);\n }\n\n // --- Reward-per-unit-staked increase functions. Called by Zero core contracts ---\n\n function increaseF_ETH(uint256 _ETHFee) external override {\n _requireCallerIsFeeDistributor();\n uint256 ETHFeePerZEROStaked;\n\n if (totalZEROStaked > 0) {\n ETHFeePerZEROStaked = _ETHFee.mul(DECIMAL_PRECISION).div(totalZEROStaked);\n }\n\n F_ETH = F_ETH.add(ETHFeePerZEROStaked);\n emit F_ETHUpdated(F_ETH);\n }\n\n function increaseF_ZUSD(uint256 _ZUSDFee) external override {\n _requireCallerIsFeeDistributor();\n uint256 ZUSDFeePerZEROStaked;\n\n if (totalZEROStaked > 0) {\n ZUSDFeePerZEROStaked = _ZUSDFee.mul(DECIMAL_PRECISION).div(totalZEROStaked);\n }\n\n F_ZUSD = F_ZUSD.add(ZUSDFeePerZEROStaked);\n emit F_ZUSDUpdated(F_ZUSD);\n }\n\n // --- Pending reward functions ---\n\n function getPendingETHGain(address _user) external view override returns (uint256) {\n return _getPendingETHGain(_user);\n }\n\n function _getPendingETHGain(address _user) internal view returns (uint256) {\n uint256 F_ETH_Snapshot = snapshots[_user].F_ETH_Snapshot;\n uint256 ETHGain = stakes[_user].mul(F_ETH.sub(F_ETH_Snapshot)).div(DECIMAL_PRECISION);\n return ETHGain;\n }\n\n function getPendingZUSDGain(address _user) external view override returns (uint256) {\n return _getPendingZUSDGain(_user);\n }\n\n function _getPendingZUSDGain(address _user) internal view returns (uint256) {\n uint256 F_ZUSD_Snapshot = snapshots[_user].F_ZUSD_Snapshot;\n uint256 ZUSDGain = stakes[_user].mul(F_ZUSD.sub(F_ZUSD_Snapshot)).div(DECIMAL_PRECISION);\n return ZUSDGain;\n }\n\n // --- Internal helper functions ---\n\n function _updateUserSnapshots(address _user) internal {\n snapshots[_user].F_ETH_Snapshot = F_ETH;\n snapshots[_user].F_ZUSD_Snapshot = F_ZUSD;\n emit StakerSnapshotsUpdated(_user, F_ETH, F_ZUSD);\n }\n\n function _sendETHGainToUser(uint256 ETHGain) internal {\n emit EtherSent(msg.sender, ETHGain);\n (bool success, ) = msg.sender.call{value: ETHGain}(\"\");\n require(success, \"ZEROStaking: Failed to send accumulated ETHGain\");\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsFeeDistributor() internal view {\n require(msg.sender == feeDistributorAddress, \"ZEROStaking: caller is not FeeDistributor\");\n }\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"ZEROStaking: caller is not ActivePool\");\n }\n\n function _requireUserHasStake(uint256 currentStake) internal pure {\n require(currentStake > 0, \"ZEROStaking: User must have a non-zero stake\");\n }\n\n function _requireNonZeroAmount(uint256 _amount) internal pure {\n require(_amount > 0, \"ZEROStaking: Amount must be non-zero\");\n }\n\n receive() external payable {\n _requireCallerIsFeeDistributor();\n }\n}\n" + }, + "contracts/ZERO/ZEROStakingStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Interfaces/IZEROToken.sol\";\nimport \"../Interfaces/IZUSDToken.sol\";\n\ncontract ZEROStakingStorage is Ownable {\n // --- Data ---\n string constant public NAME = \"ZEROStaking\";\n\n mapping( address => uint) public stakes;\n uint public totalZEROStaked;\n\n uint public F_ETH; // Running sum of ETH fees per-ZERO-staked\n uint public F_ZUSD; // Running sum of ZERO fees per-ZERO-staked\n\n // User snapshots of F_ETH and F_ZUSD, taken at the point at which their latest deposit was made\n mapping (address => Snapshot) public snapshots; \n\n struct Snapshot {\n uint F_ETH_Snapshot;\n uint F_ZUSD_Snapshot;\n }\n \n IZEROToken public zeroToken;\n IZUSDToken public zusdToken;\n\n address public feeDistributorAddress;\n address public activePoolAddress;\n\n}\n" + }, + "contracts/ZERO/ZEROToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Interfaces/IZEROToken.sol\";\nimport \"./ZEROTokenStorage.sol\";\n\n/**\n * Based upon OpenZeppelin's ERC20 contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol\n *\n * and their EIP2612 (ERC20Permit / ERC712) functionality:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\n *\n *\n * --- Functionality added specific to the ZEROToken ---\n *\n * 1) Transfer protection: blacklist of addresses that are invalid recipients (i.e. core Zero contracts) in external\n * transfer() and transferFrom() calls. The purpose is to protect users from losing tokens by mistakenly sending ZERO directly to a Zero\n * core contract, when they should rather call the right function.\n *\n * 2) sendToZEROStaking(): callable only by Zero core contracts, which move ZERO tokens from user -> ZEROStaking contract.\n *\n */\n\ncontract ZEROToken is ZEROTokenStorage, CheckContract, IZEROToken {\n using SafeMath for uint256;\n\n // --- Functions ---\n\n function initialize(\n address _zeroStakingAddress,\n address _marketMakerAddress,\n address _presaleAddress\n ) public initializer {\n // checkContract(_marketMakerAddress);\n // checkContract(_presaleAddress);\n\n deploymentStartTime = block.timestamp;\n\n zeroStakingAddress = _zeroStakingAddress;\n marketMakerAddress = _marketMakerAddress;\n presale = IBalanceRedirectPresale(_presaleAddress);\n\n bytes32 hashedName = keccak256(bytes(_NAME));\n bytes32 hashedVersion = keccak256(bytes(_VERSION));\n\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = _chainID();\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(_TYPE_HASH, hashedName, hashedVersion);\n }\n\n // --- External functions ---\n\n /// @notice Generates `amount` tokens that are assigned to `account`\n /// @param account The address that will be assigned the new tokens\n /// @param amount The quantity of tokens generated\n function mint(address account, uint256 amount) external {\n require(\n msg.sender == marketMakerAddress || msg.sender == address(presale),\n \"Invalid caller\"\n );\n _mint(account, amount);\n }\n\n /// @notice Burns `amount` tokens from `account`\n /// @param account The address that will lose the tokens\n /// @param amount The quantity of tokens to burn\n function burn(address account, uint256 amount) external {\n require(msg.sender == marketMakerAddress, \"Invalid caller\");\n _burn(account, amount);\n }\n\n function totalSupply() external view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) external view override returns (uint256) {\n return _balances[account];\n }\n\n function getDeploymentStartTime() external view override returns (uint256) {\n return deploymentStartTime;\n }\n\n function transfer(address recipient, uint256 amount) external override returns (bool) {\n _requireValidRecipient(recipient);\n\n // Otherwise, standard transfer functionality\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) external view override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) external override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external override returns (bool) {\n _requireValidRecipient(recipient);\n\n _transfer(sender, recipient, amount);\n _approve(\n sender,\n msg.sender,\n _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\")\n );\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue)\n external\n override\n returns (bool)\n {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue)\n external\n override\n returns (bool)\n {\n _approve(\n msg.sender,\n spender,\n _allowances[msg.sender][spender].sub(\n subtractedValue,\n \"ERC20: decreased allowance below zero\"\n )\n );\n return true;\n }\n\n function sendToZEROStaking(address _sender, uint256 _amount) external override {\n _requireCallerIsZEROStaking();\n _transfer(_sender, zeroStakingAddress, _amount);\n }\n\n // --- EIP 2612 functionality ---\n\n function domainSeparator() public view override returns (bytes32) {\n if (_chainID() == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external override {\n require(deadline >= now, \"ZERO: expired deadline\");\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n domainSeparator(),\n keccak256(\n abi.encode(_PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner]++, deadline)\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress == owner, \"ZERO: invalid signature\");\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) external view override returns (uint256) {\n // FOR EIP 2612\n return _nonces[owner];\n }\n\n // --- Internal operations ---\n\n function _chainID() private pure returns (uint256 chainID) {\n assembly {\n chainID := chainid()\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 name,\n bytes32 version\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, name, version, _chainID(), address(this)));\n }\n\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal {\n return; // disable the func call - ZEROToken is not used in beta\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n require(presale.isClosed(), \"Presale is not over yet\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account, uint256 amount) internal {\n return; // disable the func call - ZEROToken is not used in beta\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n function _burn(address account, uint256 amount) internal {\n return; // disable the func call - ZEROToken is not used in beta\n require(account != address(0), \"ERC20: mint to the zero address\");\n require(amount <= _balances[account], \"balance too low\");\n\n _totalSupply = _totalSupply.sub(amount);\n _balances[account] = _balances[account].sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n // --- Helper functions ---\n\n // --- 'require' functions ---\n\n function _requireValidRecipient(address _recipient) internal view {\n require(\n _recipient != address(0) && _recipient != address(this),\n \"ZERO: Cannot transfer tokens directly to the ZERO token contract or the zero address\"\n );\n }\n\n function _requireCallerIsZEROStaking() internal view {\n require(\n msg.sender == zeroStakingAddress,\n \"ZEROToken: caller must be the ZEROStaking contract\"\n );\n }\n\n // --- Optional functions ---\n\n function name() external view override returns (string memory) {\n return _NAME;\n }\n\n function symbol() external view override returns (string memory) {\n return _SYMBOL;\n }\n\n function decimals() external view override returns (uint8) {\n return _DECIMALS;\n }\n\n function version() external view override returns (string memory) {\n return _VERSION;\n }\n\n function permitTypeHash() external view override returns (bytes32) {\n return _PERMIT_TYPEHASH;\n }\n}\n" + }, + "contracts/ZERO/ZEROTokenStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IBalanceRedirectPresale.sol\";\nimport \"../Dependencies/Initializable.sol\";\n\ncontract ZEROTokenStorage is Initializable {\n // --- ERC20 Data ---\n\n string constant internal _NAME = \"ZERO\";\n string constant internal _SYMBOL = \"ZERO\";\n string constant internal _VERSION = \"1\";\n uint8 constant internal _DECIMALS = 18;\n\n mapping (address => uint256) internal _balances;\n mapping (address => mapping (address => uint256)) internal _allowances;\n uint internal _totalSupply;\n\n // --- EIP 2612 Data ---\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 internal constant _PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n // keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n bytes32 internal constant _TYPE_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 internal _CACHED_DOMAIN_SEPARATOR;\n uint256 internal _CACHED_CHAIN_ID;\n\n bytes32 internal _HASHED_NAME;\n bytes32 internal _HASHED_VERSION;\n \n mapping (address => uint256) internal _nonces;\n\n // --- ZEROToken specific data ---\n\n uint public constant ONE_YEAR_IN_SECONDS = 31536000; // 60 * 60 * 24 * 365\n\n // uint for use with SafeMath\n uint internal constant _1_MILLION = 1e24; // 1e6 * 1e18 = 1e24\n\n uint internal deploymentStartTime;\n\n address public zeroStakingAddress;\n address public marketMakerAddress;\n IBalanceRedirectPresale public presale;\n\n}\n" + }, + "contracts/ZUSDToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./ZUSDTokenStorage.sol\";\n\n/**\n *\n * Based upon OpenZeppelin's ERC20 contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol\n *\n * and their EIP2612 (ERC20Permit / ERC712) functionality:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\n *\n *\n * --- Functionality added specific to the ZUSDToken ---\n *\n * 1) Transfer protection: blacklist of addresses that are invalid recipients (i.e. core Zero contracts) in external\n * transfer() and transferFrom() calls. The purpose is to protect users from losing tokens by mistakenly sending ZUSD directly to a Zero\n * core contract, when they should rather call the right function.\n *\n * 2) sendToPool() and returnFromPool(): functions callable only Zero core contracts, which move ZUSD tokens between Zero <-> user.\n */\n\ncontract ZUSDToken is ZUSDTokenStorage, CheckContract, IZUSDToken, Ownable {\n using SafeMath for uint256;\n // --- Events ---\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event StabilityPoolAddressChanged(address _newStabilityPoolAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n\n function initialize(\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) public virtual initializer onlyOwner {\n _initialize(_troveManagerAddress, _stabilityPoolAddress, _borrowerOperationsAddress);\n }\n\n function _initialize(\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) internal {\n checkContract(_troveManagerAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_borrowerOperationsAddress);\n\n troveManagerAddress = _troveManagerAddress;\n emit TroveManagerAddressChanged(_troveManagerAddress);\n\n stabilityPoolAddress = _stabilityPoolAddress;\n emit StabilityPoolAddressChanged(_stabilityPoolAddress);\n\n borrowerOperationsAddress = _borrowerOperationsAddress;\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n\n bytes32 hashedName = keccak256(bytes(_NAME));\n bytes32 hashedVersion = keccak256(bytes(_VERSION));\n\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = _chainID();\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(_TYPE_HASH, hashedName, hashedVersion);\n }\n\n // --- Functions for intra-Zero calls ---\n\n function mint(address _account, uint256 _amount) external override {\n _requireCallerIsBorrowerOperations();\n _mint(_account, _amount);\n }\n\n function burn(address _account, uint256 _amount) external override {\n _requireCallerIsBOorTroveMorSP();\n _burn(_account, _amount);\n }\n\n function sendToPool(\n address _sender,\n address _poolAddress,\n uint256 _amount\n ) external override {\n _requireCallerIsStabilityPool();\n _transfer(_sender, _poolAddress, _amount);\n }\n\n function returnFromPool(\n address _poolAddress,\n address _receiver,\n uint256 _amount\n ) external override {\n _requireCallerIsTroveMorSP();\n _transfer(_poolAddress, _receiver, _amount);\n }\n\n // --- External functions ---\n\n function totalSupply() external view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) external view override returns (uint256) {\n return _balances[account];\n }\n\n function transfer(address recipient, uint256 amount) external override returns (bool) {\n _requireValidRecipient(recipient);\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) external view override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) external override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external override returns (bool) {\n _requireValidRecipient(recipient);\n _transfer(sender, recipient, amount);\n _approve(\n sender,\n msg.sender,\n _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\")\n );\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue)\n external\n override\n returns (bool)\n {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue)\n external\n override\n returns (bool)\n {\n _approve(\n msg.sender,\n spender,\n _allowances[msg.sender][spender].sub(\n subtractedValue,\n \"ERC20: decreased allowance below zero\"\n )\n );\n return true;\n }\n\n // --- EIP 2612 Functionality ---\n\n function domainSeparator() public view override returns (bytes32) {\n if (_chainID() == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external override {\n require(deadline >= now, \"ZUSD: expired deadline\");\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n domainSeparator(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n _nonces[owner]++,\n deadline\n )\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress == owner, \"ZUSD: invalid signature\");\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) external view override returns (uint256) {\n // FOR EIP 2612\n return _nonces[owner];\n }\n\n // --- Internal operations ---\n\n function _chainID() private pure returns (uint256 chainID) {\n assembly {\n chainID := chainid()\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 name,\n bytes32 version\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, name, version, _chainID(), address(this)));\n }\n\n // --- Internal operations ---\n // Warning: sanity checks (for sender and recipient) should have been done before calling these internal functions\n\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal {\n assert(sender != address(0));\n assert(recipient != address(0));\n\n _balances[sender] = _balances[sender].sub(\n amount,\n \"ERC20: transfer amount exceeds balance\"\n );\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account, uint256 amount) internal {\n assert(account != address(0));\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n function _burn(address account, uint256 amount) internal {\n assert(account != address(0));\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal {\n assert(owner != address(0));\n assert(spender != address(0));\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n // --- 'require' functions ---\n\n function _requireValidRecipient(address _recipient) internal view {\n require(\n _recipient != address(0) && _recipient != address(this),\n \"ZUSD: Cannot transfer tokens directly to the ZUSD token contract or the zero address\"\n );\n }\n\n function _requireCallerIsBorrowerOperations() internal view {\n require(\n msg.sender == borrowerOperationsAddress,\n \"ZUSDToken: Caller is not BorrowerOperations\"\n );\n }\n\n function _requireCallerIsBOorTroveMorSP() internal view {\n require(\n msg.sender == borrowerOperationsAddress ||\n msg.sender == troveManagerAddress ||\n msg.sender == stabilityPoolAddress,\n \"ZUSD: Caller is neither BorrowerOperations nor TroveManager nor StabilityPool\"\n );\n }\n\n function _requireCallerIsStabilityPool() internal view {\n require(msg.sender == stabilityPoolAddress, \"ZUSD: Caller is not the StabilityPool\");\n }\n\n function _requireCallerIsTroveMorSP() internal view {\n require(\n msg.sender == troveManagerAddress || msg.sender == stabilityPoolAddress,\n \"ZUSD: Caller is neither TroveManager nor StabilityPool\"\n );\n }\n\n // --- Optional functions ---\n\n function name() external view override returns (string memory) {\n return _NAME;\n }\n\n function symbol() external view override returns (string memory) {\n return _SYMBOL;\n }\n\n function decimals() external view override returns (uint8) {\n return _DECIMALS;\n }\n\n function version() external view override returns (string memory) {\n return _VERSION;\n }\n\n function permitTypeHash() external view override returns (bytes32) {\n return _PERMIT_TYPEHASH;\n }\n}\n" + }, + "contracts/ZUSDTokenStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Dependencies/Initializable.sol\";\n\ncontract ZUSDTokenStorage is Initializable {\n uint256 internal _totalSupply;\n string internal constant _NAME = \"ZUSD Stablecoin\";\n string internal constant _SYMBOL = \"ZUSD\";\n string internal constant _VERSION = \"1\";\n uint8 internal constant _DECIMALS = 18;\n\n // --- Data for EIP2612 ---\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 internal constant _PERMIT_TYPEHASH =\n 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n // keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n bytes32 internal constant _TYPE_HASH =\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n // Cache the domain separator, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 internal _CACHED_DOMAIN_SEPARATOR;\n uint256 internal _CACHED_CHAIN_ID;\n\n bytes32 internal _HASHED_NAME;\n bytes32 internal _HASHED_VERSION;\n\n mapping(address => uint256) internal _nonces;\n\n // User data for ZUSD token\n mapping(address => uint256) internal _balances;\n mapping(address => mapping(address => uint256)) internal _allowances;\n\n // --- Addresses ---\n address internal troveManagerAddress;\n address internal stabilityPoolAddress;\n address internal borrowerOperationsAddress;\n}\n" + }, + "hardhat/console.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >= 0.4.22 <0.9.0;\n\nlibrary console {\n\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n\tfunction _sendLogPayload(bytes memory payload) private view {\n\t\tuint256 payloadLength = payload.length;\n\t\taddress consoleAddress = CONSOLE_ADDRESS;\n\t\tassembly {\n\t\t\tlet payloadStart := add(payload, 32)\n\t\t\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n\t\t}\n\t}\n\n\tfunction log() internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log()\"));\n\t}\n\n\tfunction logInt(int256 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n\t}\n\n\tfunction logUint(uint256 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n\t}\n\n\tfunction logString(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction logBool(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction logAddress(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction logBytes(bytes memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n\t}\n\n\tfunction logBytes1(bytes1 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n\t}\n\n\tfunction logBytes2(bytes2 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n\t}\n\n\tfunction logBytes3(bytes3 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n\t}\n\n\tfunction logBytes4(bytes4 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n\t}\n\n\tfunction logBytes5(bytes5 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n\t}\n\n\tfunction logBytes6(bytes6 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n\t}\n\n\tfunction logBytes7(bytes7 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n\t}\n\n\tfunction logBytes8(bytes8 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n\t}\n\n\tfunction logBytes9(bytes9 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n\t}\n\n\tfunction logBytes10(bytes10 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n\t}\n\n\tfunction logBytes11(bytes11 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n\t}\n\n\tfunction logBytes12(bytes12 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n\t}\n\n\tfunction logBytes13(bytes13 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n\t}\n\n\tfunction logBytes14(bytes14 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n\t}\n\n\tfunction logBytes15(bytes15 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n\t}\n\n\tfunction logBytes16(bytes16 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n\t}\n\n\tfunction logBytes17(bytes17 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n\t}\n\n\tfunction logBytes18(bytes18 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n\t}\n\n\tfunction logBytes19(bytes19 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n\t}\n\n\tfunction logBytes20(bytes20 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n\t}\n\n\tfunction logBytes21(bytes21 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n\t}\n\n\tfunction logBytes22(bytes22 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n\t}\n\n\tfunction logBytes23(bytes23 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n\t}\n\n\tfunction logBytes24(bytes24 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n\t}\n\n\tfunction logBytes25(bytes25 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n\t}\n\n\tfunction logBytes26(bytes26 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n\t}\n\n\tfunction logBytes27(bytes27 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n\t}\n\n\tfunction logBytes28(bytes28 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n\t}\n\n\tfunction logBytes29(bytes29 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n\t}\n\n\tfunction logBytes30(bytes30 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n\t}\n\n\tfunction logBytes31(bytes31 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n\t}\n\n\tfunction logBytes32(bytes32 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n\t}\n\n\tfunction log(uint256 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n\t}\n\n\tfunction log(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction log(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction log(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n\t}\n\n\tfunction log(address p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256)\", p0, p1));\n\t}\n\n\tfunction log(address p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n\t}\n\n\tfunction log(address p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n\t}\n\n\tfunction log(address p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/be36e640ecbdc455165550d36df9feff.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/be36e640ecbdc455165550d36df9feff.json new file mode 100644 index 00000000..52d4afe5 --- /dev/null +++ b/packages/contracts/deployment/deployments/rskSovrynTestnet/solcInputs/be36e640ecbdc455165550d36df9feff.json @@ -0,0 +1,376 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n // Check the signature length\n if (signature.length != 65) {\n revert(\"ECDSA: invalid signature length\");\n }\n\n // Divide the signature in r, s and v variables\n bytes32 r;\n bytes32 s;\n uint8 v;\n\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n\n return recover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover-bytes32-bytes-} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, \"ECDSA: invalid signature 's' value\");\n require(v == 27 || v == 28, \"ECDSA: invalid signature 'v' value\");\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n require(signer != address(0), \"ECDSA: invalid signature\");\n\n return signer;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * replicates the behavior of the\n * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]\n * JSON-RPC method.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n}\n" + }, + "@openzeppelin/contracts/drafts/EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) internal {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = _getChainId();\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view virtual returns (bytes32) {\n if (_getChainId() == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(bytes32 typeHash, bytes32 name, bytes32 version) private view returns (bytes32) {\n return keccak256(\n abi.encode(\n typeHash,\n name,\n version,\n _getChainId(),\n address(this)\n )\n );\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", _domainSeparatorV4(), structHash));\n }\n\n function _getChainId() private view returns (uint256 chainId) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n // solhint-disable-next-line no-inline-assembly\n assembly {\n chainId := chainid()\n }\n }\n}\n" + }, + "@openzeppelin/contracts/drafts/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.5 <0.8.0;\n\nimport \"../token/ERC20/ERC20.sol\";\nimport \"./IERC20Permit.sol\";\nimport \"../cryptography/ECDSA.sol\";\nimport \"../utils/Counters.sol\";\nimport \"./EIP712.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping (address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private immutable _PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) internal EIP712(name, \"1\") {\n }\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\n // solhint-disable-next-line not-rely-on-time\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n _nonces[owner].current(),\n deadline\n )\n );\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _nonces[owner].increment();\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n}\n" + }, + "@openzeppelin/contracts/drafts/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens,\n * given `owner`'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for `permit`, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a, \"SafeMath: subtraction overflow\");\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: modulo by zero\");\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name_, string memory symbol_) public {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n * called.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../math/SafeMath.sol\";\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\n * directly accessed.\n */\nlibrary Counters {\n using SafeMath for uint256;\n\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n" + }, + "contracts/ActivePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IActivePool.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\n\nimport \"./ActivePoolStorage.sol\";\n\n/**\n * @title Active Pool\n * @notice The Active Pool holds the ETH collateral and ZUSD debt (but not ZUSD tokens) for all active troves.\n *\n * When a trove is liquidated, it's ETH and ZUSD debt are transferred from the Active Pool, to either the\n * Stability Pool, the Default Pool, or both, depending on the liquidation conditions.\n */\ncontract ActivePool is CheckContract, IActivePool, ActivePoolStorage {\n using SafeMath for uint256;\n // --- Events ---\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolZUSDDebtUpdated(uint256 _ZUSDDebt);\n event ActivePoolETHBalanceUpdated(uint256 _ETH);\n\n // --- Contract setters ---\n /// @notice initializer function that sets required addresses\n /// @dev Checks addresses are contracts. Only callable by contract owner.\n /// @param _borrowerOperationsAddress BorrowerOperations contract address\n /// @param _troveManagerAddress TroveManager contract address\n /// @param _stabilityPoolAddress StabilityPool contract address\n /// @param _defaultPoolAddress DefaultPool contract address\n function setAddresses(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _defaultPoolAddress\n ) external onlyOwner {\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_defaultPoolAddress);\n\n borrowerOperationsAddress = _borrowerOperationsAddress;\n troveManagerAddress = _troveManagerAddress;\n stabilityPoolAddress = _stabilityPoolAddress;\n defaultPoolAddress = _defaultPoolAddress;\n\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit StabilityPoolAddressChanged(_stabilityPoolAddress);\n emit DefaultPoolAddressChanged(_defaultPoolAddress);\n }\n\n // --- Getters for public variables. Required by IPool interface ---\n\n /// @notice Not necessarily equal to the the contract's raw ETH balance - ether can be forcibly sent to contracts.\n /// @return the ETH state variable.\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n /// @return the ZUSD debt state variable\n function getZUSDDebt() external view override returns (uint256) {\n return ZUSDDebt;\n }\n\n // --- Pool functionality ---\n\n /// @notice Send ETH amount to given account. Updates ActivePool balance. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _account account to receive the ETH amount\n /// @param _amount ETH amount to send\n function sendETH(address _account, uint256 _amount) external override {\n _requireCallerIsBOorTroveMorSP();\n ETH = ETH.sub(_amount);\n emit ActivePoolETHBalanceUpdated(ETH);\n emit EtherSent(_account, _amount);\n\n (bool success, ) = _account.call{ value: _amount }(\"\");\n require(success, \"ActivePool: sending ETH failed\");\n }\n\n /// @notice Increases ZUSD debt of the active pool. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _amount ZUSD amount to add to the pool debt\n function increaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsBOorTroveM();\n ZUSDDebt = ZUSDDebt.add(_amount);\n ActivePoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n /// @notice Decreases ZUSD debt of the active pool. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _amount ZUSD amount to sub to the pool debt\n function decreaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsBOorTroveMorSP();\n ZUSDDebt = ZUSDDebt.sub(_amount);\n ActivePoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsBorrowerOperationsOrDefaultPool() internal view {\n require(\n msg.sender == borrowerOperationsAddress || msg.sender == defaultPoolAddress,\n \"ActivePool: Caller is neither BO nor Default Pool\"\n );\n }\n\n function _requireCallerIsBOorTroveMorSP() internal view {\n require(\n msg.sender == borrowerOperationsAddress ||\n msg.sender == troveManagerAddress ||\n msg.sender == stabilityPoolAddress,\n \"ActivePool: Caller is neither BorrowerOperations nor TroveManager nor StabilityPool\"\n );\n }\n\n function _requireCallerIsBOorTroveM() internal view {\n require(\n msg.sender == borrowerOperationsAddress || msg.sender == troveManagerAddress,\n \"ActivePool: Caller is neither BorrowerOperations nor TroveManager\"\n );\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsBorrowerOperationsOrDefaultPool();\n ETH = ETH.add(msg.value);\n emit ActivePoolETHBalanceUpdated(ETH);\n }\n}\n" + }, + "contracts/ActivePoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Dependencies/Ownable.sol\";\n\n/**\n * @title Active Pool Storage\n * @dev Stores Active Pool required addresses and internal ETH and ZUSD debt states\n * Extends Ownable\n */\ncontract ActivePoolStorage is Ownable {\n string public constant NAME = \"ActivePool\";\n\n address public borrowerOperationsAddress;\n address public troveManagerAddress;\n address public stabilityPoolAddress;\n address public defaultPoolAddress;\n uint256 internal ETH; // deposited ether tracker\n uint256 internal ZUSDDebt;\n}\n" + }, + "contracts/BorrowerOperations.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./BorrowerOperationsStorage.sol\";\nimport \"./Dependencies/Mynt/MyntLib.sol\";\n\ncontract BorrowerOperations is\n LiquityBase,\n BorrowerOperationsStorage,\n CheckContract,\n IBorrowerOperations\n{\n /* --- Variable container structs ---\n\n Used to hold, return and assign variables inside a function, in order to avoid the error:\n \"CompilerError: Stack too deep\". */\n\n struct LocalVariables_adjustTrove {\n uint256 price;\n uint256 collChange;\n uint256 netDebtChange;\n bool isCollIncrease;\n uint256 debt;\n uint256 coll;\n uint256 oldICR;\n uint256 newICR;\n uint256 newTCR;\n uint256 ZUSDFee;\n uint256 newDebt;\n uint256 newColl;\n uint256 stake;\n uint256 newNICR;\n bool isRecoveryMode;\n }\n\n struct LocalVariables_openTrove {\n uint256 price;\n uint256 ZUSDFee;\n uint256 netDebt;\n uint256 compositeDebt;\n uint256 ICR;\n uint256 NICR;\n uint256 stake;\n uint256 arrayIndex;\n }\n\n struct ContractsCache {\n ITroveManager troveManager;\n IActivePool activePool;\n IZUSDToken zusdToken;\n }\n\n enum BorrowerOperation {\n openTrove,\n closeTrove,\n adjustTrove\n }\n\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n event MassetManagerAddressChanged(address _massetManagerAddress);\n\n event TroveCreated(address indexed _borrower, uint256 arrayIndex);\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 stake,\n BorrowerOperation operation\n );\n event ZUSDBorrowingFeePaid(address indexed _borrower, uint256 _ZUSDFee);\n\n // --- Dependency setters ---\n\n function setAddresses(\n address _feeDistributorAddress,\n address _liquityBaseParamsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _defaultPoolAddress,\n address _stabilityPoolAddress,\n address _gasPoolAddress,\n address _collSurplusPoolAddress,\n address _priceFeedAddress,\n address _sortedTrovesAddress,\n address _zusdTokenAddress,\n address _zeroStakingAddress\n ) external override onlyOwner {\n // This makes impossible to open a trove with zero withdrawn ZUSD\n assert(MIN_NET_DEBT > 0);\n\n checkContract(_feeDistributorAddress);\n checkContract(_liquityBaseParamsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n checkContract(_defaultPoolAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_gasPoolAddress);\n checkContract(_collSurplusPoolAddress);\n checkContract(_priceFeedAddress);\n checkContract(_sortedTrovesAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_zeroStakingAddress);\n\n feeDistributor = IFeeDistributor(_feeDistributorAddress);\n liquityBaseParams = ILiquityBaseParams(_liquityBaseParamsAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n activePool = IActivePool(_activePoolAddress);\n defaultPool = IDefaultPool(_defaultPoolAddress);\n stabilityPoolAddress = _stabilityPoolAddress;\n gasPoolAddress = _gasPoolAddress;\n collSurplusPool = ICollSurplusPool(_collSurplusPoolAddress);\n priceFeed = IPriceFeed(_priceFeedAddress);\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n zeroStakingAddress = _zeroStakingAddress;\n zeroStaking = IZEROStaking(_zeroStakingAddress);\n\n emit FeeDistributorAddressChanged(_feeDistributorAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n emit DefaultPoolAddressChanged(_defaultPoolAddress);\n emit StabilityPoolAddressChanged(_stabilityPoolAddress);\n emit GasPoolAddressChanged(_gasPoolAddress);\n emit CollSurplusPoolAddressChanged(_collSurplusPoolAddress);\n emit PriceFeedAddressChanged(_priceFeedAddress);\n emit SortedTrovesAddressChanged(_sortedTrovesAddress);\n emit ZUSDTokenAddressChanged(_zusdTokenAddress);\n emit ZEROStakingAddressChanged(_zeroStakingAddress);\n }\n\n function setMassetManagerAddress(address _massetManagerAddress) external onlyOwner {\n massetManager = IMassetManager(_massetManagerAddress);\n emit MassetManagerAddressChanged(_massetManagerAddress);\n }\n\n function openTrove(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n _openTrove(_maxFeePercentage, _ZUSDAmount, _upperHint, _lowerHint, msg.sender);\n }\n\n function openNueTrove(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n require(address(massetManager) != address(0), \"Masset address not set\");\n\n _openTrove(_maxFeePercentage, _ZUSDAmount, _upperHint, _lowerHint, address(this));\n require(\n zusdToken.approve(address(massetManager), _ZUSDAmount),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n massetManager.mintTo(address(zusdToken), _ZUSDAmount, msg.sender);\n }\n\n // --- Borrower Trove Operations ---\n function _openTrove(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint,\n address _tokensRecipient\n ) internal {\n ContractsCache memory contractsCache = ContractsCache(troveManager, activePool, zusdToken);\n LocalVariables_openTrove memory vars;\n\n vars.price = priceFeed.fetchPrice();\n bool isRecoveryMode = _checkRecoveryMode(vars.price);\n\n _requireValidMaxFeePercentage(_maxFeePercentage, isRecoveryMode);\n _requireTroveisNotActive(contractsCache.troveManager, msg.sender);\n\n vars.ZUSDFee;\n vars.netDebt = _ZUSDAmount;\n\n if (!isRecoveryMode) {\n vars.ZUSDFee = _triggerBorrowingFee(\n contractsCache.troveManager,\n contractsCache.zusdToken,\n _ZUSDAmount,\n _maxFeePercentage\n );\n vars.netDebt = vars.netDebt.add(vars.ZUSDFee);\n }\n _requireAtLeastMinNetDebt(vars.netDebt);\n\n // ICR is based on the composite debt, i.e. the requested ZUSD amount + ZUSD borrowing fee + ZUSD gas comp.\n vars.compositeDebt = _getCompositeDebt(vars.netDebt);\n assert(vars.compositeDebt > 0);\n\n vars.ICR = LiquityMath._computeCR(msg.value, vars.compositeDebt, vars.price);\n vars.NICR = LiquityMath._computeNominalCR(msg.value, vars.compositeDebt);\n\n if (isRecoveryMode) {\n _requireICRisAboveCCR(vars.ICR);\n } else {\n _requireICRisAboveMCR(vars.ICR);\n uint256 newTCR = _getNewTCRFromTroveChange(\n msg.value,\n true,\n vars.compositeDebt,\n true,\n vars.price\n ); // bools: coll increase, debt increase\n _requireNewTCRisAboveCCR(newTCR);\n }\n\n // Set the trove struct's properties\n contractsCache.troveManager.setTroveStatus(msg.sender, 1);\n contractsCache.troveManager.increaseTroveColl(msg.sender, msg.value);\n contractsCache.troveManager.increaseTroveDebt(msg.sender, vars.compositeDebt);\n\n contractsCache.troveManager.updateTroveRewardSnapshots(msg.sender);\n vars.stake = contractsCache.troveManager.updateStakeAndTotalStakes(msg.sender);\n\n sortedTroves.insert(msg.sender, vars.NICR, _upperHint, _lowerHint);\n vars.arrayIndex = contractsCache.troveManager.addTroveOwnerToArray(msg.sender);\n emit TroveCreated(msg.sender, vars.arrayIndex);\n\n // Move the ether to the Active Pool, and mint the ZUSDAmount to the borrower\n _activePoolAddColl(contractsCache.activePool, msg.value);\n _mintZusdAndIncreaseActivePoolDebt(\n contractsCache.activePool,\n contractsCache.zusdToken,\n _tokensRecipient,\n _ZUSDAmount,\n vars.netDebt\n );\n // Move the ZUSD gas compensation to the Gas Pool\n _mintZusdAndIncreaseActivePoolDebt(\n contractsCache.activePool,\n contractsCache.zusdToken,\n gasPoolAddress,\n ZUSD_GAS_COMPENSATION,\n ZUSD_GAS_COMPENSATION\n );\n\n emit TroveUpdated(\n msg.sender,\n vars.compositeDebt,\n msg.value,\n vars.stake,\n BorrowerOperation.openTrove\n );\n emit ZUSDBorrowingFeePaid(msg.sender, vars.ZUSDFee);\n }\n\n /// Send ETH as collateral to a trove\n function addColl(address _upperHint, address _lowerHint) external payable override {\n _adjustTrove(msg.sender, 0, 0, false, _upperHint, _lowerHint, 0);\n }\n\n /// Send ETH as collateral to a trove. Called by only the Stability Pool.\n function moveETHGainToTrove(\n address _borrower,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n _requireCallerIsStabilityPool();\n _adjustTrove(_borrower, 0, 0, false, _upperHint, _lowerHint, 0);\n }\n\n /// Withdraw ETH collateral from a trove\n function withdrawColl(\n uint256 _collWithdrawal,\n address _upperHint,\n address _lowerHint\n ) external override {\n _adjustTrove(msg.sender, _collWithdrawal, 0, false, _upperHint, _lowerHint, 0);\n }\n\n /// Withdraw ZUSD tokens from a trove: mint new ZUSD tokens to the owner, and increase the trove's debt accordingly\n function withdrawZUSD(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external override {\n _adjustTrove(msg.sender, 0, _ZUSDAmount, true, _upperHint, _lowerHint, _maxFeePercentage);\n }\n\n /// Borrow (withdraw) ZUSD tokens from a trove: mint new ZUSD tokens to the owner and convert it to DLLR in one transaction\n /// Zero Line of Credit owner can borrow a specified amount of ZUSD and convert it to DLLR via Sovryn Mynt\n ///@return DLLR amount minted\n function withdrawZusdAndConvertToDLLR(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external override returns (uint256) {\n address thisAddress = address(this);\n uint256 balanceBefore = zusdToken.balanceOf(thisAddress);\n\n _withdrawZusdTo(\n msg.sender,\n thisAddress,\n _ZUSDAmount,\n _upperHint,\n _lowerHint,\n _maxFeePercentage\n );\n\n require(\n zusdToken.balanceOf(thisAddress) == balanceBefore.add(_ZUSDAmount),\n \"ZUSD is not borrowed correctly\"\n );\n require(\n zusdToken.approve(address(massetManager), _ZUSDAmount),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n return massetManager.mintTo(address(zusdToken), _ZUSDAmount, msg.sender);\n }\n\n /// Repay ZUSD tokens to a Trove: Burn the repaid ZUSD tokens, and reduce the trove's debt accordingly\n function repayZUSD(\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external override {\n _adjustTrove(msg.sender, 0, _ZUSDAmount, false, _upperHint, _lowerHint, 0);\n }\n\n /// Repay ZUSD tokens to a Trove by DLLR: convert DLLR to ZUSD tokens, and then reduce the trove's debt accordingly\n function repayZusdFromDLLR(\n uint256 _dllrAmount,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external override {\n _adjustNueTrove(0, 0, _dllrAmount, false, _upperHint, _lowerHint, _permitParams);\n }\n\n function adjustTrove(\n uint256 _maxFeePercentage,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint\n ) external payable override {\n _adjustTrove(\n msg.sender,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFeePercentage\n );\n }\n\n // in case of _isDebtIncrease = false MassetManager contract must have an approval of NUE tokens\n function adjustNueTrove(\n uint256 _maxFeePercentage,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external payable override {\n _adjustNueTrove(\n _maxFeePercentage,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _permitParams\n );\n }\n\n // in case of _isDebtIncrease = false Masset Manager contract must have an approval of NUE tokens\n function _adjustNueTrove(\n uint256 _maxFeePercentage,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) internal {\n require(address(massetManager) != address(0), \"Masset address not set\");\n\n if (!_isDebtIncrease && _ZUSDChange > 0) {\n MyntLib.redeemZusdFromDllrWithPermit(\n massetManager,\n _ZUSDChange,\n address(zusdToken),\n _permitParams\n );\n }\n _adjustSenderTrove(\n msg.sender,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFeePercentage,\n address(this)\n );\n if (_isDebtIncrease && _ZUSDChange > 0) {\n require(\n zusdToken.approve(address(massetManager), _ZUSDChange),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n massetManager.mintTo(address(zusdToken), _ZUSDChange, msg.sender);\n }\n }\n\n function _adjustTrove(\n address _borrower,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n uint256 _maxFeePercentage\n ) internal {\n _adjustSenderTrove(\n _borrower,\n _collWithdrawal,\n _ZUSDChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFeePercentage,\n msg.sender\n );\n }\n\n // _withdrawZusd: _adjustTrove(msg.sender, 0, _ZUSDAmount, true, _upperHint, _lowerHint, _maxFeePercentage);\n function _withdrawZusdTo(\n address _borrower,\n address _receiver,\n uint256 _ZUSDChange,\n address _upperHint,\n address _lowerHint,\n uint256 _maxFeePercentage\n ) internal {\n _adjustSenderTrove(\n _borrower,\n 0,\n _ZUSDChange,\n true,\n _upperHint,\n _lowerHint,\n _maxFeePercentage,\n _receiver\n );\n }\n\n /**\n * _adjustSenderTrove(): Alongside a debt change, this function can perform either a collateral top-up or a collateral withdrawal.\n *\n * It therefore expects either a positive msg.value, or a positive _collWithdrawal argument.\n *\n * If both are positive, it will revert.\n */\n function _adjustSenderTrove(\n address _borrower,\n uint256 _collWithdrawal,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n uint256 _maxFeePercentage,\n address _tokensRecipient\n ) internal {\n ContractsCache memory contractsCache = ContractsCache(troveManager, activePool, zusdToken);\n LocalVariables_adjustTrove memory vars;\n\n vars.price = priceFeed.fetchPrice();\n vars.isRecoveryMode = _checkRecoveryMode(vars.price);\n\n if (_isDebtIncrease) {\n _requireValidMaxFeePercentage(_maxFeePercentage, vars.isRecoveryMode);\n _requireNonZeroDebtChange(_ZUSDChange);\n }\n _requireSingularCollChange(_collWithdrawal);\n _requireNonZeroAdjustment(_collWithdrawal, _ZUSDChange);\n _requireTroveisActive(contractsCache.troveManager, _borrower);\n\n // Confirm the operation is either a borrower adjusting their own trove, or a pure ETH transfer from the Stability Pool to a trove\n assert(\n msg.sender == _borrower ||\n (msg.sender == stabilityPoolAddress && msg.value > 0 && _ZUSDChange == 0)\n );\n\n contractsCache.troveManager.applyPendingRewards(_borrower);\n\n // Get the collChange based on whether or not ETH was sent in the transaction\n (vars.collChange, vars.isCollIncrease) = _getCollChange(msg.value, _collWithdrawal);\n\n vars.netDebtChange = _ZUSDChange;\n\n // If the adjustment incorporates a debt increase and system is in Normal Mode, then trigger a borrowing fee\n if (_isDebtIncrease && !vars.isRecoveryMode) {\n vars.ZUSDFee = _triggerBorrowingFee(\n contractsCache.troveManager,\n contractsCache.zusdToken,\n _ZUSDChange,\n _maxFeePercentage\n );\n vars.netDebtChange = vars.netDebtChange.add(vars.ZUSDFee); // The raw debt change includes the fee\n }\n\n vars.debt = contractsCache.troveManager.getTroveDebt(_borrower);\n vars.coll = contractsCache.troveManager.getTroveColl(_borrower);\n\n // Get the trove's old ICR before the adjustment, and what its new ICR will be after the adjustment\n vars.oldICR = LiquityMath._computeCR(vars.coll, vars.debt, vars.price);\n vars.newICR = _getNewICRFromTroveChange(\n vars.coll,\n vars.debt,\n vars.collChange,\n vars.isCollIncrease,\n vars.netDebtChange,\n _isDebtIncrease,\n vars.price\n );\n assert(_collWithdrawal <= vars.coll);\n\n // Check the adjustment satisfies all conditions for the current system mode\n _requireValidAdjustmentInCurrentMode(\n vars.isRecoveryMode,\n _collWithdrawal,\n _isDebtIncrease,\n vars\n );\n\n // When the adjustment is a debt repayment, check it's a valid amount and that the caller has enough ZUSD\n if (!_isDebtIncrease && _ZUSDChange > 0) {\n _requireAtLeastMinNetDebt(_getNetDebt(vars.debt).sub(vars.netDebtChange));\n _requireValidZUSDRepayment(vars.debt, vars.netDebtChange);\n _requireSufficientZUSDBalance(contractsCache.zusdToken, _borrower, vars.netDebtChange);\n }\n\n (vars.newColl, vars.newDebt) = _updateTroveFromAdjustment(\n contractsCache.troveManager,\n _borrower,\n vars.collChange,\n vars.isCollIncrease,\n vars.netDebtChange,\n _isDebtIncrease\n );\n vars.stake = contractsCache.troveManager.updateStakeAndTotalStakes(_borrower);\n\n // Re-insert trove in to the sorted list\n vars.newNICR = _getNewNominalICRFromTroveChange(\n vars.coll,\n vars.debt,\n vars.collChange,\n vars.isCollIncrease,\n vars.netDebtChange,\n _isDebtIncrease\n );\n sortedTroves.reInsert(_borrower, vars.newNICR, _upperHint, _lowerHint);\n\n emit TroveUpdated(\n _borrower,\n vars.newDebt,\n vars.newColl,\n vars.stake,\n BorrowerOperation.adjustTrove\n );\n emit ZUSDBorrowingFeePaid(msg.sender, vars.ZUSDFee);\n\n // Use the unmodified _ZUSDChange here, as we don't send the fee to the user\n _moveTokensAndETHfromAdjustment(\n contractsCache.activePool,\n contractsCache.zusdToken,\n msg.sender,\n vars.collChange,\n vars.isCollIncrease,\n _ZUSDChange,\n _isDebtIncrease,\n vars.netDebtChange,\n _tokensRecipient\n );\n }\n\n function closeTrove() external override {\n _closeTrove();\n }\n\n function closeNueTrove(IMassetManager.PermitParams calldata _permitParams) external override {\n require(address(massetManager) != address(0), \"Masset address not set\");\n\n uint256 debt = troveManager.getTroveDebt(msg.sender);\n\n MyntLib.redeemZusdFromDllrWithPermit(\n massetManager,\n debt.sub(ZUSD_GAS_COMPENSATION),\n address(zusdToken),\n _permitParams\n );\n _closeTrove();\n }\n\n function _closeTrove() internal {\n ITroveManager troveManagerCached = troveManager;\n IActivePool activePoolCached = activePool;\n IZUSDToken zusdTokenCached = zusdToken;\n\n _requireTroveisActive(troveManagerCached, msg.sender);\n uint256 price = priceFeed.fetchPrice();\n _requireNotInRecoveryMode(price);\n\n troveManagerCached.applyPendingRewards(msg.sender);\n\n uint256 coll = troveManagerCached.getTroveColl(msg.sender);\n uint256 debt = troveManagerCached.getTroveDebt(msg.sender);\n\n _requireSufficientZUSDBalance(\n zusdTokenCached,\n msg.sender,\n debt.sub(ZUSD_GAS_COMPENSATION)\n );\n\n uint256 newTCR = _getNewTCRFromTroveChange(coll, false, debt, false, price);\n _requireNewTCRisAboveCCR(newTCR);\n\n troveManagerCached.removeStake(msg.sender);\n troveManagerCached.closeTrove(msg.sender);\n\n emit TroveUpdated(msg.sender, 0, 0, 0, BorrowerOperation.closeTrove);\n\n // Burn the repaid ZUSD from the user's balance and the gas compensation from the Gas Pool\n _burnZusdAndDecreaseActivePoolDebt(\n activePoolCached,\n zusdTokenCached,\n msg.sender,\n debt.sub(ZUSD_GAS_COMPENSATION)\n );\n _burnZusdAndDecreaseActivePoolDebt(\n activePoolCached,\n zusdTokenCached,\n gasPoolAddress,\n ZUSD_GAS_COMPENSATION\n );\n\n // Send the collateral back to the user\n activePoolCached.sendETH(msg.sender, coll);\n }\n\n /**\n * Claim remaining collateral from a redemption or from a liquidation with ICR > MCR in Recovery Mode\n */\n function claimCollateral() external override {\n // send ETH from CollSurplus Pool to owner\n collSurplusPool.claimColl(msg.sender);\n }\n\n // --- Helper functions ---\n\n function _triggerBorrowingFee(\n ITroveManager _troveManager,\n IZUSDToken _zusdToken,\n uint256 _ZUSDAmount,\n uint256 _maxFeePercentage\n ) internal returns (uint256) {\n _troveManager.decayBaseRateFromBorrowing(); // decay the baseRate state variable\n uint256 ZUSDFee = _troveManager.getBorrowingFee(_ZUSDAmount);\n\n _requireUserAcceptsFee(ZUSDFee, _ZUSDAmount, _maxFeePercentage);\n _zusdToken.mint(address(feeDistributor), ZUSDFee);\n feeDistributor.distributeFees();\n\n return ZUSDFee;\n }\n\n function _getUSDValue(uint256 _coll, uint256 _price) internal pure returns (uint256) {\n uint256 usdValue = _price.mul(_coll).div(DECIMAL_PRECISION);\n\n return usdValue;\n }\n\n function _getCollChange(uint256 _collReceived, uint256 _requestedCollWithdrawal)\n internal\n pure\n returns (uint256 collChange, bool isCollIncrease)\n {\n if (_collReceived != 0) {\n collChange = _collReceived;\n isCollIncrease = true;\n } else {\n collChange = _requestedCollWithdrawal;\n }\n }\n\n /// Update trove's coll and debt based on whether they increase or decrease\n function _updateTroveFromAdjustment(\n ITroveManager _troveManager,\n address _borrower,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease\n ) internal returns (uint256, uint256) {\n uint256 newColl = (_isCollIncrease)\n ? _troveManager.increaseTroveColl(_borrower, _collChange)\n : _troveManager.decreaseTroveColl(_borrower, _collChange);\n uint256 newDebt = (_isDebtIncrease)\n ? _troveManager.increaseTroveDebt(_borrower, _debtChange)\n : _troveManager.decreaseTroveDebt(_borrower, _debtChange);\n\n return (newColl, newDebt);\n }\n\n function _moveTokensAndETHfromAdjustment(\n IActivePool _activePool,\n IZUSDToken _zusdToken,\n address _borrower,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _ZUSDChange,\n bool _isDebtIncrease,\n uint256 _netDebtChange,\n address _tokensRecipient\n ) internal {\n if (_isDebtIncrease) {\n _mintZusdAndIncreaseActivePoolDebt(\n _activePool,\n _zusdToken,\n _tokensRecipient,\n _ZUSDChange,\n _netDebtChange\n );\n } else {\n _burnZusdAndDecreaseActivePoolDebt(_activePool, _zusdToken, _borrower, _ZUSDChange);\n }\n\n if (_isCollIncrease) {\n _activePoolAddColl(_activePool, _collChange);\n } else {\n _activePool.sendETH(_borrower, _collChange);\n }\n }\n\n /// Send ETH to Active Pool and increase its recorded ETH balance\n function _activePoolAddColl(IActivePool _activePool, uint256 _amount) internal {\n (bool success, ) = address(_activePool).call{ value: _amount }(\"\");\n require(success, \"BorrowerOps: Sending ETH to ActivePool failed\");\n }\n\n /// Issue the specified amount of ZUSD to _account and increases the total active debt (_netDebtIncrease potentially includes a ZUSDFee)\n function _mintZusdAndIncreaseActivePoolDebt(\n IActivePool _activePool,\n IZUSDToken _zusdToken,\n address _account,\n uint256 _ZUSDAmount,\n uint256 _netDebtIncrease\n ) internal {\n _activePool.increaseZUSDDebt(_netDebtIncrease);\n _zusdToken.mint(_account, _ZUSDAmount);\n }\n\n /// Burn the specified amount of ZUSD from _account and decreases the total active debt\n function _burnZusdAndDecreaseActivePoolDebt(\n IActivePool _activePool,\n IZUSDToken _zusdToken,\n address _account,\n uint256 _ZUSD\n ) internal {\n _activePool.decreaseZUSDDebt(_ZUSD);\n _zusdToken.burn(_account, _ZUSD);\n }\n\n // --- 'Require' wrapper functions ---\n\n function _requireSingularCollChange(uint256 _collWithdrawal) internal view {\n require(\n msg.value == 0 || _collWithdrawal == 0,\n \"BorrowerOperations: Cannot withdraw and add coll\"\n );\n }\n\n function _requireCallerIsBorrower(address _borrower) internal view {\n require(\n msg.sender == _borrower,\n \"BorrowerOps: Caller must be the borrower for a withdrawal\"\n );\n }\n\n function _requireNonZeroAdjustment(uint256 _collWithdrawal, uint256 _ZUSDChange)\n internal\n view\n {\n require(\n msg.value != 0 || _collWithdrawal != 0 || _ZUSDChange != 0,\n \"BorrowerOps: There must be either a collateral change or a debt change\"\n );\n }\n\n function _requireTroveisActive(ITroveManager _troveManager, address _borrower) internal view {\n uint256 status = _troveManager.getTroveStatus(_borrower);\n require(status == 1, \"BorrowerOps: Trove does not exist or is closed\");\n }\n\n function _requireTroveisNotActive(ITroveManager _troveManager, address _borrower)\n internal\n view\n {\n uint256 status = _troveManager.getTroveStatus(_borrower);\n require(status != 1, \"BorrowerOps: Trove is active\");\n }\n\n function _requireNonZeroDebtChange(uint256 _ZUSDChange) internal pure {\n require(_ZUSDChange > 0, \"BorrowerOps: Debt increase requires non-zero debtChange\");\n }\n\n function _requireNotInRecoveryMode(uint256 _price) internal view {\n require(\n !_checkRecoveryMode(_price),\n \"BorrowerOps: Operation not permitted during Recovery Mode\"\n );\n }\n\n function _requireNoCollWithdrawal(uint256 _collWithdrawal) internal pure {\n require(\n _collWithdrawal == 0,\n \"BorrowerOps: Collateral withdrawal not permitted Recovery Mode\"\n );\n }\n\n function _requireValidAdjustmentInCurrentMode(\n bool _isRecoveryMode,\n uint256 _collWithdrawal,\n bool _isDebtIncrease,\n LocalVariables_adjustTrove memory _vars\n ) internal view {\n /*\n *In Recovery Mode, only allow:\n *\n * - Pure collateral top-up\n * - Pure debt repayment\n * - Collateral top-up with debt repayment\n * - A debt increase combined with a collateral top-up which makes the ICR >= 150% and improves the ICR (and by extension improves the TCR).\n *\n * In Normal Mode, ensure:\n *\n * - The new ICR is above MCR\n * - The adjustment won't pull the TCR below CCR\n */\n if (_isRecoveryMode) {\n _requireNoCollWithdrawal(_collWithdrawal);\n if (_isDebtIncrease) {\n _requireICRisAboveCCR(_vars.newICR);\n _requireNewICRisAboveOldICR(_vars.newICR, _vars.oldICR);\n }\n } else {\n // if Normal Mode\n _requireICRisAboveMCR(_vars.newICR);\n _vars.newTCR = _getNewTCRFromTroveChange(\n _vars.collChange,\n _vars.isCollIncrease,\n _vars.netDebtChange,\n _isDebtIncrease,\n _vars.price\n );\n _requireNewTCRisAboveCCR(_vars.newTCR);\n }\n }\n\n function _requireICRisAboveMCR(uint256 _newICR) internal view {\n require(\n _newICR >= liquityBaseParams.MCR(),\n \"BorrowerOps: An operation that would result in ICR < MCR is not permitted\"\n );\n }\n\n function _requireICRisAboveCCR(uint256 _newICR) internal view {\n require(\n _newICR >= liquityBaseParams.CCR(),\n \"BorrowerOps: Operation must leave trove with ICR >= CCR\"\n );\n }\n\n function _requireNewICRisAboveOldICR(uint256 _newICR, uint256 _oldICR) internal pure {\n require(\n _newICR >= _oldICR,\n \"BorrowerOps: Cannot decrease your Trove's ICR in Recovery Mode\"\n );\n }\n\n function _requireNewTCRisAboveCCR(uint256 _newTCR) internal view {\n require(\n _newTCR >= liquityBaseParams.CCR(),\n \"BorrowerOps: An operation that would result in TCR < CCR is not permitted\"\n );\n }\n\n function _requireAtLeastMinNetDebt(uint256 _netDebt) internal pure {\n require(\n _netDebt >= MIN_NET_DEBT,\n \"BorrowerOps: Trove's net debt must be greater than minimum\"\n );\n }\n\n function _requireValidZUSDRepayment(uint256 _currentDebt, uint256 _debtRepayment)\n internal\n pure\n {\n require(\n _debtRepayment <= _currentDebt.sub(ZUSD_GAS_COMPENSATION),\n \"BorrowerOps: Amount repaid must not be larger than the Trove's debt\"\n );\n }\n\n function _requireCallerIsStabilityPool() internal view {\n require(msg.sender == stabilityPoolAddress, \"BorrowerOps: Caller is not Stability Pool\");\n }\n\n function _requireSufficientZUSDBalance(\n IZUSDToken _zusdToken,\n address _borrower,\n uint256 _debtRepayment\n ) internal view {\n require(\n _zusdToken.balanceOf(_borrower) >= _debtRepayment,\n \"BorrowerOps: Caller doesnt have enough ZUSD to make repayment\"\n );\n }\n\n function _requireValidMaxFeePercentage(uint256 _maxFeePercentage, bool _isRecoveryMode)\n internal\n view\n {\n if (_isRecoveryMode) {\n require(\n _maxFeePercentage <= DECIMAL_PRECISION,\n \"Max fee percentage must less than or equal to 100%\"\n );\n } else {\n require(\n _maxFeePercentage >= liquityBaseParams.BORROWING_FEE_FLOOR() &&\n _maxFeePercentage <= DECIMAL_PRECISION,\n \"Max fee percentage must be between 0.5% and 100%\"\n );\n }\n }\n\n // --- ICR and TCR getters ---\n\n /// Compute the new collateral ratio, considering the change in coll and debt. Assumes 0 pending rewards.\n function _getNewNominalICRFromTroveChange(\n uint256 _coll,\n uint256 _debt,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease\n ) internal pure returns (uint256) {\n (uint256 newColl, uint256 newDebt) = _getNewTroveAmounts(\n _coll,\n _debt,\n _collChange,\n _isCollIncrease,\n _debtChange,\n _isDebtIncrease\n );\n\n uint256 newNICR = LiquityMath._computeNominalCR(newColl, newDebt);\n return newNICR;\n }\n\n /// Compute the new collateral ratio, considering the change in coll and debt. Assumes 0 pending rewards.\n function _getNewICRFromTroveChange(\n uint256 _coll,\n uint256 _debt,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease,\n uint256 _price\n ) internal pure returns (uint256) {\n (uint256 newColl, uint256 newDebt) = _getNewTroveAmounts(\n _coll,\n _debt,\n _collChange,\n _isCollIncrease,\n _debtChange,\n _isDebtIncrease\n );\n\n uint256 newICR = LiquityMath._computeCR(newColl, newDebt, _price);\n return newICR;\n }\n\n function _getNewTroveAmounts(\n uint256 _coll,\n uint256 _debt,\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease\n ) internal pure returns (uint256, uint256) {\n uint256 newColl = _coll;\n uint256 newDebt = _debt;\n\n newColl = _isCollIncrease ? _coll.add(_collChange) : _coll.sub(_collChange);\n newDebt = _isDebtIncrease ? _debt.add(_debtChange) : _debt.sub(_debtChange);\n\n return (newColl, newDebt);\n }\n\n function _getNewTCRFromTroveChange(\n uint256 _collChange,\n bool _isCollIncrease,\n uint256 _debtChange,\n bool _isDebtIncrease,\n uint256 _price\n ) internal view returns (uint256) {\n uint256 totalColl = getEntireSystemColl();\n uint256 totalDebt = getEntireSystemDebt();\n\n totalColl = _isCollIncrease ? totalColl.add(_collChange) : totalColl.sub(_collChange);\n totalDebt = _isDebtIncrease ? totalDebt.add(_debtChange) : totalDebt.sub(_debtChange);\n\n uint256 newTCR = LiquityMath._computeCR(totalColl, totalDebt, _price);\n return newTCR;\n }\n\n function getCompositeDebt(uint256 _debt) external view override returns (uint256) {\n return _getCompositeDebt(_debt);\n }\n\n function BORROWING_FEE_FLOOR() external view override returns (uint256) {\n return liquityBaseParams.BORROWING_FEE_FLOOR();\n }\n\n function getMassetManager() external view override returns (IMassetManager) {\n return massetManager;\n }\n}\n" + }, + "contracts/BorrowerOperationsStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IActivePool.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/Mynt/IMassetManager.sol\";\n\ncontract BorrowerOperationsStorage is Ownable {\n string public constant NAME = \"BorrowerOperations\";\n\n // --- Connected contract declarations ---\n\n ITroveManager public troveManager;\n\n address stabilityPoolAddress;\n\n address gasPoolAddress;\n\n ICollSurplusPool collSurplusPool;\n\n IZEROStaking public zeroStaking;\n address public zeroStakingAddress;\n\n IZUSDToken public zusdToken;\n\n // A doubly linked list of Troves, sorted by their collateral ratios\n ISortedTroves public sortedTroves;\n\n IMassetManager public massetManager;\n IFeeDistributor public feeDistributor;\n}\n" + }, + "contracts/CollSurplusPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./CollSurplusPoolStorage.sol\";\n\ncontract CollSurplusPool is CollSurplusPoolStorage, CheckContract, ICollSurplusPool {\n using SafeMath for uint256;\n // --- Events ---\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n\n event CollBalanceUpdated(address indexed _account, uint256 _newBalance);\n event EtherSent(address _to, uint256 _amount);\n\n // --- Contract setters ---\n\n function setAddresses(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress\n ) external override onlyOwner {\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n\n borrowerOperationsAddress = _borrowerOperationsAddress;\n troveManagerAddress = _troveManagerAddress;\n activePoolAddress = _activePoolAddress;\n\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n }\n\n /** Returns the ETH state variable at ActivePool address.\n Not necessarily equal to the raw ether balance - ether can be forcibly sent to contracts. */\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n function getCollateral(address _account) external view override returns (uint256) {\n return balances[_account];\n }\n\n // --- Pool functionality ---\n\n function accountSurplus(address _account, uint256 _amount) external override {\n _requireCallerIsTroveManager();\n\n uint256 newAmount = balances[_account].add(_amount);\n balances[_account] = newAmount;\n\n emit CollBalanceUpdated(_account, newAmount);\n }\n\n function claimColl(address _account) external override {\n _requireCallerIsBorrowerOperations();\n uint256 claimableColl = balances[_account];\n require(claimableColl > 0, \"CollSurplusPool: No collateral available to claim\");\n\n balances[_account] = 0;\n emit CollBalanceUpdated(_account, 0);\n\n ETH = ETH.sub(claimableColl);\n emit EtherSent(_account, claimableColl);\n\n (bool success, ) = _account.call{ value: claimableColl }(\"\");\n require(success, \"CollSurplusPool: sending ETH failed\");\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsBorrowerOperations() internal view {\n require(\n msg.sender == borrowerOperationsAddress,\n \"CollSurplusPool: Caller is not Borrower Operations\"\n );\n }\n\n function _requireCallerIsTroveManager() internal view {\n require(msg.sender == troveManagerAddress, \"CollSurplusPool: Caller is not TroveManager\");\n }\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"CollSurplusPool: Caller is not Active Pool\");\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsActivePool();\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/CollSurplusPoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Dependencies/Ownable.sol\";\n\ncontract CollSurplusPoolStorage is Ownable {\n string public constant NAME = \"CollSurplusPool\";\n\n address public borrowerOperationsAddress;\n address public troveManagerAddress;\n address public activePoolAddress;\n\n // deposited ether tracker\n uint256 internal ETH;\n // Collateral surplus claimable by trove owners\n mapping(address => uint256) internal balances;\n}\n" + }, + "contracts/DefaultPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IDefaultPool.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./DefaultPoolStorage.sol\";\n\n/**\n * The Default Pool holds the ETH and ZUSD debt (but not ZUSD tokens) from liquidations that have been redistributed\n * to active troves but not yet \"applied\", i.e. not yet recorded on a recipient active trove's struct.\n *\n * When a trove makes an operation that applies its pending ETH and ZUSD debt, its pending ETH and ZUSD debt is moved\n * from the Default Pool to the Active Pool.\n */\ncontract DefaultPool is DefaultPoolStorage, CheckContract, IDefaultPool {\n using SafeMath for uint256;\n\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event DefaultPoolZUSDDebtUpdated(uint256 _ZUSDDebt);\n event DefaultPoolETHBalanceUpdated(uint256 _ETH);\n\n // --- Dependency setters ---\n\n function setAddresses(address _troveManagerAddress, address _activePoolAddress)\n external\n onlyOwner\n {\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n\n troveManagerAddress = _troveManagerAddress;\n activePoolAddress = _activePoolAddress;\n\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n }\n\n // --- Getters for public variables. Required by IPool interface ---\n\n /**\n * @return the ETH state variable.\n *\n * Not necessarily equal to the the contract's raw ETH balance - ether can be forcibly sent to contracts.\n */\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n function getZUSDDebt() external view override returns (uint256) {\n return ZUSDDebt;\n }\n\n // --- Pool functionality ---\n\n function sendETHToActivePool(uint256 _amount) external override {\n _requireCallerIsTroveManager();\n address activePool = activePoolAddress; // cache to save an SLOAD\n ETH = ETH.sub(_amount);\n emit DefaultPoolETHBalanceUpdated(ETH);\n emit EtherSent(activePool, _amount);\n\n (bool success, ) = activePool.call{ value: _amount }(\"\");\n require(success, \"DefaultPool: sending ETH failed\");\n }\n\n function increaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsTroveManager();\n ZUSDDebt = ZUSDDebt.add(_amount);\n emit DefaultPoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n function decreaseZUSDDebt(uint256 _amount) external override {\n _requireCallerIsTroveManager();\n ZUSDDebt = ZUSDDebt.sub(_amount);\n emit DefaultPoolZUSDDebtUpdated(ZUSDDebt);\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"DefaultPool: Caller is not the ActivePool\");\n }\n\n function _requireCallerIsTroveManager() internal view {\n require(msg.sender == troveManagerAddress, \"DefaultPool: Caller is not the TroveManager\");\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsActivePool();\n ETH = ETH.add(msg.value);\n emit DefaultPoolETHBalanceUpdated(ETH);\n }\n}\n" + }, + "contracts/DefaultPoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract DefaultPoolStorage is Ownable {\n string public constant NAME = \"DefaultPool\";\n\n address public troveManagerAddress;\n address public activePoolAddress;\n uint256 internal ETH; // deposited ETH tracker\n uint256 internal ZUSDDebt; // debt\n}\n" + }, + "contracts/Dependencies/BaseMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\n\ncontract BaseMath {\n uint constant public DECIMAL_PRECISION = 1e18;\n}\n" + }, + "contracts/Dependencies/CheckContract.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n\ncontract CheckContract {\n /**\n * @dev Check that the account is an already deployed non-destroyed contract.\n * See: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L12\n */\n function checkContract(address _account) internal view {\n require(_account != address(0), \"Account cannot be zero address\");\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(_account) }\n require(size > 0, \"Account code size cannot be zero\");\n }\n}\n" + }, + "contracts/Dependencies/console.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// Buidler's helper contract for console logging\nlibrary console {\n\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n\tfunction log() internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log()\"));\n\t\tignored;\n\t}\tfunction logInt(int p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(int)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logUint(uint p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logString(string memory p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBool(bool p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logAddress(address p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes(bytes memory p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logByte(byte p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(byte)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes1(bytes1 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes1)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes2(bytes2 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes2)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes3(bytes3 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes3)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes4(bytes4 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes4)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes5(bytes5 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes5)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes6(bytes6 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes6)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes7(bytes7 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes7)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes8(bytes8 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes8)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes9(bytes9 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes9)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes10(bytes10 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes10)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes11(bytes11 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes11)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes12(bytes12 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes12)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes13(bytes13 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes13)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes14(bytes14 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes14)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes15(bytes15 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes15)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes16(bytes16 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes16)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes17(bytes17 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes17)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes18(bytes18 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes18)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes19(bytes19 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes19)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes20(bytes20 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes20)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes21(bytes21 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes21)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes22(bytes22 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes22)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes23(bytes23 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes23)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes24(bytes24 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes24)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes25(bytes25 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes25)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes26(bytes26 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes26)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes27(bytes27 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes27)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes28(bytes28 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes28)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes29(bytes29 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes29)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes30(bytes30 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes30)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes31(bytes31 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes31)\", p0));\n\t\tignored;\n\t}\n\n\tfunction logBytes32(bytes32 p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bytes32)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(address p0) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address)\", p0));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(uint p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(bool p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, uint p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, bool p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, uint p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, bool p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, uint p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, bool p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n\tfunction log(address p0, address p1, address p2, address p3) internal view {\n\t\t(bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n\t\tignored;\n\t}\n\n}\n" + }, + "contracts/Dependencies/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * Based on the OpenZeppelin IER20 interface:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol\n *\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n function increaseAllowance(address spender, uint256 addedValue) external returns (bool);\n function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n function name() external view returns (string memory);\n function symbol() external view returns (string memory);\n function decimals() external view returns (uint8);\n \n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}" + }, + "contracts/Dependencies/IERC2612.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * @dev Interface of the ERC2612 standard as defined in the EIP.\n *\n * Adds the {permit} method, which can be used to change one's\n * {IERC20-allowance} without having to send a transaction, by signing a\n * message. This allows users to spend tokens without having to hold Ether.\n *\n * See https://eips.ethereum.org/EIPS/eip-2612.\n * \n * Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\n */\ninterface IERC2612 {\n /**\n * @dev Sets `amount` as the allowance of `spender` over `owner`'s tokens,\n * given `owner`'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(address owner, address spender, uint256 amount, \n uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n \n /**\n * @dev Returns the current ERC2612 nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases `owner`'s nonce by one. This\n * prevents a signature from being used multiple times.\n *\n * `owner` can limit the time a Permit is valid for by setting `deadline` to \n * a value in the near future. The deadline argument can be set to uint(-1) to \n * create Permits that effectively never expire.\n */\n function nonces(address owner) external view returns (uint256);\n \n function version() external view returns (string memory);\n function permitTypeHash() external view returns (bytes32);\n function domainSeparator() external view returns (bytes32);\n}\n" + }, + "contracts/Dependencies/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * @title Initializable\n *\n * Based on OpenZeppelin's Initializable contract:\n * https://github.com/OpenZeppelin/openzeppelin-upgrades/blob/master/packages/core/contracts/Initializable.sol\n * \n * @dev Helper contract to support initializer functions. To use it, replace\n * the constructor with a function that has the `initializer` modifier.\n * WARNING: Unlike constructors, initializer functions must be manually\n * invoked. This applies both to deploying an Initializable contract, as well\n * as extending an Initializable contract via inheritance.\n * WARNING: When used with inheritance, manual care must be taken to not invoke\n * a parent initializer twice, or ensure that all initializers are idempotent,\n * because this is not dealt with automatically as with constructors.\n */\ncontract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private initializing;\n\n /**\n * @dev Modifier to use in the initializer function of a contract.\n */\n modifier initializer() {\n require(\n initializing || isConstructor() || !initialized,\n \"Contract instance has already been initialized\"\n );\n\n bool isTopLevelCall = !initializing;\n if (isTopLevelCall) {\n initializing = true;\n initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n initializing = false;\n }\n }\n\n /// @dev Returns true if and only if the function is running in the constructor\n function isConstructor() private view returns (bool) {\n // extcodesize checks the size of the code stored in an address, and\n // address returns the current address. Since the code is still not\n // deployed when running a constructor, any checks on its code size will\n // yield zero, making it an effective way to detect if a contract is\n // under construction or not.\n address self = address(this);\n uint256 cs;\n assembly {\n cs := extcodesize(self)\n }\n return cs == 0;\n }\n\n // Reserved storage space to allow for layout changes in the future.\n uint256[50] private ______gap;\n}\n" + }, + "contracts/Dependencies/LiquityBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./BaseMath.sol\";\nimport \"./LiquityMath.sol\";\nimport \"../Interfaces/IActivePool.sol\";\nimport \"../Interfaces/IDefaultPool.sol\";\nimport \"../Interfaces/IPriceFeed.sol\";\nimport \"../Interfaces/ILiquityBase.sol\";\nimport \"../Interfaces/ILiquityBaseParams.sol\";\n\n/**\n * Base contract for TroveManager, BorrowerOperations and StabilityPool. Contains global system constants and\n * common functions.\n */\ncontract LiquityBase is BaseMath, ILiquityBase {\n using SafeMath for uint256;\n\n uint256 public constant _100pct = 1000000000000000000; // 1e18 == 100%\n\n /// Amount of ZUSD to be locked in gas pool on opening troves\n uint256 public constant ZUSD_GAS_COMPENSATION = 20e18;\n\n /// Minimum amount of net ZUSD debt a trove must have\n uint256 public constant MIN_NET_DEBT = 180e18;\n\n IActivePool public activePool;\n\n IDefaultPool public defaultPool;\n\n IPriceFeed public override priceFeed;\n\n ILiquityBaseParams public override liquityBaseParams;\n\n // --- Gas compensation functions ---\n\n // Returns the composite debt (drawn debt + gas compensation) of a trove, for the purpose of ICR calculation\n function _getCompositeDebt(uint256 _debt) internal pure returns (uint256) {\n return _debt.add(ZUSD_GAS_COMPENSATION);\n }\n\n function _getNetDebt(uint256 _debt) internal pure returns (uint256) {\n return _debt.sub(ZUSD_GAS_COMPENSATION);\n }\n\n /// Return the amount of ETH to be drawn from a trove's collateral and sent as gas compensation.\n function _getCollGasCompensation(uint256 _entireColl) internal view returns (uint256) {\n return _entireColl / liquityBaseParams.PERCENT_DIVISOR();\n }\n\n function getEntireSystemColl() public view returns (uint256 entireSystemColl) {\n uint256 activeColl = activePool.getETH();\n uint256 liquidatedColl = defaultPool.getETH();\n\n return activeColl.add(liquidatedColl);\n }\n\n function getEntireSystemDebt() public view returns (uint256 entireSystemDebt) {\n uint256 activeDebt = activePool.getZUSDDebt();\n uint256 closedDebt = defaultPool.getZUSDDebt();\n\n return activeDebt.add(closedDebt);\n }\n\n function _getTCR(uint256 _price) internal view returns (uint256 TCR) {\n uint256 entireSystemColl = getEntireSystemColl();\n uint256 entireSystemDebt = getEntireSystemDebt();\n\n TCR = LiquityMath._computeCR(entireSystemColl, entireSystemDebt, _price);\n\n return TCR;\n }\n\n function _checkRecoveryMode(uint256 _price) internal view returns (bool) {\n uint256 TCR = _getTCR(_price);\n\n return TCR < liquityBaseParams.CCR();\n }\n\n function _requireUserAcceptsFee(\n uint256 _fee,\n uint256 _amount,\n uint256 _maxFeePercentage\n ) internal pure {\n uint256 feePercentage = _fee.mul(DECIMAL_PRECISION).div(_amount);\n require(feePercentage <= _maxFeePercentage, \"Fee exceeded provided maximum\");\n }\n}\n" + }, + "contracts/Dependencies/LiquityMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./SafeMath.sol\";\nimport \"./console.sol\";\n\nlibrary LiquityMath {\n using SafeMath for uint;\n\n uint internal constant DECIMAL_PRECISION = 1e18;\n\n /* Precision for Nominal ICR (independent of price). Rationale for the value:\n *\n * - Making it “too high” could lead to overflows.\n * - Making it “too low” could lead to an ICR equal to zero, due to truncation from Solidity floor division. \n *\n * This value of 1e20 is chosen for safety: the NICR will only overflow for numerator > ~1e39 ETH,\n * and will only truncate to 0 if the denominator is at least 1e20 times greater than the numerator.\n *\n */\n uint internal constant NICR_PRECISION = 1e20;\n\n function _min(uint _a, uint _b) internal pure returns (uint) {\n return (_a < _b) ? _a : _b;\n }\n\n function _max(uint _a, uint _b) internal pure returns (uint) {\n return (_a >= _b) ? _a : _b;\n }\n\n /* \n * Multiply two decimal numbers and use normal rounding rules:\n * -round product up if 19'th mantissa digit >= 5\n * -round product down if 19'th mantissa digit < 5\n *\n * Used only inside the exponentiation, _decPow().\n */\n function decMul(uint x, uint y) internal pure returns (uint decProd) {\n uint prod_xy = x.mul(y);\n\n decProd = prod_xy.add(DECIMAL_PRECISION / 2).div(DECIMAL_PRECISION);\n }\n\n /* \n * _decPow: Exponentiation function for 18-digit decimal base, and integer exponent n.\n * \n * Uses the efficient \"exponentiation by squaring\" algorithm. O(log(n)) complexity. \n * \n * Called by two functions that represent time in units of minutes:\n * 1) TroveManager._calcDecayedBaseRate\n * 2) CommunityIssuance._getCumulativeIssuanceFraction \n * \n * The exponent is capped to avoid reverting due to overflow. The cap 525600000 equals\n * \"minutes in 1000 years\": 60 * 24 * 365 * 1000\n * \n * If a period of > 1000 years is ever used as an exponent in either of the above functions, the result will be\n * negligibly different from just passing the cap, since: \n *\n * In function 1), the decayed base rate will be 0 for 1000 years or > 1000 years\n * In function 2), the difference in tokens issued at 1000 years and any time > 1000 years, will be negligible\n */\n function _decPow(uint _base, uint _minutes) internal pure returns (uint) {\n \n if (_minutes > 525600000) {_minutes = 525600000;} // cap to avoid overflow\n \n if (_minutes == 0) {return DECIMAL_PRECISION;}\n\n uint y = DECIMAL_PRECISION;\n uint x = _base;\n uint n = _minutes;\n\n // Exponentiation-by-squaring\n while (n > 1) {\n if (n % 2 == 0) {\n x = decMul(x, x);\n n = n.div(2);\n } else { // if (n % 2 != 0)\n y = decMul(x, y);\n x = decMul(x, x);\n n = (n.sub(1)).div(2);\n }\n }\n\n return decMul(x, y);\n }\n\n function _getAbsoluteDifference(uint _a, uint _b) internal pure returns (uint) {\n return (_a >= _b) ? _a.sub(_b) : _b.sub(_a);\n }\n\n function _computeNominalCR(uint _coll, uint _debt) internal pure returns (uint) {\n if (_debt > 0) {\n return _coll.mul(NICR_PRECISION).div(_debt);\n }\n // Return the maximal value for uint256 if the Trove has a debt of 0. Represents \"infinite\" CR.\n else { // if (_debt == 0)\n return 2**256 - 1;\n }\n }\n\n function _computeCR(uint _coll, uint _debt, uint _price) internal pure returns (uint) {\n if (_debt > 0) {\n uint newCollRatio = _coll.mul(_price).div(_debt);\n\n return newCollRatio;\n }\n // Return the maximal value for uint256 if the Trove has a debt of 0. Represents \"infinite\" CR.\n else { // if (_debt == 0)\n return 2**256 - 1; \n }\n }\n}\n" + }, + "contracts/Dependencies/LiquitySafeMath128.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// uint128 addition and subtraction, with overflow protection.\n\nlibrary LiquitySafeMath128 {\n function add(uint128 a, uint128 b) internal pure returns (uint128) {\n uint128 c = a + b;\n require(c >= a, \"LiquitySafeMath128: addition overflow\");\n\n return c;\n }\n \n function sub(uint128 a, uint128 b) internal pure returns (uint128) {\n require(b <= a, \"LiquitySafeMath128: subtraction overflow\");\n uint128 c = a - b;\n\n return c;\n }\n}" + }, + "contracts/Dependencies/Mynt/IDLLR.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\nimport \"../IERC20.sol\";\n\n/// Public interface for Sovryn Dollar DLLR (Meta Asset Token of Sovryn Mynt) exposing specific functions\ninterface IDLLR is IERC20 {\n /**\n * @notice Only owner can transfer the token.\n * @notice destination cannot be:\n * - zero (0x0) address.\n *\n * @param _recipient Recipient of the token.\n * @param _amount The amount of token that will be transferred.\n *\n * @return true / false.\n */\n function transfer(address _recipient, uint256 _amount) external override returns (bool);\n\n /**\n * @notice Only owner who can transfer the token.\n * @notice destination cannot be:\n * - zero (0x0) address.\n *\n * @param _from Sender of the token.\n * @param _to Recipient of the token.\n * @param _amount The amount of token that will be transferred.\n *\n * @return true / false.\n */\n function transferFrom(\n address _from,\n address _to,\n uint256 _amount\n ) external override returns (bool);\n\n /**\n * @notice transfer utilizing EIP-2612, to reduce the additional sending transaction for doing the approval to the spender.\n *\n * @notice destination cannot be:\n * - zero (0x0) address.\n *\n * @dev By calling this function, the allowance will be overwritten by the total amount.\n *\n * @param _from Sender of the token.\n * @param _to Recipient of the token.\n * @param _amount The amount of the token that will be transferred.\n * @param _deadline Expiration time of the signature.\n * @param _v Last 1 byte of ECDSA signature.\n * @param _r First 32 bytes of ECDSA signature.\n * @param _s 32 bytes after _r in ECDSA signature.\n */\n function transferWithPermit(\n address _from,\n address _to,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external;\n\n /**\n * @notice Approves and then calls the receiving contract.\n * Useful to encapsulate sending tokens to a contract in one call.\n * Solidity has no native way to send tokens to contracts.\n * ERC-20 tokens require approval to be spent by third parties, such as a contract in this case.\n * @param _spender The contract address to spend the tokens.\n * @param _amount The amount of tokens to be sent.\n * @param _data Parameters for the contract call, such as endpoint signature.\n */\n function approveAndCall(address _spender, uint256 _amount, bytes calldata _data) external;\n}\n" + }, + "contracts/Dependencies/Mynt/IMassetManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IMassetManager {\n struct PermitParams {\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n function mintTo(\n address _bAsset,\n uint256 _bAssetQuantity,\n address _recipient\n ) external returns (uint256);\n\n function getToken() external view returns (address);\n\n /**\n * @dev Credits a recipient with a certain quantity of selected bAsset, in exchange for burning the\n * relative mAsset quantity from the sender. Sender also incurs a small fee, if any.\n * @param _bAsset Address of the bAsset to redeem.\n * @param _massetQuantity Units of the masset to redeem.\n * @param _recipient Address to credit with withdrawn bAssets.\n * @return massetRedeemed Relative number of mAsset units burned to pay for the bAssets.\n */\n function redeemTo(\n address _bAsset,\n uint256 _massetQuantity,\n address _recipient\n ) external returns (uint256 massetRedeemed);\n}\n" + }, + "contracts/Dependencies/Mynt/MyntLib.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IMassetManager.sol\";\nimport \"./IDLLR.sol\";\nimport \"../SafeMath.sol\";\n\nlibrary MyntLib {\n using SafeMath for uint256;\n\n /**\n * @notice Convert DLLR _dllrAmount to _toToken utilizing EIP-2612 permit\n * to reduce the additional sending transaction for doing the approval to the spender.\n *\n * @param _myntMassetManager Mynt protocol MassetManager contract address - needed for integration\n * @param _dllrAmount The amount of the DLLR (mAsset) token that will be burned in exchange for _toToken\n * @param _toToken bAsset token address to wothdraw from DLLR\n * @param _permitParams EIP-2612 permit params:\n * _deadline Expiration time of the signature.\n * _v Last 1 byte of ECDSA signature.\n * _r First 32 bytes of ECDSA signature.\n * _s 32 bytes after _r in ECDSA signature.\n * @return redeemed ZUSD amount\n */\n function redeemZusdFromDllrWithPermit(\n IMassetManager _myntMassetManager,\n uint256 _dllrAmount,\n address _toToken,\n IMassetManager.PermitParams calldata _permitParams\n ) internal returns (uint256) {\n IDLLR dllr = IDLLR(_myntMassetManager.getToken());\n uint256 thisBalanceBefore = dllr.balanceOf(address(this));\n address thisAddress = address(this);\n dllr.transferWithPermit(\n msg.sender,\n thisAddress,\n _dllrAmount,\n _permitParams.deadline,\n _permitParams.v,\n _permitParams.r,\n _permitParams.s\n );\n require(\n dllr.balanceOf(thisAddress).sub(thisBalanceBefore) == _dllrAmount,\n \"DLLR transferred amount validation failed\"\n );\n return _myntMassetManager.redeemTo(_toToken, _dllrAmount, msg.sender);\n }\n}\n" + }, + "contracts/Dependencies/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * Based on OpenZeppelin's Ownable contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n *\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\ncontract Ownable {\n bytes32 private constant KEY_OWNER = keccak256(\"key.ownable.owner\");\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () internal {\n _setOwner(msg.sender);\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(msg.sender == getOwner(), \"Ownable:: access denied\");\n _;\n }\n\n /**\n * @notice Set address of the owner.\n * @param _owner Address of the owner.\n * */\n function _setOwner(address _owner) internal {\n require(_owner != address(0), \"Ownable::setOwner: invalid address\");\n emit OwnershipTransferred(getOwner(), _owner);\n\n bytes32 key = KEY_OWNER;\n assembly {\n sstore(key, _owner)\n }\n }\n\n /**\n * @notice Set address of the owner (only owner can call this function)\n * @param _owner Address of the owner.\n * */\n function setOwner(address _owner) public onlyOwner {\n _setOwner(_owner);\n }\n\n /**\n * @notice Return address of the owner.\n * @return _owner Address of the owner.\n * */\n function getOwner() public view returns (address _owner) {\n bytes32 key = KEY_OWNER;\n assembly {\n _owner := sload(key)\n }\n }\n}\n" + }, + "contracts/Dependencies/PriceFeed/IExternalPriceFeed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/// @title A generic interface for external price providers \ninterface IExternalPriceFeed {\n /// @dev The returned price should be 18-decimal value\n /// @return the prive value and a boolean stating if the query was successful\n function latestAnswer() external view returns (uint256, bool);\n}\n" + }, + "contracts/Dependencies/PriceFeed/MocMedianizer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./IExternalPriceFeed.sol\";\n\ninterface IMoCBaseOracle {\n function peek() external view returns (bytes32, bool);\n}\n\ncontract MoCMedianizer is IExternalPriceFeed {\n IMoCBaseOracle medianizer;\n\n constructor(address _medianizer) public {\n medianizer = IMoCBaseOracle(_medianizer);\n }\n\n function latestAnswer() external view override returns (uint256, bool) {\n (bytes32 price, bool success) = medianizer.peek();\n return (uint256(price), success);\n }\n}\n" + }, + "contracts/Dependencies/PriceFeed/RskOracle.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./IExternalPriceFeed.sol\";\n\ninterface IRSKOracle {\n function getPricing() external view returns (uint256, uint256);\n}\n\ncontract RskOracle is IExternalPriceFeed {\n \n IRSKOracle rskOracle;\n\n constructor(address _address) public {\n rskOracle = IRSKOracle(_address);\n }\n\n function latestAnswer() external view override returns (uint256, bool) {\n (uint256 price, ) = rskOracle.getPricing();\n return (price, true);\n }\n}\n" + }, + "contracts/Dependencies/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * Based on OpenZeppelin's SafeMath:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol\n *\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "contracts/Dependencies/TroveManagerBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IActivePool.sol\";\nimport \"../Interfaces/IDefaultPool.sol\";\nimport \"../Interfaces/IZUSDToken.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\nimport \"../Interfaces/ISortedTroves.sol\";\nimport \"../Interfaces/ICollSurplusPool.sol\";\nimport \"../TroveManagerStorage.sol\";\nimport \"./LiquityBase.sol\";\n\ncontract TroveManagerBase is LiquityBase, TroveManagerStorage {\n uint256 public constant SECONDS_IN_ONE_MINUTE = 60;\n\n uint256 public constant MINUTE_DECAY_FACTOR = 999037758833783000;\n\n /// During bootsrap period redemptions are not allowed\n uint256 public immutable BOOTSTRAP_PERIOD;\n\n /**\n BETA: 18 digit decimal. Parameter by which to divide the redeemed fraction, in order to calc the new base rate from a redemption.\n Corresponds to (1 / ALPHA) in the white paper.\n */\n uint256 public constant BETA = 2;\n\n /**\n --- Variable container structs for liquidations ---\n \n These structs are used to hold, return and assign variables inside the liquidation functions,\n in order to avoid the error: \"CompilerError: Stack too deep\".\n */\n\n struct LocalVariables_OuterLiquidationFunction {\n uint256 price;\n uint256 ZUSDInStabPool;\n bool recoveryModeAtStart;\n uint256 liquidatedDebt;\n uint256 liquidatedColl;\n }\n\n struct LocalVariables_InnerSingleLiquidateFunction {\n uint256 collToLiquidate;\n uint256 pendingDebtReward;\n uint256 pendingCollReward;\n }\n\n struct LocalVariables_LiquidationSequence {\n uint256 remainingZUSDInStabPool;\n uint256 i;\n uint256 ICR;\n address user;\n bool backToNormalMode;\n uint256 entireSystemDebt;\n uint256 entireSystemColl;\n }\n\n struct LiquidationValues {\n uint256 entireTroveDebt;\n uint256 entireTroveColl;\n uint256 collGasCompensation;\n uint256 ZUSDGasCompensation;\n uint256 debtToOffset;\n uint256 collToSendToSP;\n uint256 debtToRedistribute;\n uint256 collToRedistribute;\n uint256 collSurplus;\n }\n\n struct LiquidationTotals {\n uint256 totalCollInSequence;\n uint256 totalDebtInSequence;\n uint256 totalCollGasCompensation;\n uint256 totalZUSDGasCompensation;\n uint256 totalDebtToOffset;\n uint256 totalCollToSendToSP;\n uint256 totalDebtToRedistribute;\n uint256 totalCollToRedistribute;\n uint256 totalCollSurplus;\n }\n\n struct ContractsCache {\n IActivePool activePool;\n IDefaultPool defaultPool;\n IZUSDToken zusdToken;\n IZEROStaking zeroStaking;\n ISortedTroves sortedTroves;\n ICollSurplusPool collSurplusPool;\n address gasPoolAddress;\n }\n // --- Variable container structs for redemptions ---\n\n struct RedemptionTotals {\n uint256 remainingZUSD;\n uint256 totalZUSDToRedeem;\n uint256 totalETHDrawn;\n uint256 ETHFee;\n uint256 ETHToSendToRedeemer;\n uint256 decayedBaseRate;\n uint256 price;\n uint256 totalZUSDSupplyAtStart;\n }\n\n struct SingleRedemptionValues {\n uint256 ZUSDLot;\n uint256 ETHLot;\n bool cancelledPartial;\n }\n\n // --- Events ---\n\n event Liquidation(\n uint256 _liquidatedDebt,\n uint256 _liquidatedColl,\n uint256 _collGasCompensation,\n uint256 _ZUSDGasCompensation\n );\n event Redemption(\n uint256 _attemptedZUSDAmount,\n uint256 _actualZUSDAmount,\n uint256 _ETHSent,\n uint256 _ETHFee\n );\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 _stake,\n TroveManagerOperation _operation\n );\n event TroveLiquidated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n TroveManagerOperation _operation\n );\n event BaseRateUpdated(uint256 _baseRate);\n event LastFeeOpTimeUpdated(uint256 _lastFeeOpTime);\n event TotalStakesUpdated(uint256 _newTotalStakes);\n event SystemSnapshotsUpdated(uint256 _totalStakesSnapshot, uint256 _totalCollateralSnapshot);\n event LTermsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveSnapshotsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveIndexUpdated(address _borrower, uint256 _newIndex);\n\n enum TroveManagerOperation {\n applyPendingRewards,\n liquidateInNormalMode,\n liquidateInRecoveryMode,\n redeemCollateral\n }\n\n constructor(uint256 _bootstrapPeriod) public {\n BOOTSTRAP_PERIOD = _bootstrapPeriod;\n }\n\n /// Return the current collateral ratio (ICR) of a given Trove. Takes a trove's pending coll and debt rewards from redistributions into account.\n function _getCurrentICR(address _borrower, uint256 _price) public view returns (uint256) {\n (uint256 currentETH, uint256 currentZUSDDebt) = _getCurrentTroveAmounts(_borrower);\n\n uint256 ICR = LiquityMath._computeCR(currentETH, currentZUSDDebt, _price);\n return ICR;\n }\n\n function _getCurrentTroveAmounts(address _borrower) internal view returns (uint256, uint256) {\n uint256 pendingETHReward = _getPendingETHReward(_borrower);\n uint256 pendingZUSDDebtReward = _getPendingZUSDDebtReward(_borrower);\n\n uint256 currentETH = Troves[_borrower].coll.add(pendingETHReward);\n uint256 currentZUSDDebt = Troves[_borrower].debt.add(pendingZUSDDebtReward);\n\n return (currentETH, currentZUSDDebt);\n }\n\n /// Get the borrower's pending accumulated ETH reward, earned by their stake\n function _getPendingETHReward(address _borrower) public view returns (uint256) {\n uint256 snapshotETH = rewardSnapshots[_borrower].ETH;\n uint256 rewardPerUnitStaked = L_ETH.sub(snapshotETH);\n\n if (rewardPerUnitStaked == 0 || Troves[_borrower].status != Status.active) {\n return 0;\n }\n\n uint256 stake = Troves[_borrower].stake;\n\n uint256 pendingETHReward = stake.mul(rewardPerUnitStaked).div(DECIMAL_PRECISION);\n\n return pendingETHReward;\n }\n\n /// Get the borrower's pending accumulated ZUSD reward, earned by their stake\n function _getPendingZUSDDebtReward(address _borrower) public view returns (uint256) {\n uint256 snapshotZUSDDebt = rewardSnapshots[_borrower].ZUSDDebt;\n uint256 rewardPerUnitStaked = L_ZUSDDebt.sub(snapshotZUSDDebt);\n\n if (rewardPerUnitStaked == 0 || Troves[_borrower].status != Status.active) {\n return 0;\n }\n\n uint256 stake = Troves[_borrower].stake;\n\n uint256 pendingZUSDDebtReward = stake.mul(rewardPerUnitStaked).div(DECIMAL_PRECISION);\n\n return pendingZUSDDebtReward;\n }\n\n /// Add the borrowers's coll and debt rewards earned from redistributions, to their Trove\n function _applyPendingRewards(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n address _borrower\n ) internal {\n if (_hasPendingRewards(_borrower)) {\n _requireTroveIsActive(_borrower);\n\n // Compute pending rewards\n uint256 pendingETHReward = _getPendingETHReward(_borrower);\n uint256 pendingZUSDDebtReward = _getPendingZUSDDebtReward(_borrower);\n\n // Apply pending rewards to trove's state\n Troves[_borrower].coll = Troves[_borrower].coll.add(pendingETHReward);\n Troves[_borrower].debt = Troves[_borrower].debt.add(pendingZUSDDebtReward);\n\n _updateTroveRewardSnapshots(_borrower);\n\n // Transfer from DefaultPool to ActivePool\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n pendingZUSDDebtReward,\n pendingETHReward\n );\n\n emit TroveUpdated(\n _borrower,\n Troves[_borrower].debt,\n Troves[_borrower].coll,\n Troves[_borrower].stake,\n TroveManagerOperation.applyPendingRewards\n );\n }\n }\n\n function _hasPendingRewards(address _borrower) public view returns (bool) {\n /*\n * A Trove has pending rewards if its snapshot is less than the current rewards per-unit-staked sum:\n * this indicates that rewards have occured since the snapshot was made, and the user therefore has\n * pending rewards\n */\n if (Troves[_borrower].status != Status.active) {\n return false;\n }\n\n return (rewardSnapshots[_borrower].ETH < L_ETH);\n }\n\n function _updateTroveRewardSnapshots(address _borrower) internal {\n rewardSnapshots[_borrower].ETH = L_ETH;\n rewardSnapshots[_borrower].ZUSDDebt = L_ZUSDDebt;\n emit TroveSnapshotsUpdated(L_ETH, L_ZUSDDebt);\n }\n\n /// Move a Trove's pending debt and collateral rewards from distributions, from the Default Pool to the Active Pool\n function _movePendingTroveRewardsToActivePool(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _ZUSD,\n uint256 _ETH\n ) internal {\n _defaultPool.decreaseZUSDDebt(_ZUSD);\n _activePool.increaseZUSDDebt(_ZUSD);\n _defaultPool.sendETHToActivePool(_ETH);\n }\n\n /// Remove borrower's stake from the totalStakes sum, and set their stake to 0\n function _removeStake(address _borrower) internal {\n uint256 stake = Troves[_borrower].stake;\n totalStakes = totalStakes.sub(stake);\n Troves[_borrower].stake = 0;\n }\n\n function _closeTrove(address _borrower, Status closedStatus) internal {\n assert(closedStatus != Status.nonExistent && closedStatus != Status.active);\n\n uint256 TroveOwnersArrayLength = TroveOwners.length;\n _requireMoreThanOneTroveInSystem(TroveOwnersArrayLength);\n\n Troves[_borrower].status = closedStatus;\n Troves[_borrower].coll = 0;\n Troves[_borrower].debt = 0;\n\n rewardSnapshots[_borrower].ETH = 0;\n rewardSnapshots[_borrower].ZUSDDebt = 0;\n\n _removeTroveOwner(_borrower, TroveOwnersArrayLength);\n sortedTroves.remove(_borrower);\n }\n\n /// Update borrower's stake based on their latest collateral value\n function _updateStakeAndTotalStakes(address _borrower) internal returns (uint256) {\n uint256 newStake = _computeNewStake(Troves[_borrower].coll);\n uint256 oldStake = Troves[_borrower].stake;\n Troves[_borrower].stake = newStake;\n\n totalStakes = totalStakes.sub(oldStake).add(newStake);\n emit TotalStakesUpdated(totalStakes);\n\n return newStake;\n }\n\n // Calculate a new stake based on the snapshots of the totalStakes and totalCollateral taken at the last liquidation\n function _computeNewStake(uint256 _coll) internal view returns (uint256) {\n uint256 stake;\n if (totalCollateralSnapshot == 0) {\n stake = _coll;\n } else {\n /*\n * The following assert() holds true because:\n * - The system always contains >= 1 trove\n * - When we close or liquidate a trove, we redistribute the pending rewards, so if all troves were closed/liquidated,\n * rewards would’ve been emptied and totalCollateralSnapshot would be zero too.\n */\n assert(totalStakesSnapshot > 0);\n stake = _coll.mul(totalStakesSnapshot).div(totalCollateralSnapshot);\n }\n return stake;\n }\n\n function _calcDecayedBaseRate() internal view returns (uint256) {\n uint256 minutesPassed = _minutesPassedSinceLastFeeOp();\n uint256 decayFactor = LiquityMath._decPow(MINUTE_DECAY_FACTOR, minutesPassed);\n\n return baseRate.mul(decayFactor).div(DECIMAL_PRECISION);\n }\n\n function _minutesPassedSinceLastFeeOp() internal view returns (uint256) {\n return (block.timestamp.sub(lastFeeOperationTime)).div(SECONDS_IN_ONE_MINUTE);\n }\n\n // Update the last fee operation time only if time passed >= decay interval. This prevents base rate griefing.\n function _updateLastFeeOpTime() internal {\n uint256 timePassed = block.timestamp.sub(lastFeeOperationTime);\n\n if (timePassed >= SECONDS_IN_ONE_MINUTE) {\n lastFeeOperationTime = block.timestamp;\n emit LastFeeOpTimeUpdated(block.timestamp);\n }\n }\n\n function _calcRedemptionFee(\n uint256 _redemptionRate,\n uint256 _ETHDrawn\n ) internal pure returns (uint256) {\n uint256 redemptionFee = _redemptionRate.mul(_ETHDrawn).div(DECIMAL_PRECISION);\n require(\n redemptionFee < _ETHDrawn,\n \"TroveManager: Fee would eat up all returned collateral\"\n );\n return redemptionFee;\n }\n\n function _getRedemptionRate() public view returns (uint256) {\n return _calcRedemptionRate(baseRate);\n }\n\n function _getRedemptionFee(uint256 _ETHDrawn) internal view returns (uint256) {\n return _calcRedemptionFee(_getRedemptionRate(), _ETHDrawn);\n }\n\n function _calcRedemptionRate(uint256 _baseRate) internal view returns (uint256) {\n return\n LiquityMath._min(\n liquityBaseParams.REDEMPTION_FEE_FLOOR().add(_baseRate),\n DECIMAL_PRECISION // cap at a maximum of 100%\n );\n }\n\n /**\n Remove a Trove owner from the TroveOwners array, not preserving array order. Removing owner 'B' does the following:\n [A B C D E] => [A E C D], and updates E's Trove struct to point to its new array index.\n */\n function _removeTroveOwner(address _borrower, uint256 TroveOwnersArrayLength) internal {\n Status troveStatus = Troves[_borrower].status;\n // It’s set in caller function `_closeTrove`\n assert(troveStatus != Status.nonExistent && troveStatus != Status.active);\n\n uint128 index = Troves[_borrower].arrayIndex;\n uint256 length = TroveOwnersArrayLength;\n uint256 idxLast = length.sub(1);\n\n assert(index <= idxLast);\n\n address addressToMove = TroveOwners[idxLast];\n\n TroveOwners[index] = addressToMove;\n Troves[addressToMove].arrayIndex = index;\n emit TroveIndexUpdated(addressToMove, index);\n\n TroveOwners.pop();\n }\n\n // --- 'require' wrapper functions ---\n\n function _requireCallerIsBorrowerOperations() internal view {\n require(\n msg.sender == borrowerOperationsAddress,\n \"TroveManager: Caller is not the BorrowerOperations contract\"\n );\n }\n\n function _requireTroveIsActive(address _borrower) internal view {\n require(\n Troves[_borrower].status == Status.active,\n \"TroveManager: Trove does not exist or is closed\"\n );\n }\n\n function _requireZUSDBalanceCoversRedemption(\n IZUSDToken _zusdToken,\n address _redeemer,\n uint256 _amount\n ) internal view {\n require(\n _zusdToken.balanceOf(_redeemer) >= _amount,\n \"TroveManager: Requested redemption amount must be <= user's ZUSD token balance\"\n );\n }\n\n function _requireMoreThanOneTroveInSystem(uint256 TroveOwnersArrayLength) internal view {\n require(\n TroveOwnersArrayLength > 1 && sortedTroves.getSize() > 1,\n \"TroveManager: Only one trove in the system\"\n );\n }\n\n function _requireAmountGreaterThanZero(uint256 _amount) internal pure {\n require(_amount > 0, \"TroveManager: Amount must be greater than zero\");\n }\n\n function _requireTCRoverMCR(uint256 _price) internal view {\n require(\n _getTCR(_price) >= liquityBaseParams.MCR(),\n \"TroveManager: Cannot redeem when TCR < MCR\"\n );\n }\n\n function _requireAfterBootstrapPeriod() internal view {\n uint256 systemDeploymentTime = _zeroToken.getDeploymentStartTime();\n require(\n block.timestamp >= systemDeploymentTime.add(BOOTSTRAP_PERIOD),\n \"TroveManager: Redemptions are not allowed during bootstrap phase\"\n );\n }\n\n function _requireValidMaxFeePercentage(uint256 _maxFeePercentage) internal view {\n require(\n _maxFeePercentage >= liquityBaseParams.REDEMPTION_FEE_FLOOR() &&\n _maxFeePercentage <= DECIMAL_PRECISION,\n \"Max fee percentage must be between 0.5% and 100%\"\n );\n }\n}\n" + }, + "contracts/Dependencies/TroveManagerRedeemOps.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../Dependencies/Mynt/MyntLib.sol\";\nimport \"../Interfaces/IBorrowerOperations.sol\";\nimport \"./TroveManagerBase.sol\";\n\n/// This contract is designed to be used via delegatecall from the TroveManager contract\n/// TroveManagerBase constructor param is bootsrap period when redemptions are not allowed\ncontract TroveManagerRedeemOps is TroveManagerBase {\n /** Send _ZUSDamount ZUSD to the system and redeem the corresponding amount of collateral from as many Troves as are needed to fill the redemption\n request. Applies pending rewards to a Trove before reducing its debt and coll.\n \n Note that if _amount is very large, this function can run out of gas, specially if traversed troves are small. This can be easily avoided by\n splitting the total _amount in appropriate chunks and calling the function multiple times.\n \n Param `_maxIterations` can also be provided, so the loop through Troves is capped (if it’s zero, it will be ignored).This makes it easier to\n avoid OOG for the frontend, as only knowing approximately the average cost of an iteration is enough, without needing to know the “topology”\n of the trove list. It also avoids the need to set the cap in stone in the contract, nor doing gas calculations, as both gas price and opcode\n costs can vary.\n \n All Troves that are redeemed from -- with the likely exception of the last one -- will end up with no debt left, therefore they will be closed.\n If the last Trove does have some remaining debt, it has a finite ICR, and the reinsertion could be anywhere in the list, therefore it requires a hint.\n A frontend should use getRedemptionHints() to calculate what the ICR of this Trove will be after redemption, and pass a hint for its position\n in the sortedTroves list along with the ICR value that the hint was found for.\n \n If another transaction modifies the list between calling getRedemptionHints() and passing the hints to redeemCollateral(), it\n is very likely that the last (partially) redeemed Trove would end up with a different ICR than what the hint is for. In this case the\n redemption will stop after the last completely redeemed Trove and the sender will keep the remaining ZUSD amount, which they can attempt\n to redeem later.\n */\n\n constructor(uint256 _bootstrapPeriod) public TroveManagerBase(_bootstrapPeriod) {}\n\n function redeemCollateral(\n uint256 _ZUSDamount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage\n ) external {\n _redeemCollateral(\n _ZUSDamount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n _maxIterations,\n _maxFeePercentage\n );\n }\n\n function _redeemCollateral(\n uint256 _ZUSDamount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage\n ) internal {\n ContractsCache memory contractsCache = ContractsCache(\n activePool,\n defaultPool,\n _zusdToken,\n _zeroStaking,\n sortedTroves,\n collSurplusPool,\n gasPoolAddress\n );\n RedemptionTotals memory totals;\n\n _requireValidMaxFeePercentage(_maxFeePercentage);\n _requireAfterBootstrapPeriod();\n totals.price = priceFeed.fetchPrice();\n _requireTCRoverMCR(totals.price);\n _requireAmountGreaterThanZero(_ZUSDamount);\n _requireZUSDBalanceCoversRedemption(contractsCache.zusdToken, msg.sender, _ZUSDamount);\n\n totals.totalZUSDSupplyAtStart = getEntireSystemDebt();\n // Confirm redeemer's balance is less than total ZUSD supply\n assert(contractsCache.zusdToken.balanceOf(msg.sender) <= totals.totalZUSDSupplyAtStart);\n\n totals.remainingZUSD = _ZUSDamount;\n address currentBorrower;\n\n if (\n _isValidFirstRedemptionHint(\n contractsCache.sortedTroves,\n _firstRedemptionHint,\n totals.price\n )\n ) {\n currentBorrower = _firstRedemptionHint;\n } else {\n currentBorrower = contractsCache.sortedTroves.getLast();\n // Find the first trove with ICR >= MCR\n while (\n currentBorrower != address(0) &&\n _getCurrentICR(currentBorrower, totals.price) < liquityBaseParams.MCR()\n ) {\n currentBorrower = contractsCache.sortedTroves.getPrev(currentBorrower);\n }\n }\n\n // Loop through the Troves starting from the one with lowest collateral ratio until _amount of ZUSD is exchanged for collateral\n if (_maxIterations == 0) {\n _maxIterations = uint256(-1);\n }\n while (currentBorrower != address(0) && totals.remainingZUSD > 0 && _maxIterations > 0) {\n _maxIterations--;\n // Save the address of the Trove preceding the current one, before potentially modifying the list\n address nextUserToCheck = contractsCache.sortedTroves.getPrev(currentBorrower);\n\n _applyPendingRewards(\n contractsCache.activePool,\n contractsCache.defaultPool,\n currentBorrower\n );\n\n SingleRedemptionValues memory singleRedemption = _redeemCollateralFromTrove(\n contractsCache,\n currentBorrower,\n totals.remainingZUSD,\n totals.price,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR\n );\n\n if (singleRedemption.cancelledPartial) break; // Partial redemption was cancelled (out-of-date hint, or new net debt < minimum), therefore we could not redeem from the last Trove\n\n totals.totalZUSDToRedeem = totals.totalZUSDToRedeem.add(singleRedemption.ZUSDLot);\n totals.totalETHDrawn = totals.totalETHDrawn.add(singleRedemption.ETHLot);\n\n totals.remainingZUSD = totals.remainingZUSD.sub(singleRedemption.ZUSDLot);\n currentBorrower = nextUserToCheck;\n }\n require(totals.totalETHDrawn > 0, \"TroveManager: Unable to redeem any amount\");\n\n // Decay the baseRate due to time passed, and then increase it according to the size of this redemption.\n // Use the saved total ZUSD supply value, from before it was reduced by the redemption.\n _updateBaseRateFromRedemption(\n totals.totalETHDrawn,\n totals.price,\n totals.totalZUSDSupplyAtStart\n );\n\n // Calculate the ETH fee\n totals.ETHFee = _getRedemptionFee(totals.totalETHDrawn);\n\n _requireUserAcceptsFee(totals.ETHFee, totals.totalETHDrawn, _maxFeePercentage);\n\n // Send the ETH fee to the feeDistributorContract address\n contractsCache.activePool.sendETH(address(feeDistributor), totals.ETHFee);\n feeDistributor.distributeFees();\n\n totals.ETHToSendToRedeemer = totals.totalETHDrawn.sub(totals.ETHFee);\n\n emit Redemption(\n _ZUSDamount,\n totals.totalZUSDToRedeem,\n totals.totalETHDrawn,\n totals.ETHFee\n );\n\n // Burn the total ZUSD that is cancelled with debt, and send the redeemed ETH to msg.sender\n contractsCache.zusdToken.burn(msg.sender, totals.totalZUSDToRedeem);\n // Update Active Pool ZUSD, and send ETH to account\n contractsCache.activePool.decreaseZUSDDebt(totals.totalZUSDToRedeem);\n contractsCache.activePool.sendETH(msg.sender, totals.ETHToSendToRedeemer);\n }\n\n ///DLLR _owner can use Sovryn Mynt to convert DLLR to ZUSD, then use the Zero redemption mechanism to redeem ZUSD for RBTC, all in a single transaction\n function redeemCollateralViaDLLR(\n uint256 _dllrAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage,\n IMassetManager.PermitParams calldata _permitParams\n ) external {\n uint256 _zusdAmount = MyntLib.redeemZusdFromDllrWithPermit(\n IBorrowerOperations(borrowerOperationsAddress).getMassetManager(),\n _dllrAmount,\n address(_zusdToken),\n _permitParams\n );\n _redeemCollateral(\n _zusdAmount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n _maxIterations,\n _maxFeePercentage\n );\n }\n\n function _isValidFirstRedemptionHint(\n ISortedTroves _sortedTroves,\n address _firstRedemptionHint,\n uint256 _price\n ) internal view returns (bool) {\n if (\n _firstRedemptionHint == address(0) ||\n !_sortedTroves.contains(_firstRedemptionHint) ||\n _getCurrentICR(_firstRedemptionHint, _price) < liquityBaseParams.MCR()\n ) {\n return false;\n }\n\n address nextTrove = _sortedTroves.getNext(_firstRedemptionHint);\n return\n nextTrove == address(0) || _getCurrentICR(nextTrove, _price) < liquityBaseParams.MCR();\n }\n\n /// Redeem as much collateral as possible from _borrower's Trove in exchange for ZUSD up to _maxZUSDamount\n function _redeemCollateralFromTrove(\n ContractsCache memory _contractsCache,\n address _borrower,\n uint256 _maxZUSDamount,\n uint256 _price,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR\n ) internal returns (SingleRedemptionValues memory singleRedemption) {\n // Determine the remaining amount (lot) to be redeemed, capped by the entire debt of the Trove minus the liquidation reserve\n singleRedemption.ZUSDLot = LiquityMath._min(\n _maxZUSDamount,\n Troves[_borrower].debt.sub(ZUSD_GAS_COMPENSATION)\n );\n\n // Get the ETHLot of equivalent value in USD\n singleRedemption.ETHLot = singleRedemption.ZUSDLot.mul(DECIMAL_PRECISION).div(_price);\n\n // Decrease the debt and collateral of the current Trove according to the ZUSD lot and corresponding ETH to send\n uint256 newDebt = (Troves[_borrower].debt).sub(singleRedemption.ZUSDLot);\n uint256 newColl = (Troves[_borrower].coll).sub(singleRedemption.ETHLot);\n\n if (newDebt == ZUSD_GAS_COMPENSATION) {\n // No debt left in the Trove (except for the liquidation reserve), therefore the trove gets closed\n _removeStake(_borrower);\n _closeTrove(_borrower, Status.closedByRedemption);\n _redeemCloseTrove(_contractsCache, _borrower, ZUSD_GAS_COMPENSATION, newColl);\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.redeemCollateral);\n } else {\n uint256 newNICR = LiquityMath._computeNominalCR(newColl, newDebt);\n\n /*\n * If the provided hint is out of date, we bail since trying to reinsert without a good hint will almost\n * certainly result in running out of gas.\n *\n * If the resultant net debt of the partial is less than the minimum, net debt we bail.\n */\n if (newNICR != _partialRedemptionHintNICR || _getNetDebt(newDebt) < MIN_NET_DEBT) {\n singleRedemption.cancelledPartial = true;\n return singleRedemption;\n }\n\n _contractsCache.sortedTroves.reInsert(\n _borrower,\n newNICR,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint\n );\n\n Troves[_borrower].debt = newDebt;\n Troves[_borrower].coll = newColl;\n _updateStakeAndTotalStakes(_borrower);\n\n emit TroveUpdated(\n _borrower,\n newDebt,\n newColl,\n Troves[_borrower].stake,\n TroveManagerOperation.redeemCollateral\n );\n }\n\n return singleRedemption;\n }\n\n /**\n This function has two impacts on the baseRate state variable:\n 1) decays the baseRate based on time passed since last redemption or ZUSD borrowing operation.\n then,\n 2) increases the baseRate based on the amount redeemed, as a proportion of total supply\n */\n function _updateBaseRateFromRedemption(\n uint256 _ETHDrawn,\n uint256 _price,\n uint256 _totalZUSDSupply\n ) internal returns (uint256) {\n uint256 decayedBaseRate = _calcDecayedBaseRate();\n\n /* Convert the drawn ETH back to ZUSD at face value rate (1 ZUSD:1 USD), in order to get\n * the fraction of total supply that was redeemed at face value. */\n uint256 redeemedZUSDFraction = _ETHDrawn.mul(_price).div(_totalZUSDSupply);\n\n uint256 newBaseRate = decayedBaseRate.add(redeemedZUSDFraction.div(BETA));\n newBaseRate = LiquityMath._min(newBaseRate, DECIMAL_PRECISION); // cap baseRate at a maximum of 100%\n //assert(newBaseRate <= DECIMAL_PRECISION); // This is already enforced in the line above\n assert(newBaseRate > 0); // Base rate is always non-zero after redemption\n\n // Update the baseRate state variable\n baseRate = newBaseRate;\n emit BaseRateUpdated(newBaseRate);\n\n _updateLastFeeOpTime();\n\n return newBaseRate;\n }\n\n /**\n Called when a full redemption occurs, and closes the trove.\n The redeemer swaps (debt - liquidation reserve) ZUSD for (debt - liquidation reserve) worth of ETH, so the ZUSD liquidation reserve left corresponds to the remaining debt.\n In order to close the trove, the ZUSD liquidation reserve is burned, and the corresponding debt is removed from the active pool.\n The debt recorded on the trove's struct is zero'd elswhere, in _closeTrove.\n Any surplus ETH left in the trove, is sent to the Coll surplus pool, and can be later claimed by the borrower.\n */\n function _redeemCloseTrove(\n ContractsCache memory _contractsCache,\n address _borrower,\n uint256 _ZUSD,\n uint256 _ETH\n ) internal {\n _contractsCache.zusdToken.burn(gasPoolAddress, _ZUSD);\n // Update Active Pool ZUSD, and send ETH to account\n _contractsCache.activePool.decreaseZUSDDebt(_ZUSD);\n\n // send ETH from Active Pool to CollSurplus Pool\n _contractsCache.collSurplusPool.accountSurplus(_borrower, _ETH);\n _contractsCache.activePool.sendETH(address(_contractsCache.collSurplusPool), _ETH);\n }\n}\n" + }, + "contracts/FeeDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/LiquityMath.sol\";\nimport \"./FeeDistributorStorage.sol\";\nimport \"./Dependencies/SafeMath.sol\";\n\ncontract FeeDistributor is CheckContract, FeeDistributorStorage, IFeeDistributor {\n using SafeMath for uint256;\n // --- Events ---\n\n event FeeSharingCollectorAddressChanged(address _feeSharingCollectorAddress);\n event ZeroStakingAddressChanged(address _zeroStakingAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event WrbtcAddressChanged(address _wrbtcAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event ZUSDDistributed(uint256 _zusdDistributedAmount);\n event RBTCistributed(uint256 _rbtcDistributedAmount);\n\n // --- Dependency setters ---\n\n function setAddresses(\n address _feeSharingCollectorAddress,\n address _zeroStakingAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _wrbtcAddress,\n address _zusdTokenAddress,\n address _activePoolAddress\n ) external override onlyOwner {\n checkContract(_feeSharingCollectorAddress);\n checkContract(_zeroStakingAddress);\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_wrbtcAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_activePoolAddress);\n\n feeSharingCollector = IFeeSharingCollector(_feeSharingCollectorAddress);\n zeroStaking = IZEROStaking(_zeroStakingAddress);\n borrowerOperations = IBorrowerOperations(_borrowerOperationsAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n wrbtc = IWrbtc(_wrbtcAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n activePoolAddress = _activePoolAddress;\n\n // Not entirely removing this as per request from @light\n FEE_TO_FEE_SHARING_COLLECTOR = LiquityMath.DECIMAL_PRECISION; // 100%\n\n emit FeeSharingCollectorAddressChanged(_feeSharingCollectorAddress);\n emit ZeroStakingAddressChanged(_zeroStakingAddress);\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit WrbtcAddressChanged(_wrbtcAddress);\n emit ZUSDTokenAddressChanged(_zusdTokenAddress);\n emit ActivePoolAddressSet(_activePoolAddress);\n }\n\n function setFeeToFeeSharingCollector(uint256 FEE_TO_FEE_SHARING_COLLECTOR_) public onlyOwner {\n FEE_TO_FEE_SHARING_COLLECTOR = FEE_TO_FEE_SHARING_COLLECTOR_;\n }\n\n function distributeFees() public override {\n require(\n msg.sender == address(borrowerOperations) || msg.sender == address(troveManager),\n \"FeeDistributor: invalid caller\"\n );\n uint256 zusdtoDistribute = zusdToken.balanceOf(address(this));\n uint256 rbtcToDistribute = address(this).balance;\n if (zusdtoDistribute != 0) {\n _distributeZUSD(zusdtoDistribute);\n }\n if (rbtcToDistribute != 0) {\n _distributeRBTC(rbtcToDistribute);\n }\n }\n\n function _distributeZUSD(uint256 toDistribute) internal {\n // Send fee to the FeeSharingCollector address\n uint256 feeToFeeSharingCollector = toDistribute.mul(FEE_TO_FEE_SHARING_COLLECTOR).div(\n LiquityMath.DECIMAL_PRECISION\n );\n zusdToken.approve(address(feeSharingCollector), feeToFeeSharingCollector);\n\n feeSharingCollector.transferTokens(address(zusdToken), uint96(feeToFeeSharingCollector));\n // Send fee to ZERO staking contract\n uint256 feeToZeroStaking = toDistribute.sub(feeToFeeSharingCollector);\n if (feeToZeroStaking != 0) {\n require(\n zusdToken.transfer(address(zeroStaking), feeToZeroStaking),\n \"Coudn't execute ZUSD transfer\"\n );\n zeroStaking.increaseF_ZUSD(feeToZeroStaking);\n }\n emit ZUSDDistributed(toDistribute);\n }\n\n function _distributeRBTC(uint256 toDistribute) internal {\n // Send fee to the feeSharingCollector address\n uint256 feeToFeeSharingCollector = toDistribute.mul(FEE_TO_FEE_SHARING_COLLECTOR).div(\n LiquityMath.DECIMAL_PRECISION\n );\n\n feeSharingCollector.transferRBTC{ value: feeToFeeSharingCollector }();\n\n // Send the ETH fee to the ZERO staking contract\n uint256 feeToZeroStaking = toDistribute.sub(feeToFeeSharingCollector);\n if (feeToZeroStaking != 0) {\n (bool success, ) = address(zeroStaking).call{ value: feeToZeroStaking }(\"\");\n require(success, \"FeeDistributor: sending ETH failed\");\n zeroStaking.increaseF_ETH(feeToZeroStaking);\n }\n emit RBTCistributed(toDistribute);\n }\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"FeeDistributor: caller is not ActivePool\");\n }\n\n receive() external payable {\n _requireCallerIsActivePool();\n }\n}\n" + }, + "contracts/FeeDistributorStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IFeeSharingCollector.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IWrbtc.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract FeeDistributorStorage is Ownable {\n string public constant NAME = \"FeeDistributor\";\n\n // --- Connected contract declarations ---\n\n IFeeSharingCollector public feeSharingCollector;\n\n IZEROStaking public zeroStaking;\n\n IBorrowerOperations public borrowerOperations;\n\n ITroveManager public troveManager;\n\n IWrbtc public wrbtc;\n\n IZUSDToken public zusdToken;\n\n address public activePoolAddress;\n\n //pct of fees sent to feeSharingCollector address\n uint256 public FEE_TO_FEE_SHARING_COLLECTOR;\n}\n" + }, + "contracts/GasPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/**\n * The purpose of this contract is to hold ZUSD tokens for gas compensation:\n * https://github.com/DistributedCollective/zero#gas-compensation\n * When a borrower opens a trove, an additional 50 ZUSD debt is issued,\n * and 50 ZUSD is minted and sent to this contract.\n * When a borrower closes their active trove, this gas compensation is refunded:\n * 50 ZUSD is burned from the this contract's balance, and the corresponding\n * 50 ZUSD debt on the trove is cancelled.\n * See this issue for more context: https://github.com/liquity/dev/issues/186\n */\ncontract GasPool {\n // do nothing, as the core contracts have permission to send to and burn from this address\n}\n" + }, + "contracts/HintHelpers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./HintHelpersStorage.sol\";\n\ncontract HintHelpers is LiquityBase, HintHelpersStorage, CheckContract {\n // --- Events ---\n\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event TroveManagerAddressChanged(address _troveManagerAddress);\n\n // --- Dependency setters ---\n\n function setAddresses(\n address _liquityBaseParamsAddress,\n address _sortedTrovesAddress,\n address _troveManagerAddress\n ) external onlyOwner {\n checkContract(_liquityBaseParamsAddress);\n checkContract(_sortedTrovesAddress);\n checkContract(_troveManagerAddress);\n\n liquityBaseParams = ILiquityBaseParams(_liquityBaseParamsAddress);\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n\n emit SortedTrovesAddressChanged(_sortedTrovesAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n }\n\n // --- Functions ---\n\n /** getRedemptionHints() - Helper function for finding the right hints to pass to redeemCollateral().\n *\n * It simulates a redemption of `_ZUSDamount` to figure out where the redemption sequence will start and what state the final Trove\n * of the sequence will end up in.\n *\n * Returns three hints:\n * - `firstRedemptionHint` is the address of the first Trove with ICR >= MCR (i.e. the first Trove that will be redeemed).\n * - `partialRedemptionHintNICR` is the final nominal ICR of the last Trove of the sequence after being hit by partial redemption,\n * or zero in case of no partial redemption.\n * - `truncatedZUSDamount` is the maximum amount that can be redeemed out of the the provided `_ZUSDamount`. This can be lower than\n * `_ZUSDamount` when redeeming the full amount would leave the last Trove of the redemption sequence with less net debt than the\n * minimum allowed value (i.e. MIN_NET_DEBT).\n *\n * The number of Troves to consider for redemption can be capped by passing a non-zero value as `_maxIterations`, while passing zero\n * will leave it uncapped.\n */\n\n function getRedemptionHints(\n uint256 _ZUSDamount,\n uint256 _price,\n uint256 _maxIterations\n )\n external\n view\n returns (\n address firstRedemptionHint,\n uint256 partialRedemptionHintNICR,\n uint256 truncatedZUSDamount\n )\n {\n ISortedTroves sortedTrovesCached = sortedTroves;\n\n uint256 remainingZUSD = _ZUSDamount;\n address currentTroveuser = sortedTrovesCached.getLast();\n\n while (\n currentTroveuser != address(0) &&\n troveManager.getCurrentICR(currentTroveuser, _price) < liquityBaseParams.MCR()\n ) {\n currentTroveuser = sortedTrovesCached.getPrev(currentTroveuser);\n }\n\n firstRedemptionHint = currentTroveuser;\n\n if (_maxIterations == 0) {\n _maxIterations = uint256(-1);\n }\n\n while (currentTroveuser != address(0) && remainingZUSD > 0 && _maxIterations-- > 0) {\n uint256 netZUSDDebt = _getNetDebt(troveManager.getTroveDebt(currentTroveuser)).add(\n troveManager.getPendingZUSDDebtReward(currentTroveuser)\n );\n\n if (netZUSDDebt > remainingZUSD) {\n if (netZUSDDebt > MIN_NET_DEBT) {\n uint256 maxRedeemableZUSD = LiquityMath._min(\n remainingZUSD,\n netZUSDDebt.sub(MIN_NET_DEBT)\n );\n\n uint256 ETH = troveManager.getTroveColl(currentTroveuser).add(\n troveManager.getPendingETHReward(currentTroveuser)\n );\n\n uint256 newColl = ETH.sub(\n maxRedeemableZUSD.mul(DECIMAL_PRECISION).div(_price)\n );\n uint256 newDebt = netZUSDDebt.sub(maxRedeemableZUSD);\n\n uint256 compositeDebt = _getCompositeDebt(newDebt);\n partialRedemptionHintNICR = LiquityMath._computeNominalCR(\n newColl,\n compositeDebt\n );\n\n remainingZUSD = remainingZUSD.sub(maxRedeemableZUSD);\n }\n break;\n } else {\n remainingZUSD = remainingZUSD.sub(netZUSDDebt);\n }\n\n currentTroveuser = sortedTrovesCached.getPrev(currentTroveuser);\n }\n\n truncatedZUSDamount = _ZUSDamount.sub(remainingZUSD);\n }\n\n /** getApproxHint() - return address of a Trove that is, on average, (length / numTrials) positions away in the \n sortedTroves list from the correct insert position of the Trove to be inserted. \n \n Note: The output address is worst-case O(n) positions away from the correct insert position, however, the function \n is probabilistic. Input can be tuned to guarantee results to a high degree of confidence, e.g:\n\n Submitting numTrials = k * sqrt(length), with k = 15 makes it very, very likely that the ouput address will \n be <= sqrt(length) positions away from the correct insert position.\n */\n function getApproxHint(\n uint256 _CR,\n uint256 _numTrials,\n uint256 _inputRandomSeed\n )\n external\n view\n returns (\n address hintAddress,\n uint256 diff,\n uint256 latestRandomSeed\n )\n {\n uint256 arrayLength = troveManager.getTroveOwnersCount();\n\n if (arrayLength == 0) {\n return (address(0), 0, _inputRandomSeed);\n }\n\n hintAddress = sortedTroves.getLast();\n diff = LiquityMath._getAbsoluteDifference(_CR, troveManager.getNominalICR(hintAddress));\n latestRandomSeed = _inputRandomSeed;\n\n uint256 i = 1;\n\n while (i < _numTrials) {\n latestRandomSeed = uint256(keccak256(abi.encodePacked(latestRandomSeed)));\n\n uint256 arrayIndex = latestRandomSeed % arrayLength;\n address currentAddress = troveManager.getTroveFromTroveOwnersArray(arrayIndex);\n uint256 currentNICR = troveManager.getNominalICR(currentAddress);\n\n // check if abs(current - CR) > abs(closest - CR), and update closest if current is closer\n uint256 currentDiff = LiquityMath._getAbsoluteDifference(currentNICR, _CR);\n\n if (currentDiff < diff) {\n diff = currentDiff;\n hintAddress = currentAddress;\n }\n i++;\n }\n }\n\n function computeNominalCR(uint256 _coll, uint256 _debt) external pure returns (uint256) {\n return LiquityMath._computeNominalCR(_coll, _debt);\n }\n\n function computeCR(\n uint256 _coll,\n uint256 _debt,\n uint256 _price\n ) external pure returns (uint256) {\n return LiquityMath._computeCR(_coll, _debt, _price);\n }\n}\n" + }, + "contracts/HintHelpersStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract HintHelpersStorage is Ownable {\n string public constant NAME = \"HintHelpers\";\n\n ISortedTroves public sortedTroves;\n ITroveManager public troveManager;\n}\n" + }, + "contracts/Interfaces/IActivePool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IPool.sol\";\n\n/**\n * The Active Pool holds the ETH collateral and ZUSD debt (but not ZUSD tokens) for all active troves.\n *\n * When a trove is liquidated, it's ETH and ZUSD debt are transferred from the Active Pool, to either the\n * Stability Pool, the Default Pool, or both, depending on the liquidation conditions.\n *\n */\ninterface IActivePool is IPool {\n // --- Events ---\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolZUSDDebtUpdated(uint _ZUSDDebt);\n event ActivePoolETHBalanceUpdated(uint _ETH);\n\n // --- Functions ---\n\n /// @notice Send ETH amount to given account. Updates ActivePool balance. Only callable by BorrowerOperations, TroveManager or StabilityPool.\n /// @param _account account to receive the ETH amount\n /// @param _amount ETH amount to send\n function sendETH(address _account, uint _amount) external;\n}\n" + }, + "contracts/Interfaces/IBalanceRedirectPresale.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IBalanceRedirectPresale {\n\n function isClosed() external view returns (bool);\n}" + }, + "contracts/Interfaces/IBorrowerOperations.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../Dependencies/Mynt/IMassetManager.sol\";\n\n/// Common interface for the Trove Manager.\ninterface IBorrowerOperations {\n // --- Events ---\n\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n\n event TroveCreated(address indexed _borrower, uint256 arrayIndex);\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 stake,\n uint8 operation\n );\n event ZUSDBorrowingFeePaid(address indexed _borrower, uint256 _ZUSDFee);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _feeDistributorAddress feeDistributor contract address\n * @param _liquityBaseParamsAddress LiquidityBaseParams contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _activePoolAddress ActivePool contract address\n * @param _defaultPoolAddress DefaultPool contract address\n * @param _stabilityPoolAddress StabilityPool contract address\n * @param _gasPoolAddress GasPool contract address\n * @param _collSurplusPoolAddress CollSurplusPool contract address\n * @param _priceFeedAddress PrideFeed contract address\n * @param _sortedTrovesAddress SortedTroves contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _zeroStakingAddress ZEROStaking contract address\n */\n function setAddresses(\n address _feeDistributorAddress,\n address _liquityBaseParamsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _defaultPoolAddress,\n address _stabilityPoolAddress,\n address _gasPoolAddress,\n address _collSurplusPoolAddress,\n address _priceFeedAddress,\n address _sortedTrovesAddress,\n address _zusdTokenAddress,\n address _zeroStakingAddress\n ) external;\n\n /**\n * @notice payable function that creates a Trove for the caller with the requested debt, and the Ether received as collateral.\n * Successful execution is conditional mainly on the resulting collateralization ratio which must exceed the minimum (110% in Normal Mode, 150% in Recovery Mode).\n * In addition to the requested debt, extra debt is issued to pay the issuance fee, and cover the gas compensation.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _ZUSDAmount ZUSD requested debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function openTrove(\n uint256 _maxFee,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /**\n * @notice payable function that creates a Trove for the caller with the requested debt, and the Ether received as collateral.\n * Successful execution is conditional mainly on the resulting collateralization ratio which must exceed the minimum (110% in Normal Mode, 150% in Recovery Mode).\n * In addition to the requested debt, extra debt is issued to pay the issuance fee, and cover the gas compensation.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * This method is identical to `openTrove()`, but operates on NUE tokens instead of ZUSD.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _ZUSDAmount ZUSD requested debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function openNueTrove(\n uint256 _maxFee,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /// @notice payable function that adds the received Ether to the caller's active Trove.\n /// @param _upperHint upper trove id hint\n /// @param _lowerHint lower trove id hint\n function addColl(address _upperHint, address _lowerHint) external payable;\n\n /// @notice send ETH as collateral to a trove. Called by only the Stability Pool.\n /// @param _user user trove address\n /// @param _upperHint upper trove id hint\n /// @param _lowerHint lower trove id hint\n function moveETHGainToTrove(\n address _user,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /**\n * @notice withdraws `_amount` of collateral from the caller’s Trove.\n * Executes only if the user has an active Trove, the withdrawal would not pull the user’s Trove below the minimum collateralization ratio,\n * and the resulting total collateralization ratio of the system is above 150%.\n * @param _amount collateral amount to withdraw\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function withdrawColl(uint256 _amount, address _upperHint, address _lowerHint) external;\n\n /**\n * @notice issues `_amount` of ZUSD from the caller’s Trove to the caller.\n * Executes only if the Trove's collateralization ratio would remain above the minimum, and the resulting total collateralization ratio is above 150%.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _amount ZUSD amount to withdraw\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function withdrawZUSD(\n uint256 _maxFee,\n uint256 _amount,\n address _upperHint,\n address _lowerHint\n ) external;\n\n /// Borrow (withdraw) ZUSD tokens from a trove: mint new ZUSD tokens to the owner and convert it to DLLR in one transaction\n function withdrawZusdAndConvertToDLLR(\n uint256 _maxFeePercentage,\n uint256 _ZUSDAmount,\n address _upperHint,\n address _lowerHint\n ) external returns (uint256);\n\n /// @notice repay `_amount` of ZUSD to the caller’s Trove, subject to leaving 50 debt in the Trove (which corresponds to the 50 ZUSD gas compensation).\n /// @param _amount ZUSD amount to repay\n /// @param _upperHint upper trove id hint\n /// @param _lowerHint lower trove id hint\n function repayZUSD(uint256 _amount, address _upperHint, address _lowerHint) external;\n\n /// Repay ZUSD tokens to a Trove: Burn the repaid ZUSD tokens, and reduce the trove's debt accordingly\n function repayZusdFromDLLR(\n uint256 _dllrAmount,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external;\n\n /**\n * @notice allows a borrower to repay all debt, withdraw all their collateral, and close their Trove.\n * Requires the borrower have a ZUSD balance sufficient to repay their trove's debt, excluding gas compensation - i.e. `(debt - 50)` ZUSD.\n */\n function closeTrove() external;\n\n /**\n * @notice allows a borrower to repay all debt, withdraw all their collateral, and close their Trove.\n * Requires the borrower have a NUE balance sufficient to repay their trove's debt, excluding gas compensation - i.e. `(debt - 50)` NUE.\n * This method is identical to `closeTrove()`, but operates on NUE tokens instead of ZUSD.\n */\n function closeNueTrove(IMassetManager.PermitParams calldata _permitParams) external;\n\n /**\n * @notice enables a borrower to simultaneously change both their collateral and debt, subject to all the restrictions that apply to individual increases/decreases of each quantity with the following particularity:\n * if the adjustment reduces the collateralization ratio of the Trove, the function only executes if the resulting total collateralization ratio is above 150%.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * The parameter is ignored if the debt is not increased with the transaction.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _collWithdrawal collateral amount to withdraw\n * @param _debtChange ZUSD amount to change\n * @param isDebtIncrease indicates if increases debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function adjustTrove(\n uint256 _maxFee,\n uint256 _collWithdrawal,\n uint256 _debtChange,\n bool isDebtIncrease,\n address _upperHint,\n address _lowerHint\n ) external payable;\n\n /**\n * @notice enables a borrower to simultaneously change both their collateral and debt, subject to all the restrictions that apply to individual increases/decreases of each quantity with the following particularity:\n * if the adjustment reduces the collateralization ratio of the Trove, the function only executes if the resulting total collateralization ratio is above 150%.\n * The borrower has to provide a `_maxFeePercentage` that he/she is willing to accept in case of a fee slippage, i.e. when a redemption transaction is processed first, driving up the issuance fee.\n * The parameter is ignored if the debt is not increased with the transaction.\n * This method is identical to `adjustTrove()`, but operates on NUE tokens instead of ZUSD.\n * @param _maxFee max fee percentage to acept in case of a fee slippage\n * @param _collWithdrawal collateral amount to withdraw\n * @param _debtChange ZUSD amount to change\n * @param isDebtIncrease indicates if increases debt\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function adjustNueTrove(\n uint256 _maxFee,\n uint256 _collWithdrawal,\n uint256 _debtChange,\n bool isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n IMassetManager.PermitParams calldata _permitParams\n ) external payable;\n\n /**\n * @notice when a borrower’s Trove has been fully redeemed from and closed, or liquidated in Recovery Mode with a collateralization ratio above 110%,\n * this function allows the borrower to claim their ETH collateral surplus that remains in the system (collateral - debt upon redemption; collateral - 110% of the debt upon liquidation).\n */\n function claimCollateral() external;\n\n function getCompositeDebt(uint256 _debt) external view returns (uint256);\n\n function BORROWING_FEE_FLOOR() external view returns (uint256);\n\n function getMassetManager() external view returns (IMassetManager);\n}\n" + }, + "contracts/Interfaces/ICollSurplusPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface ICollSurplusPool {\n // --- Events ---\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n\n event CollBalanceUpdated(address indexed _account, uint256 _newBalance);\n event EtherSent(address _to, uint256 _amount);\n\n // --- Contract setters ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _borrowerOperationsAddress BorrowerOperations contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _activePoolAddress ActivePool contract address\n */\n function setAddresses(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress\n ) external;\n\n /// @notice Not necessarily equal to the raw ether balance - ether can be forcibly sent to contracts.\n /// @return ETH state variable\n function getETH() external view returns (uint256);\n\n /// @param _account account to retrieve collateral\n /// @return collateral\n function getCollateral(address _account) external view returns (uint256);\n\n /// @notice adds amount to current account balance. Only callable by TroveManager.\n /// @param _account account to add amount\n /// @param _amount amount to add\n function accountSurplus(address _account, uint256 _amount) external;\n\n /// @notice claims collateral for given account. Only callable by BorrowerOperations.\n /// @param _account account to send claimable collateral\n function claimColl(address _account) external;\n}\n" + }, + "contracts/Interfaces/ICommunityIssuance.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface ICommunityIssuance { \n \n // --- Events ---\n \n event SOVTokenAddressSet(address _zeroTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event StabilityPoolAddressSet(address _stabilityPoolAddress);\n event PriceFeedAddressSet(address _priceFeed);\n event RewardManagerAddressSet(address _rewardManagerAddress);\n event APRSet(uint256 _APR);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other contracts. Callable only by owner.\n * @dev initializer function, checks addresses are contracts\n * @param _zeroTokenAddress ZEROToken contract address\n * @param _communityPotAddress CommunityPot contract address\n */\n function initialize\n (\n address _zeroTokenAddress, \n address _communityPotAddress,\n address _fundingWalletAddress\n ) external;\n\n /**\n * @dev setter function to set the APR value in basis points.\n * can only be called by reward manager.\n * @param _APR apr value in basis points.\n */\n function setAPR(uint256 _APR) external;\n\n /**\n * @dev setter function to set the price feed.\n * can only be called by the owner.\n * @param _priceFeedAddress price feed address.\n */\n function setPriceFeed(address _priceFeedAddress) external;\n\n /**\n * @dev setter function to set reward manager.\n * can only be called by the owner.\n * @param _rewardManagerAddress reward manager address.\n */\n function setRewardManager(address _rewardManagerAddress) external;\n\n /// @notice issues SOV tokens based on total zusd is deposited.\n /// @return SOV tokens issuance \n function issueSOV(uint256 _totalZUSDDeposits) external returns (uint256);\n\n /// @notice sends ZERO tokens to given account\n /// @param _account account to receive the tokens\n /// @param _ZEROamount amount of tokens to transfer\n function sendSOV(address _account, uint _ZEROamount) external;\n}\n" + }, + "contracts/Interfaces/IDefaultPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IPool.sol\";\n\ninterface IDefaultPool is IPool {\n // --- Events ---\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event DefaultPoolZUSDDebtUpdated(uint256 _ZUSDDebt);\n event DefaultPoolETHBalanceUpdated(uint256 _ETH);\n\n // --- Functions ---\n\n /// @notice Send ETH to Active Pool\n /// @param _amount ETH to send\n function sendETHToActivePool(uint256 _amount) external;\n}\n" + }, + "contracts/Interfaces/IFeeDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n/// Common interface for Fee Distributor.\ninterface IFeeDistributor {\n // --- Events ---\n\n event FeeSharingCollectorAddressChanged(address _feeSharingCollectorAddress);\n event ZeroStakingAddressChanged(address _zeroStakingAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event WrbtcAddressChanged(address _wrbtcAddress);\n event ZUSDTokenAddressChanged(address _zusdTokenAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event ZUSDDistributed(uint256 _zusdDistributedAmount);\n event RBTCistributed(uint256 _rbtcDistributedAmount);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _feeSharingCollectorAddress FeeSharingCollector address\n * @param _zeroStakingAddress ZEROStaking contract address\n * @param _borrowerOperationsAddress borrowerOperations contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _wrbtcAddress wrbtc ERC20 contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _activePoolAddress ActivePool contract address\n */\n function setAddresses(\n address _feeSharingCollectorAddress,\n address _zeroStakingAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _wrbtcAddress,\n address _zusdTokenAddress,\n address _activePoolAddress\n ) external;\n\n function distributeFees() external;\n}\n" + }, + "contracts/Interfaces/IFeeSharingCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\n/**\n * @title Interface for Sovryn protocol fee sharing collector.\n * @dev Interfaces are used to cast a contract address into a callable instance.\n * */\ninterface IFeeSharingCollector {\n\tfunction withdrawFees(address _token) external;\n\n\tfunction transferTokens(address _token, uint96 _amount) external;\n\n\tfunction withdraw(\n\t\taddress _loanPoolToken,\n\t\tuint32 _maxCheckpoints,\n\t\taddress _receiver\n\t) external;\n\n\tfunction transferRBTC() external payable;\n}\n" + }, + "contracts/Interfaces/ILiquityBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./IPriceFeed.sol\";\nimport \"./ILiquityBaseParams.sol\";\n\ninterface ILiquityBase {\n /// @return PriceFeed contract\n function priceFeed() external view returns (IPriceFeed);\n\n /// @return LiquityBaseParams contract\n function liquityBaseParams() external view returns (ILiquityBaseParams);\n}\n" + }, + "contracts/Interfaces/ILiquityBaseParams.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface ILiquityBaseParams {\n\n /// Minimum collateral ratio for individual troves\n function MCR() external view returns (uint);\n\n /// Critical system collateral ratio. If the system's total collateral ratio (TCR) falls below the CCR, Recovery Mode is triggered.\n function CCR() external view returns (uint);\n\n function PERCENT_DIVISOR() external view returns (uint);\n\n function BORROWING_FEE_FLOOR() external view returns (uint);\n\n /**\n * Half-life of 12h. 12h = 720 min\n * (1/2) = d^720 => d = (1/2)^(1/720)\n */\n function REDEMPTION_FEE_FLOOR() external view returns (uint);\n\n function MAX_BORROWING_FEE() external view returns (uint);\n\n}" + }, + "contracts/Interfaces/IPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// Common interface for the Pools.\ninterface IPool {\n // --- Events ---\n\n event ETHBalanceUpdated(uint _newBalance);\n event ZUSDBalanceUpdated(uint _newBalance);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n event DefaultPoolAddressChanged(address _newDefaultPoolAddress);\n event StabilityPoolAddressChanged(address _newStabilityPoolAddress);\n event EtherSent(address _to, uint _amount);\n\n // --- Functions ---\n\n /// @notice Not necessarily equal to the raw ether balance - ether can be forcibly sent to contracts.\n /// @return ETH pool balance\n function getETH() external view returns (uint);\n\n /// @return ZUSD debt pool balance\n function getZUSDDebt() external view returns (uint);\n\n /// @notice Increases ZUSD debt of the pool.\n /// @param _amount ZUSD amount to add to the pool debt\n function increaseZUSDDebt(uint _amount) external;\n\n /// @notice Decreases ZUSD debt of the pool.\n /// @param _amount ZUSD amount to subtract to the pool debt\n function decreaseZUSDDebt(uint _amount) external;\n}\n" + }, + "contracts/Interfaces/IPriceFeed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IPriceFeed {\n // --- Events ---\n event LastGoodPriceUpdated(uint256 _lastGoodPrice);\n\n // --- Function ---\n\n /// @notice Returns the latest price obtained from the Oracle. Called by Zero functions that require a current price.\n /// It uses the main price feed and fallback to the backup one in case of an error. If both fail return the last\n /// good price seen.\n /// @dev It's also callable by anyone externally\n /// @return The price\n function fetchPrice() external returns (uint256);\n}\n" + }, + "contracts/Interfaces/IPriceFeedSovryn.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IPriceFeedSovryn {\n function queryRate(address sourceToken, address destToken)\n external\n view\n returns (uint256 rate, uint256 precision);\n\n function queryPrecision(address sourceToken, address destToken)\n external\n view\n returns (uint256 precision);\n\n function queryReturn(\n address sourceToken,\n address destToken,\n uint256 sourceAmount\n ) external view returns (uint256 destAmount);\n\n function checkPriceDisagreement(\n address sourceToken,\n address destToken,\n uint256 sourceAmount,\n uint256 destAmount,\n uint256 maxSlippage\n ) external view returns (uint256 sourceToDestSwapRate);\n\n function amountInEth(address Token, uint256 amount) external view returns (uint256 ethAmount);\n\n function getMaxDrawdown(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount,\n uint256 maintenanceMargin\n ) external view returns (uint256);\n\n function getCurrentMarginAndCollateralSize(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount\n ) external view returns (uint256 currentMargin, uint256 collateralInEthAmount);\n\n function getCurrentMargin(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount\n ) external view returns (uint256 currentMargin, uint256 collateralToLoanRate);\n\n function shouldLiquidate(\n address loanToken,\n address collateralToken,\n uint256 loanAmount,\n uint256 collateralAmount,\n uint256 maintenanceMargin\n ) external view returns (bool);\n\n function getFastGasPrice(address payToken) external view returns (uint256);\n}\n" + }, + "contracts/Interfaces/ISortedTroves.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n// Common interface for the SortedTroves Doubly Linked List.\ninterface ISortedTroves {\n // --- Events ---\n\n event SortedTrovesAddressChanged(address _sortedDoublyLLAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event NodeAdded(address _id, uint256 _NICR);\n event NodeRemoved(address _id);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts and size. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _size max size of troves list\n * @param _TroveManagerAddress TroveManager contract address\n * @param _borrowerOperationsAddress BorrowerOperations contract address\n */\n function setParams(\n uint256 _size,\n address _TroveManagerAddress,\n address _borrowerOperationsAddress\n ) external;\n\n /**\n * @dev Add a node to the list\n * @param _id Node's id\n * @param _ICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function insert(\n address _id,\n uint256 _ICR,\n address _prevId,\n address _nextId\n ) external;\n\n /**\n * @dev Remove a node from the list\n * @param _id Node's id\n */\n function remove(address _id) external;\n\n /**\n * @dev Re-insert the node at a new position, based on its new NICR\n * @param _id Node's id\n * @param _newICR Node's new NICR\n * @param _prevId Id of previous node for the new insert position\n * @param _nextId Id of next node for the new insert position\n */\n function reInsert(\n address _id,\n uint256 _newICR,\n address _prevId,\n address _nextId\n ) external;\n\n /**\n * @dev Checks if the list contains a node\n * @param _id Node's id\n * @return true if list contains a node with given id\n */\n function contains(address _id) external view returns (bool);\n\n /**\n * @dev Checks if the list is full\n * @return true if list is full\n */\n function isFull() external view returns (bool);\n\n /**\n * @dev Checks if the list is empty\n * @return true if list is empty\n */\n function isEmpty() external view returns (bool);\n\n /**\n * @return list current size\n */\n function getSize() external view returns (uint256);\n\n /**\n * @return list max size\n */\n function getMaxSize() external view returns (uint256);\n\n /**\n * @return the first node in the list (node with the largest NICR)\n */\n function getFirst() external view returns (address);\n\n /**\n * @return the last node in the list (node with the smallest NICR)\n */\n function getLast() external view returns (address);\n\n /**\n * @param _id Node's id\n * @return the next node (with a smaller NICR) in the list for a given node\n */\n function getNext(address _id) external view returns (address);\n\n /**\n * @param _id Node's id\n * @return the previous node (with a larger NICR) in the list for a given node\n */\n function getPrev(address _id) external view returns (address);\n\n /**\n * @notice Check if a pair of nodes is a valid insertion point for a new node with the given NICR\n * @param _ICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function validInsertPosition(\n uint256 _ICR,\n address _prevId,\n address _nextId\n ) external view returns (bool);\n\n /**\n * @notice Find the insert position for a new node with the given NICR\n * @param _ICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function findInsertPosition(\n uint256 _ICR,\n address _prevId,\n address _nextId\n ) external view returns (address, address);\n}\n" + }, + "contracts/Interfaces/IStabilityPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../Dependencies/Mynt/IMassetManager.sol\";\n\n/*\n * The Stability Pool holds ZUSD tokens deposited by Stability Pool depositors.\n *\n * When a trove is liquidated, then depending on system conditions, some of its ZUSD debt gets offset with\n * ZUSD in the Stability Pool: that is, the offset debt evaporates, and an equal amount of ZUSD tokens in the Stability Pool is burned.\n *\n * Thus, a liquidation causes each depositor to receive a ZUSD loss, in proportion to their deposit as a share of total deposits.\n * They also receive an ETH gain, as the ETH collateral of the liquidated trove is distributed among Stability depositors,\n * in the same proportion.\n *\n * When a liquidation occurs, it depletes every deposit by the same fraction: for example, a liquidation that depletes 40%\n * of the total ZUSD in the Stability Pool, depletes 40% of each deposit.\n *\n * A deposit that has experienced a series of liquidations is termed a \"compounded deposit\": each liquidation depletes the deposit,\n * multiplying it by some factor in range ]0,1[\n *\n * Please see the implementation spec in the proof document, which closely follows on from the compounded deposit / ETH gain derivations:\n * https://github.com/liquity/liquity/blob/master/papers/Scalable_Reward_Distribution_with_Compounding_Stakes.pdf\n *\n * --- SOV ISSUANCE TO STABILITY POOL DEPOSITORS ---\n *\n * An SOV issuance event occurs at every deposit operation, and every liquidation.\n *\n * Each deposit is tagged with the address of the front end through which it was made.\n *\n * All deposits earn a share of the issued SOV in proportion to the deposit as a share of total deposits. The SOV earned\n * by a given deposit, is split between the depositor and the front end through which the deposit was made, based on the front end's kickbackRate.\n *\n * Please see the system Readme for an overview:\n * https://github.com/liquity/dev/blob/main/README.md#zero-issuance-to-stability-providers\n */\ninterface IStabilityPool {\n // --- Events ---\n\n event StabilityPoolETHBalanceUpdated(uint _newBalance);\n event StabilityPoolZUSDBalanceUpdated(uint _newBalance);\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n event DefaultPoolAddressChanged(address _newDefaultPoolAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event SortedTrovesAddressChanged(address _newSortedTrovesAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event CommunityIssuanceAddressChanged(address _newCommunityIssuanceAddress);\n\n event P_Updated(uint _P);\n event S_Updated(uint _S, uint128 _epoch, uint128 _scale);\n event G_Updated(uint _G, uint128 _epoch, uint128 _scale);\n event EpochUpdated(uint128 _currentEpoch);\n event ScaleUpdated(uint128 _currentScale);\n\n event FrontEndRegistered(address indexed _frontEnd, uint _kickbackRate);\n event FrontEndTagSet(address indexed _depositor, address indexed _frontEnd);\n\n event DepositSnapshotUpdated(address indexed _depositor, uint _P, uint _S, uint _G);\n event FrontEndSnapshotUpdated(address indexed _frontEnd, uint _P, uint _G);\n event UserDepositChanged(address indexed _depositor, uint _newDeposit);\n event FrontEndStakeChanged(\n address indexed _frontEnd,\n uint _newFrontEndStake,\n address _depositor\n );\n\n event ETHGainWithdrawn(address indexed _depositor, uint _ETH, uint _ZUSDLoss);\n event SOVPaidToDepositor(address indexed _depositor, uint _SOV);\n event SOVPaidToFrontEnd(address indexed _frontEnd, uint _SOV);\n event EtherSent(address _to, uint _amount);\n\n event WithdrawFromSpAndConvertToDLLR(\n address _depositor,\n uint256 _zusdAmountRequested,\n uint256 _dllrAmountReceived\n );\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Liquity contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _liquityBaseParamsAddress LiquidityBaseParams contract address\n * @param _borrowerOperationsAddress BorrowerOperations contract address\n * @param _troveManagerAddress TroveManager contract address\n * @param _activePoolAddress ActivePool contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _sortedTrovesAddress SortedTroves contract address\n * @param _priceFeedAddress PriceFeed contract address\n * @param _communityIssuanceAddress CommunityIssuanceAddress\n */\n function setAddresses(\n address _liquityBaseParamsAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _zusdTokenAddress,\n address _sortedTrovesAddress,\n address _priceFeedAddress,\n address _communityIssuanceAddress\n ) external;\n\n /**\n * @notice Initial checks:\n * - Frontend is registered or zero address\n * - Sender is not a registered frontend\n * - _amount is not zero\n * ---\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Tags the deposit with the provided front end tag param, if it's a new deposit\n * - Sends depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Increases deposit and tagged front end's stake, and takes new snapshots for each.\n * @param _amount amount to provide\n * @param _frontEndTag frontend address to receive accumulated SOV gains\n */\n function provideToSP(uint _amount, address _frontEndTag) external;\n\n /**\n * @notice Initial checks:\n * - _amount is zero or there are no under collateralized troves left in the system\n * - User has a non zero deposit\n * ---\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Removes the deposit's front end tag if it is a full withdrawal\n * - Sends all depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Decreases deposit and tagged front end's stake, and takes new snapshots for each.\n *\n * If _amount > userDeposit, the user withdraws all of their compounded deposit.\n * @param _amount amount to withdraw\n */\n function withdrawFromSP(uint _amount) external;\n\n /**\n * @notice Initial checks:\n * - User has a non zero deposit\n * - User has an open trove\n * - User has some ETH gain\n * ---\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Sends all depositor's SOV gain to depositor\n * - Sends all tagged front end's SOV gain to the tagged front end\n * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove\n * - Leaves their compounded deposit in the Stability Pool\n * - Updates snapshots for deposit and tagged front end stake\n * @param _upperHint upper trove id hint\n * @param _lowerHint lower trove id hint\n */\n function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external;\n\n /**\n * @notice Initial checks:\n * - Frontend (sender) not already registered\n * - User (sender) has no deposit\n * - _kickbackRate is in the range [0, 100%]\n * ---\n * Front end makes a one-time selection of kickback rate upon registering\n * @param _kickbackRate kickback rate selected by frontend\n */\n function registerFrontEnd(uint _kickbackRate) external;\n\n /**\n * @notice Initial checks:\n * - Caller is TroveManager\n * ---\n * Cancels out the specified debt against the ZUSD contained in the Stability Pool (as far as possible)\n * and transfers the Trove's ETH collateral from ActivePool to StabilityPool.\n * Only called by liquidation functions in the TroveManager.\n * @param _debt debt to cancel\n * @param _coll collateral to transfer\n */\n function offset(uint _debt, uint _coll) external;\n\n /**\n * @return the total amount of ETH held by the pool, accounted in an internal variable instead of `balance`,\n * to exclude edge cases like ETH received from a self-destruct.\n */\n function getETH() external view returns (uint);\n\n /**\n * @return ZUSD held in the pool. Changes when users deposit/withdraw, and when Trove debt is offset.\n */\n function getTotalZUSDDeposits() external view returns (uint);\n\n /**\n * @notice Calculates the ETH gain earned by the deposit since its last snapshots were taken.\n * @param _depositor address to calculate ETH gain\n * @return ETH gain from given depositor\n */\n function getDepositorETHGain(address _depositor) external view returns (uint);\n\n /**\n * @notice Calculate the SOV gain earned by a deposit since its last snapshots were taken.\n * If not tagged with a front end, the depositor gets a 100% cut of what their deposit earned.\n * Otherwise, their cut of the deposit's earnings is equal to the kickbackRate, set by the front end through\n * which they made their deposit.\n * @param _depositor address to calculate ETH gain\n * @return SOV gain from given depositor\n */\n function getDepositorSOVGain(address _depositor) external view returns (uint);\n\n /**\n * @param _frontEnd front end address\n * @return the SOV gain earned by the front end.\n */\n function getFrontEndSOVGain(address _frontEnd) external view returns (uint);\n\n /**\n * @param _depositor depositor address\n * @return the user's compounded deposit.\n */\n function getCompoundedZUSDDeposit(address _depositor) external view returns (uint);\n\n /**\n * @notice The front end's compounded stake is equal to the sum of its depositors' compounded deposits.\n * @param _frontEnd front end address\n * @return the front end's compounded stake.\n */\n function getCompoundedFrontEndStake(address _frontEnd) external view returns (uint);\n\n //DLLR _owner or _spender can convert a specified amount of DLLR into ZUSD via Sovryn Mynt and deposit the ZUSD into the SOV Stability Pool, all in a single transaction\n function provideToSpFromDLLR(\n uint _dllrAmount,\n IMassetManager.PermitParams calldata _permitParams\n ) external;\n\n /// Stability Pool depositor can withdraw a specified amount of ZUSD from the SOV Stability Pool and optionally convert the ZUSD to DLLR via Sovryn Mynt, all in a single transaction\n function withdrawFromSpAndConvertToDLLR(uint256 _zusdAmount) external;\n\n /**\n * Fallback function\n * Only callable by Active Pool, it just accounts for ETH received\n * receive() external payable;\n */\n}\n" + }, + "contracts/Interfaces/ITroveManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./ILiquityBase.sol\";\nimport \"./IStabilityPool.sol\";\nimport \"./IZUSDToken.sol\";\nimport \"./IZEROToken.sol\";\nimport \"./IZEROStaking.sol\";\nimport \"../Dependencies/Mynt/IMassetManager.sol\";\n\n/// Common interface for the Trove Manager.\ninterface ITroveManager is ILiquityBase {\n // --- Events ---\n\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerRedeemOpsAddressChanged(address _troveManagerRedeemOps);\n event LiquityBaseParamsAddressChanges(address _borrowerOperationsAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZEROTokenAddressChanged(address _zeroTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n\n event Liquidation(\n uint256 _liquidatedDebt,\n uint256 _liquidatedColl,\n uint256 _collGasCompensation,\n uint256 _ZUSDGasCompensation\n );\n event Redemption(\n uint256 _attemptedZUSDAmount,\n uint256 _actualZUSDAmount,\n uint256 _ETHSent,\n uint256 _ETHFee\n );\n event TroveUpdated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint256 stake,\n uint8 operation\n );\n event TroveLiquidated(\n address indexed _borrower,\n uint256 _debt,\n uint256 _coll,\n uint8 operation\n );\n event BaseRateUpdated(uint256 _baseRate);\n event LastFeeOpTimeUpdated(uint256 _lastFeeOpTime);\n event TotalStakesUpdated(uint256 _newTotalStakes);\n event SystemSnapshotsUpdated(uint256 _totalStakesSnapshot, uint256 _totalCollateralSnapshot);\n event LTermsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveSnapshotsUpdated(uint256 _L_ETH, uint256 _L_ZUSDDebt);\n event TroveIndexUpdated(address _borrower, uint256 _newIndex);\n\n struct TroveManagerInitAddressesParams {\n address _feeDistributorAddress;\n address _troveManagerRedeemOps;\n address _liquityBaseParamsAddress;\n address _borrowerOperationsAddress;\n address _activePoolAddress;\n address _defaultPoolAddress;\n address _stabilityPoolAddress;\n address _gasPoolAddress;\n address _collSurplusPoolAddress;\n address _priceFeedAddress;\n address _zusdTokenAddress;\n address _sortedTrovesAddress;\n address _zeroTokenAddress;\n address _zeroStakingAddress;\n }\n\n // --- Functions ---\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _troveManagerInitAddresses addresses list to intialize TroveManager with _\n * _feeDistributorAddress feeDistributor contract address\n * _troveManagerRedeemOps TroveManagerRedeemOps contract address\n * _liquityBaseParamsAddress LiquityBaseParams contract address\n * _borrowerOperationsAddress BorrowerOperations contract address\n * _activePoolAddress ActivePool contract address\n * _defaultPoolAddress DefaultPool contract address\n * _stabilityPoolAddress StabilityPool contract address\n * _gasPoolAddress GasPool contract address\n * _collSurplusPoolAddress CollSurplusPool contract address\n * _priceFeedAddress PriceFeed contract address\n * _zusdTokenAddress ZUSDToken contract address\n * _sortedTrovesAddress SortedTroves contract address\n * _zeroTokenAddress ZEROToken contract address\n * _zeroStakingAddress ZEROStaking contract address\n */\n function setAddresses(\n TroveManagerInitAddressesParams memory _troveManagerInitAddresses\n ) external;\n\n function setTroveManagerRedeemOps(address _troveManagerRedeemOps) external;\n\n /// @return Trove owners count\n function getTroveOwnersCount() external view returns (uint256);\n\n /// @param _index Trove owner index\n /// @return Trove from TroveOwners array in given index\n function getTroveFromTroveOwnersArray(uint256 _index) external view returns (address);\n\n /// @param _borrower borrower address\n /// @return the nominal collateral ratio (ICR) of a given Trove, without the price. Takes a trove's pending coll and debt rewards from redistributions into account.\n function getNominalICR(address _borrower) external view returns (uint256);\n\n /// @notice computes the user’s individual collateralization ratio (ICR) based on their total collateral and total ZUSD debt. Returns 2^256 -1 if they have 0 debt.\n /// @param _borrower borrower address\n /// @param _price ETH price\n /// @return the current collateral ratio (ICR) of a given Trove. Takes a trove's pending coll and debt rewards from redistributions into account.\n function getCurrentICR(address _borrower, uint256 _price) external view returns (uint256);\n\n /// @notice Closes the trove if its ICR is lower than the minimum collateral ratio.\n /// @param _borrower borrower address\n function liquidate(address _borrower) external;\n\n /**\n * @notice Liquidate a sequence of troves. Closes a maximum number of n under-collateralized Troves,\n * starting from the one with the lowest collateral ratio in the system, and moving upwards\n * @param _n max number of under-collateralized Troves to liquidate\n */\n function liquidateTroves(uint256 _n) external;\n\n /**\n * @notice Attempt to liquidate a custom list of troves provided by the caller.\n * @param _troveArray list of trove addresses\n */\n function batchLiquidateTroves(address[] calldata _troveArray) external;\n\n /**\n * @notice Send _ZUSDamount ZUSD to the system and redeem the corresponding amount of collateral from as many Troves as are needed to fill the redemption\n * request. Applies pending rewards to a Trove before reducing its debt and coll.\n *\n * Note that if _amount is very large, this function can run out of gas, specially if traversed troves are small. This can be easily avoided by\n * splitting the total _amount in appropriate chunks and calling the function multiple times.\n *\n * Param `_maxIterations` can also be provided, so the loop through Troves is capped (if it’s zero, it will be ignored).This makes it easier to\n * avoid OOG for the frontend, as only knowing approximately the average cost of an iteration is enough, without needing to know the “topology”\n * of the trove list. It also avoids the need to set the cap in stone in the contract, nor doing gas calculations, as both gas price and opcode\n * costs can vary.\n *\n * All Troves that are redeemed from -- with the likely exception of the last one -- will end up with no debt left, therefore they will be closed.\n * If the last Trove does have some remaining debt, it has a finite ICR, and the reinsertion could be anywhere in the list, therefore it requires a hint.\n * A frontend should use getRedemptionHints() to calculate what the ICR of this Trove will be after redemption, and pass a hint for its position\n * in the sortedTroves list along with the ICR value that the hint was found for.\n *\n * If another transaction modifies the list between calling getRedemptionHints() and passing the hints to redeemCollateral(), it\n * is very likely that the last (partially) redeemed Trove would end up with a different ICR than what the hint is for. In this case the\n * redemption will stop after the last completely redeemed Trove and the sender will keep the remaining ZUSD amount, which they can attempt\n * to redeem later.\n *\n * @param _ZUSDAmount ZUSD amount to send to the system\n * @param _firstRedemptionHint calculated ICR hint of first trove after redemption\n * @param _maxIterations max Troves iterations (can be 0)\n * @param _maxFee max fee percentage to accept\n */\n function redeemCollateral(\n uint256 _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFee\n ) external;\n\n function redeemCollateralViaDLLR(\n uint256 _dllrAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage,\n IMassetManager.PermitParams calldata _permitParams\n ) external;\n\n /// @notice Update borrower's stake based on their latest collateral value\n /// @param _borrower borrower address\n function updateStakeAndTotalStakes(address _borrower) external returns (uint256);\n\n /// @notice Update borrower's snapshots of L_ETH and L_ZUSDDebt to reflect the current values\n /// @param _borrower borrower address\n function updateTroveRewardSnapshots(address _borrower) external;\n\n /// @notice Push the owner's address to the Trove owners list, and record the corresponding array index on the Trove struct\n /// @param _borrower borrower address\n /// @return index where Trove was inserted\n function addTroveOwnerToArray(address _borrower) external returns (uint256 index);\n\n /// @notice Add the borrowers's coll and debt rewards earned from redistributions, to their Trove\n /// @param _borrower borrower address\n function applyPendingRewards(address _borrower) external;\n\n /// @param _borrower borrower address\n /// @return the borrower's pending accumulated ETH reward, earned by their stake\n function getPendingETHReward(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return the borrower's pending accumulated ZUSD reward, earned by their stake\n function getPendingZUSDDebtReward(address _borrower) external view returns (uint256);\n\n /*\n * @notice A Trove has pending rewards if its snapshot is less than the current rewards per-unit-staked sum:\n * this indicates that rewards have occured since the snapshot was made, and the user therefore has\n * pending rewards\n *\n * @param _borrower borrower address\n * @return true if has pending rewards\n */\n function hasPendingRewards(address _borrower) external view returns (bool);\n\n /// @notice returns the Troves entire debt and coll, including pending rewards from redistributions.\n /// @param _borrower borrower address\n function getEntireDebtAndColl(\n address _borrower\n )\n external\n view\n returns (\n uint256 debt,\n uint256 coll,\n uint256 pendingZUSDDebtReward,\n uint256 pendingETHReward\n );\n\n /// @notice Close given trove. Called by BorrowerOperations.\n /// @param _borrower borrower address\n function closeTrove(address _borrower) external;\n\n /// @notice Remove borrower's stake from the totalStakes sum, and set their stake to 0\n /// @param _borrower borrower address\n function removeStake(address _borrower) external;\n\n /// @return calculated redemption rate using baseRate\n function getRedemptionRate() external view returns (uint256);\n\n /// @return calculated redemption rate using calculated decayed as base rate\n function getRedemptionRateWithDecay() external view returns (uint256);\n\n /// @notice The redemption fee is taken as a cut of the total ETH drawn from the system in a redemption. It is based on the current redemption rate.\n /// @param _ETHDrawn ETH drawn\n function getRedemptionFeeWithDecay(uint256 _ETHDrawn) external view returns (uint256);\n\n /// @return borrowing rate\n function getBorrowingRate() external view returns (uint256);\n\n /// @return borrowing rate calculated using decayed as base rate\n function getBorrowingRateWithDecay() external view returns (uint256);\n\n /// @param ZUSDDebt ZUSD debt amount to calculate fee\n /// @return borrowing fee using borrowing rate\n function getBorrowingFee(uint256 ZUSDDebt) external view returns (uint256);\n\n /// @param _ZUSDDebt ZUSD debt amount to calculate fee\n /// @return borrowing fee using borrowing rate with decay\n function getBorrowingFeeWithDecay(uint256 _ZUSDDebt) external view returns (uint256);\n\n /// @notice Updates the baseRate state variable based on time elapsed since the last redemption or ZUSD borrowing operation.\n function decayBaseRateFromBorrowing() external;\n\n /// @param _borrower borrower address\n /// @return Trove status from given trove\n function getTroveStatus(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return Trove stake from given trove\n function getTroveStake(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return Trove debt from given trove\n function getTroveDebt(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @return Trove collateral from given trove\n function getTroveColl(address _borrower) external view returns (uint256);\n\n /// @param _borrower borrower address\n /// @param num status to set\n function setTroveStatus(address _borrower, uint256 num) external;\n\n /// @param _borrower borrower address\n /// @param _collIncrease amount of collateral to increase\n /// @return new trove collateral\n function increaseTroveColl(\n address _borrower,\n uint256 _collIncrease\n ) external returns (uint256);\n\n /// @param _borrower borrower address\n /// @param _collDecrease amount of collateral to decrease\n /// @return new trove collateral\n function decreaseTroveColl(\n address _borrower,\n uint256 _collDecrease\n ) external returns (uint256);\n\n /// @param _borrower borrower address\n /// @param _debtIncrease amount of debt to increase\n /// @return new trove debt\n function increaseTroveDebt(\n address _borrower,\n uint256 _debtIncrease\n ) external returns (uint256);\n\n /// @param _borrower borrower address\n /// @param _debtDecrease amount of debt to decrease\n /// @return new trove debt\n function decreaseTroveDebt(\n address _borrower,\n uint256 _debtDecrease\n ) external returns (uint256);\n\n /**\n * @param _price ETH price\n * @return the total collateralization ratio (TCR) of the system.\n * The TCR is based on the the entire system debt and collateral (including pending rewards).\n */\n function getTCR(uint256 _price) external view returns (uint256);\n\n function MCR() external view returns (uint256);\n\n function CCR() external view returns (uint256);\n\n /// @notice reveals whether or not the system is in Recovery Mode (i.e. whether the Total Collateralization Ratio (TCR) is below the Critical Collateralization Ratio (CCR)).\n function checkRecoveryMode(uint256 _price) external view returns (bool);\n}\n" + }, + "contracts/Interfaces/IWrbtc.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Dependencies/IERC20.sol\";\n\ninterface IWrbtc is IERC20 {\n\t\n\tfunction deposit() external payable;\n\n\tfunction withdraw(uint256 wad) external;\n\n}\n" + }, + "contracts/Interfaces/IZEROStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\ninterface IZEROStaking {\n // --- Events --\n\n event ZEROTokenAddressSet(address _zeroTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event FeeDistributorAddressAddressSet(address _feeDistributorAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event StakeChanged(address indexed staker, uint256 newStake);\n event StakingGainsWithdrawn(address indexed staker, uint256 ZUSDGain, uint256 ETHGain);\n event F_ETHUpdated(uint256 _F_ETH);\n event F_ZUSDUpdated(uint256 _F_ZUSD);\n event TotalZEROStakedUpdated(uint256 _totalZEROStaked);\n event EtherSent(address _account, uint256 _amount);\n event StakerSnapshotsUpdated(address _staker, uint256 _F_ETH, uint256 _F_ZUSD);\n\n // --- Functions ---\n\n /**\n * @notice Called only once on init, to set addresses of other Zero contracts. Callable only by owner\n * @dev initializer function, checks addresses are contracts\n * @param _zeroTokenAddress ZEROToken contract address\n * @param _zusdTokenAddress ZUSDToken contract address\n * @param _feeDistributorAddress FeeDistributorAddress contract address\n * @param _activePoolAddress ActivePool contract address\n */\n function setAddresses(\n address _zeroTokenAddress,\n address _zusdTokenAddress,\n address _feeDistributorAddress,\n address _activePoolAddress\n ) external;\n\n /// @notice If caller has a pre-existing stake, send any accumulated ETH and ZUSD gains to them.\n /// @param _ZEROamount ZERO tokens to stake\n function stake(uint256 _ZEROamount) external;\n\n /**\n * @notice Unstake the ZERO and send the it back to the caller, along with their accumulated ZUSD & ETH gains.\n * If requested amount > stake, send their entire stake.\n * @param _ZEROamount ZERO tokens to unstake\n */\n function unstake(uint256 _ZEROamount) external;\n\n /// @param _ETHFee ETH fee\n /// @notice increase ETH fee\n function increaseF_ETH(uint256 _ETHFee) external;\n\n /// @param _ZEROFee ZUSD fee\n /// @notice increase ZUSD fee\n function increaseF_ZUSD(uint256 _ZEROFee) external;\n\n /// @param _user user address\n /// @return pending ETH gain of given user\n function getPendingETHGain(address _user) external view returns (uint256);\n\n /// @param _user user address\n /// @return pending ZUSD gain of given user\n function getPendingZUSDGain(address _user) external view returns (uint256);\n}\n" + }, + "contracts/Interfaces/IZEROToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Dependencies/IERC2612.sol\";\n\ninterface IZEROToken is IERC20, IERC2612 { \n\n // --- Functions ---\n\n /// @notice send zero tokens to ZEROStaking contract\n /// @param _sender sender address\n /// @param _amount amount to send\n function sendToZEROStaking(address _sender, uint256 _amount) external;\n\n /// @return deployment start time\n function getDeploymentStartTime() external view returns (uint256);\n\n}\n" + }, + "contracts/Interfaces/IZUSDToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Dependencies/IERC2612.sol\";\n\ninterface IZUSDToken is IERC20, IERC2612 { \n \n // --- Events ---\n\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event StabilityPoolAddressChanged(address _newStabilityPoolAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n\n event ZUSDTokenBalanceUpdated(address _user, uint _amount);\n\n // --- Functions ---\n\n function mint(address _account, uint256 _amount) external;\n\n function burn(address _account, uint256 _amount) external;\n\n function sendToPool(address _sender, address poolAddress, uint256 _amount) external;\n\n function returnFromPool(address poolAddress, address user, uint256 _amount ) external;\n}\n" + }, + "contracts/LiquityBaseParams.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ILiquityBaseParams.sol\";\nimport \"./Dependencies/BaseMath.sol\";\nimport \"./Dependencies/LiquityMath.sol\";\n\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/Initializable.sol\";\n\ncontract LiquityBaseParams is ILiquityBaseParams, Ownable, Initializable, BaseMath {\n using SafeMath for uint256;\n\n /// Minimum collateral ratio for individual troves\n uint256 public override MCR;\n\n /// Critical system collateral ratio. If the system's total collateral ratio (TCR) falls below the CCR, Recovery Mode is triggered.\n uint256 public override CCR;\n\n uint256 public override PERCENT_DIVISOR;\n\n uint256 public override BORROWING_FEE_FLOOR;\n\n /**\n * Half-life of 12h. 12h = 720 min\n * (1/2) = d^720 => d = (1/2)^(1/720)\n */\n uint256 public override REDEMPTION_FEE_FLOOR;\n\n uint256 public override MAX_BORROWING_FEE;\n\n function initialize() public initializer onlyOwner {\n MCR = 1100000000000000000; // 110%\n CCR = 1500000000000000000; // 150%\n PERCENT_DIVISOR = 200; // dividing by 200 yields 0.5%\n BORROWING_FEE_FLOOR = (DECIMAL_PRECISION / 1000) * 5; // 0.5%\n REDEMPTION_FEE_FLOOR = (DECIMAL_PRECISION / 1000) * 5; // 0.5%\n MAX_BORROWING_FEE = (DECIMAL_PRECISION / 100) * 5; // 5%\n }\n\n function setMCR(uint256 MCR_) public onlyOwner {\n MCR = MCR_;\n }\n\n function setCCR(uint256 CCR_) public onlyOwner {\n CCR = CCR_;\n }\n\n function setPercentDivisor(uint256 PERCENT_DIVISOR_) public onlyOwner {\n PERCENT_DIVISOR = PERCENT_DIVISOR_;\n }\n\n function setBorrowingFeeFloor(uint256 BORROWING_FEE_FLOOR_) public onlyOwner {\n BORROWING_FEE_FLOOR = BORROWING_FEE_FLOOR_;\n }\n\n function setRedemptionFeeFloor(uint256 REDEMPTION_FEE_FLOOR_) public onlyOwner {\n REDEMPTION_FEE_FLOOR = REDEMPTION_FEE_FLOOR_;\n }\n\n function setMaxBorrowingFee(uint256 MAX_BORROWING_FEE_) public onlyOwner {\n MAX_BORROWING_FEE = MAX_BORROWING_FEE_;\n }\n}\n" + }, + "contracts/MultiTroveGetter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./TroveManager.sol\";\nimport \"./SortedTroves.sol\";\nimport \"./MultiTroveGetterStorage.sol\";\n\n/** Helper contract for grabbing Trove data for the front end. Not part of the core Zero system. */\ncontract MultiTroveGetter is MultiTroveGetterStorage {\n struct CombinedTroveData {\n address owner;\n uint256 debt;\n uint256 coll;\n uint256 stake;\n uint256 snapshotETH;\n uint256 snapshotZUSDDebt;\n }\n\n function setAddresses(TroveManager _troveManager, ISortedTroves _sortedTroves)\n public\n onlyOwner\n {\n troveManager = _troveManager;\n sortedTroves = _sortedTroves;\n }\n\n function getMultipleSortedTroves(int256 _startIdx, uint256 _count)\n external\n view\n returns (CombinedTroveData[] memory _troves)\n {\n uint256 startIdx;\n bool descend;\n\n if (_startIdx >= 0) {\n startIdx = uint256(_startIdx);\n descend = true;\n } else {\n startIdx = uint256(-(_startIdx + 1));\n descend = false;\n }\n\n uint256 sortedTrovesSize = sortedTroves.getSize();\n\n if (startIdx >= sortedTrovesSize) {\n _troves = new CombinedTroveData[](0);\n } else {\n uint256 maxCount = sortedTrovesSize - startIdx;\n\n if (_count > maxCount) {\n _count = maxCount;\n }\n\n if (descend) {\n _troves = _getMultipleSortedTrovesFromHead(startIdx, _count);\n } else {\n _troves = _getMultipleSortedTrovesFromTail(startIdx, _count);\n }\n }\n }\n\n function _getMultipleSortedTrovesFromHead(uint256 _startIdx, uint256 _count)\n internal\n view\n returns (CombinedTroveData[] memory _troves)\n {\n address currentTroveowner = sortedTroves.getFirst();\n\n for (uint256 idx = 0; idx < _startIdx; ++idx) {\n currentTroveowner = sortedTroves.getNext(currentTroveowner);\n }\n\n _troves = new CombinedTroveData[](_count);\n\n for (uint256 idx = 0; idx < _count; ++idx) {\n _troves[idx].owner = currentTroveowner;\n (\n _troves[idx].debt,\n _troves[idx].coll,\n _troves[idx].stake,\n /* status */\n /* arrayIndex */\n ,\n\n ) = troveManager.Troves(currentTroveowner);\n (_troves[idx].snapshotETH, _troves[idx].snapshotZUSDDebt) = troveManager\n .rewardSnapshots(currentTroveowner);\n\n currentTroveowner = sortedTroves.getNext(currentTroveowner);\n }\n }\n\n function _getMultipleSortedTrovesFromTail(uint256 _startIdx, uint256 _count)\n internal\n view\n returns (CombinedTroveData[] memory _troves)\n {\n address currentTroveowner = sortedTroves.getLast();\n\n for (uint256 idx = 0; idx < _startIdx; ++idx) {\n currentTroveowner = sortedTroves.getPrev(currentTroveowner);\n }\n\n _troves = new CombinedTroveData[](_count);\n\n for (uint256 idx = 0; idx < _count; ++idx) {\n _troves[idx].owner = currentTroveowner;\n (\n _troves[idx].debt,\n _troves[idx].coll,\n _troves[idx].stake,\n /* status */\n /* arrayIndex */\n ,\n\n ) = troveManager.Troves(currentTroveowner);\n (_troves[idx].snapshotETH, _troves[idx].snapshotZUSDDebt) = troveManager\n .rewardSnapshots(currentTroveowner);\n\n currentTroveowner = sortedTroves.getPrev(currentTroveowner);\n }\n }\n}\n" + }, + "contracts/MultiTroveGetterStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\nimport \"./TroveManager.sol\";\nimport \"./SortedTroves.sol\";\nimport \"./Dependencies/Ownable.sol\";\n\ncontract MultiTroveGetterStorage is Ownable {\n TroveManager public troveManager; // XXX Troves missing from ITroveManager?\n ISortedTroves public sortedTroves;\n}\n" + }, + "contracts/PriceFeed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IPriceFeed.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./PriceFeedStorage.sol\";\n\n/// @title The system price feed adapter\n/// @notice The PriceFeed relies upon a main oracle and a secondary as a fallback in case of error\ncontract PriceFeed is PriceFeedStorage, IPriceFeed {\n event LastGoodPriceUpdated(uint256 _lastGoodPrice);\n event PriceFeedBroken(uint8 index, address priceFeedAddress);\n event PriceFeedUpdated(uint8 index, address newPriceFeedAddress);\n\n // --- Dependency setters ---\n\n function setAddresses(address _mainPriceFeed, address _backupPriceFeed) external onlyOwner {\n uint256 latestPrice = setAddress(0, _mainPriceFeed);\n setAddress(1, _backupPriceFeed);\n\n _storePrice(latestPrice);\n }\n\n // --- Functions ---\n\n /// @notice Returns the latest price obtained from the Oracle. Called by Zero functions that require a current price.\n /// It uses the main price feed and fallback to the backup one in case of an error. If both fail return the last\n /// good price seen.\n /// @dev It's also callable by anyone externally\n /// @return The price\n function fetchPrice() external override returns (uint256) {\n for (uint8 index = 0; index < 2; index++) {\n (uint256 price, bool success) = priceFeeds[index].latestAnswer();\n if (success) {\n _storePrice(price);\n return price;\n } else {\n emit PriceFeedBroken(index, address(priceFeeds[index]));\n }\n }\n return lastGoodPrice;\n }\n\n /// @notice Allows users to setup the main and the backup price feeds\n /// @param _index the oracle to be configured\n /// @param _newPriceFeed address where an IExternalPriceFeed implementation is located\n /// @return price the latest price of the inserted price feed\n function setAddress(uint8 _index, address _newPriceFeed) public onlyOwner returns (uint256) {\n require(_index < priceFeeds.length, \"Out of bounds when setting the price feed\");\n checkContract(_newPriceFeed);\n priceFeeds[_index] = IExternalPriceFeed(_newPriceFeed);\n (uint256 price, bool success) = priceFeeds[_index].latestAnswer();\n require(success, \"PriceFeed: Price feed must be working\");\n emit PriceFeedUpdated(_index, _newPriceFeed);\n return price;\n }\n\n // --- Helper functions ---\n function _storePrice(uint256 _currentPrice) internal {\n lastGoodPrice = _currentPrice;\n emit LastGoodPriceUpdated(_currentPrice);\n }\n}\n" + }, + "contracts/PriceFeedStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IPriceFeed.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/PriceFeed/IExternalPriceFeed.sol\";\nimport \"./Dependencies/CheckContract.sol\";\n\ncontract PriceFeedStorage is Ownable, CheckContract {\n string public constant NAME = \"PriceFeed\";\n\n IExternalPriceFeed[2] priceFeeds;\n\n // The last good price seen from an oracle by Zero\n uint256 public lastGoodPrice;\n}\n" + }, + "contracts/Proxy/BorrowerOperationsScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/IBorrowerOperations.sol\";\n\n\ncontract BorrowerOperationsScript is CheckContract {\n IBorrowerOperations immutable borrowerOperations;\n\n constructor(IBorrowerOperations _borrowerOperations) public {\n checkContract(address(_borrowerOperations));\n borrowerOperations = _borrowerOperations;\n }\n\n function openTrove(uint _maxFee, uint _ZUSDAmount, address _upperHint, address _lowerHint) external payable {\n borrowerOperations.openTrove{ value: msg.value }(_maxFee, _ZUSDAmount, _upperHint, _lowerHint);\n }\n\n function addColl(address _upperHint, address _lowerHint) external payable {\n borrowerOperations.addColl{ value: msg.value }(_upperHint, _lowerHint);\n }\n\n function withdrawColl(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.withdrawColl(_amount, _upperHint, _lowerHint);\n }\n\n function withdrawZUSD(uint _maxFee, uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.withdrawZUSD(_maxFee, _amount, _upperHint, _lowerHint);\n }\n\n function repayZUSD(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.repayZUSD(_amount, _upperHint, _lowerHint);\n }\n\n function closeTrove() external {\n borrowerOperations.closeTrove();\n }\n\n function adjustTrove(uint _maxFee, uint _collWithdrawal, uint _debtChange, bool isDebtIncrease, address _upperHint, address _lowerHint) external payable {\n borrowerOperations.adjustTrove{ value: msg.value }(_maxFee, _collWithdrawal, _debtChange, isDebtIncrease, _upperHint, _lowerHint);\n }\n\n function claimCollateral() external {\n borrowerOperations.claimCollateral();\n }\n}\n" + }, + "contracts/Proxy/BorrowerWrappersScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Interfaces/IBorrowerOperations.sol\";\nimport \"../Interfaces/ITroveManager.sol\";\nimport \"../Interfaces/IStabilityPool.sol\";\nimport \"../Interfaces/IPriceFeed.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\nimport \"./BorrowerOperationsScript.sol\";\nimport \"./ETHTransferScript.sol\";\nimport \"./ZEROStakingScript.sol\";\nimport \"../Dependencies/console.sol\";\n\n\ncontract BorrowerWrappersScript is BorrowerOperationsScript, ETHTransferScript, ZEROStakingScript {\n using SafeMath for uint;\n\n string constant public NAME = \"BorrowerWrappersScript\";\n\n ITroveManager immutable troveManager;\n IStabilityPool immutable stabilityPool;\n IPriceFeed immutable priceFeed;\n IERC20 immutable zusdToken;\n IERC20 immutable zeroToken;\n IZEROStaking immutable zeroStaking;\n\n constructor(\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _zeroStakingAddress,\n address _stabilityPoolAddress,\n address _priceFeedAddress,\n address _zusdTokenAddress,\n address _zeroTokenAddress\n )\n BorrowerOperationsScript(IBorrowerOperations(_borrowerOperationsAddress))\n ZEROStakingScript(_zeroStakingAddress)\n public\n {\n checkContract(_troveManagerAddress);\n ITroveManager troveManagerCached = ITroveManager(_troveManagerAddress);\n troveManager = troveManagerCached;\n\n IStabilityPool stabilityPoolCached = IStabilityPool(_stabilityPoolAddress);\n checkContract(_stabilityPoolAddress);\n stabilityPool = stabilityPoolCached;\n\n IPriceFeed priceFeedCached = IPriceFeed(_priceFeedAddress); \n checkContract(_priceFeedAddress);\n priceFeed = priceFeedCached;\n\n checkContract(_zusdTokenAddress);\n zusdToken = IERC20(_zusdTokenAddress);\n\n checkContract(_zeroTokenAddress);\n zeroToken = IERC20(_zeroTokenAddress);\n\n IZEROStaking zeroStakingCached = IZEROStaking(_zeroStakingAddress);\n checkContract(_zeroStakingAddress);\n zeroStaking = zeroStakingCached;\n }\n\n function claimCollateralAndOpenTrove(uint _maxFee, uint _ZUSDAmount, address _upperHint, address _lowerHint) external payable {\n uint balanceBefore = address(this).balance;\n\n // Claim collateral\n borrowerOperations.claimCollateral();\n\n uint balanceAfter = address(this).balance;\n\n // already checked in CollSurplusPool\n assert(balanceAfter > balanceBefore);\n\n uint totalCollateral = balanceAfter.sub(balanceBefore).add(msg.value);\n\n // Open trove with obtained collateral, plus collateral sent by user\n borrowerOperations.openTrove{ value: totalCollateral }(_maxFee, _ZUSDAmount, _upperHint, _lowerHint);\n }\n\n function claimSPRewardsAndRecycle(uint _maxFee, address _upperHint, address _lowerHint) external {\n uint collBalanceBefore = address(this).balance;\n uint zeroBalanceBefore = zeroToken.balanceOf(address(this));\n\n // Claim rewards\n stabilityPool.withdrawFromSP(0);\n\n uint collBalanceAfter = address(this).balance;\n uint zeroBalanceAfter = zeroToken.balanceOf(address(this));\n uint claimedCollateral = collBalanceAfter.sub(collBalanceBefore);\n\n // Add claimed ETH to trove, get more ZUSD and stake it into the Stability Pool\n if (claimedCollateral > 0) {\n _requireUserHasTrove(address(this));\n uint ZUSDAmount = _getNetZUSDAmount(claimedCollateral);\n borrowerOperations.adjustTrove{ value: claimedCollateral }(_maxFee, 0, ZUSDAmount, true, _upperHint, _lowerHint);\n // Provide withdrawn ZUSD to Stability Pool\n if (ZUSDAmount > 0) {\n stabilityPool.provideToSP(ZUSDAmount, address(0));\n }\n }\n\n // Stake claimed ZERO\n uint claimedZERO = zeroBalanceAfter.sub(zeroBalanceBefore);\n if (claimedZERO > 0) {\n zeroStaking.stake(claimedZERO);\n }\n }\n\n function claimStakingGainsAndRecycle(uint _maxFee, address _upperHint, address _lowerHint) external {\n uint collBalanceBefore = address(this).balance;\n uint zusdBalanceBefore = zusdToken.balanceOf(address(this));\n uint zeroBalanceBefore = zeroToken.balanceOf(address(this));\n\n // Claim gains\n zeroStaking.unstake(0);\n\n uint gainedCollateral = address(this).balance.sub(collBalanceBefore); // stack too deep issues :'(\n uint gainedZUSD = zusdToken.balanceOf(address(this)).sub(zusdBalanceBefore);\n\n uint netZUSDAmount;\n // Top up trove and get more ZUSD, keeping ICR constant\n if (gainedCollateral > 0) {\n _requireUserHasTrove(address(this));\n netZUSDAmount = _getNetZUSDAmount(gainedCollateral);\n borrowerOperations.adjustTrove{ value: gainedCollateral }(_maxFee, 0, netZUSDAmount, true, _upperHint, _lowerHint);\n }\n\n uint totalZUSD = gainedZUSD.add(netZUSDAmount);\n if (totalZUSD > 0) {\n stabilityPool.provideToSP(totalZUSD, address(0));\n\n // Providing to Stability Pool also triggers ZERO claim, so stake it if any\n uint zeroBalanceAfter = zeroToken.balanceOf(address(this));\n uint claimedZERO = zeroBalanceAfter.sub(zeroBalanceBefore);\n if (claimedZERO > 0) {\n zeroStaking.stake(claimedZERO);\n }\n }\n\n }\n\n function _getNetZUSDAmount(uint _collateral) internal returns (uint) {\n uint price = priceFeed.fetchPrice();\n uint ICR = troveManager.getCurrentICR(address(this), price);\n\n uint ZUSDAmount = _collateral.mul(price).div(ICR);\n uint borrowingRate = troveManager.getBorrowingRateWithDecay();\n uint netDebt = ZUSDAmount.mul(LiquityMath.DECIMAL_PRECISION).div(LiquityMath.DECIMAL_PRECISION.add(borrowingRate));\n\n return netDebt;\n }\n\n function _requireUserHasTrove(address _depositor) internal view {\n require(troveManager.getTroveStatus(_depositor) == 1, \"BorrowerWrappersScript: caller must have an active trove\");\n }\n}\n" + }, + "contracts/Proxy/ETHTransferScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\n\ncontract ETHTransferScript {\n function transferETH(address _recipient, uint256 _amount) external returns (bool) {\n (bool success, ) = _recipient.call{value: _amount}(\"\");\n return success;\n }\n}\n" + }, + "contracts/Proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Dependencies/Ownable.sol\";\n/**\n * @title Base Proxy contract.\n * \n * Adapted version of https://github.com/DistributedCollective/Sovryn-smart-contracts/blob/development/contracts/proxy/Proxy.sol \n *\n * @notice The proxy performs delegated calls to the contract implementation\n * it is pointing to. This way upgradable contracts are possible on blockchain.\n *\n * Delegating proxy contracts are widely used for both upgradeability and gas\n * savings. These proxies rely on a logic contract (also known as implementation\n * contract or master copy) that is called using delegatecall. This allows\n * proxies to keep a persistent state (storage and balance) while the code is\n * delegated to the logic contract.\n *\n * Proxy contract is meant to be inherited and its internal functions\n * _setImplementation and _setOwner to be called when upgrades become\n * neccessary.\n *\n * The loan token (iToken) contract as well as the protocol contract act as\n * proxies, delegating all calls to underlying contracts. Therefore, if you\n * want to interact with them using web3, you need to use the ABIs from the\n * contracts containing the actual logic or the interface contract.\n * ABI for LoanToken contracts: LoanTokenLogicStandard\n * ABI for Protocol contract: ISovryn\n *\n * @dev UpgradableProxy is the contract that inherits Proxy and wraps these\n * functions.\n * */\ncontract Proxy is Ownable {\n bytes32 private constant KEY_IMPLEMENTATION = keccak256(\"key.implementation\");\n\n event ImplementationChanged(\n address indexed _oldImplementation,\n address indexed _newImplementation\n );\n\n /**\n * @notice Set address of the implementation.\n * @param _implementation Address of the implementation.\n * */\n function _setImplementation(address _implementation) internal {\n require(_implementation != address(0), \"Proxy::setImplementation: invalid address\");\n emit ImplementationChanged(getImplementation(), _implementation);\n\n bytes32 key = KEY_IMPLEMENTATION;\n assembly {\n sstore(key, _implementation)\n }\n }\n\n /**\n * @notice Return address of the implementation.\n * @return _implementation Address of the implementation.\n * */\n function getImplementation() public view returns (address _implementation) {\n bytes32 key = KEY_IMPLEMENTATION;\n assembly {\n _implementation := sload(key)\n }\n }\n\n /**\n * @notice Fallback function performs a delegate call\n * to the actual implementation address is pointing this proxy.\n * Returns whatever the implementation call returns.\n * */\n fallback() external payable {\n delegate();\n }\n\n /**\n * @notice Fallback function performs a delegate call\n * to the actual implementation address is pointing this proxy.\n * Returns whatever the implementation call returns.\n * */\n receive() external payable {\n delegate();\n }\n\n function delegate() internal {\n address implementation = getImplementation();\n require(implementation != address(0), \"Proxy::(): implementation not found\");\n\n assembly {\n let pointer := mload(0x40)\n calldatacopy(pointer, 0, calldatasize())\n let result := delegatecall(gas(), implementation, pointer, calldatasize(), 0, 0)\n let size := returndatasize()\n returndatacopy(pointer, 0, size)\n\n switch result\n case 0 {\n revert(pointer, size)\n }\n default {\n return(pointer, size)\n }\n }\n }\n}\n" + }, + "contracts/Proxy/StabilityPoolScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/IStabilityPool.sol\";\n\n\ncontract StabilityPoolScript is CheckContract {\n string constant public NAME = \"StabilityPoolScript\";\n\n IStabilityPool immutable stabilityPool;\n\n constructor(IStabilityPool _stabilityPool) public {\n checkContract(address(_stabilityPool));\n stabilityPool = _stabilityPool;\n }\n\n function provideToSP(uint _amount, address _frontEndTag) external {\n stabilityPool.provideToSP(_amount, _frontEndTag);\n }\n\n function withdrawFromSP(uint _amount) external {\n stabilityPool.withdrawFromSP(_amount);\n }\n\n function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external {\n stabilityPool.withdrawETHGainToTrove(_upperHint, _lowerHint);\n }\n}\n" + }, + "contracts/Proxy/TokenScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/IERC20.sol\";\n\n\ncontract TokenScript is CheckContract {\n string constant public NAME = \"TokenScript\";\n\n IERC20 immutable token;\n\n constructor(address _tokenAddress) public {\n checkContract(_tokenAddress);\n token = IERC20(_tokenAddress);\n }\n\n function transfer(address recipient, uint256 amount) external returns (bool) {\n token.transfer(recipient, amount);\n }\n\n function allowance(address owner, address spender) external view returns (uint256) {\n token.allowance(owner, spender);\n }\n\n function approve(address spender, uint256 amount) external returns (bool) {\n token.approve(spender, amount);\n }\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {\n token.transferFrom(sender, recipient, amount);\n }\n\n function increaseAllowance(address spender, uint256 addedValue) external returns (bool) {\n token.increaseAllowance(spender, addedValue);\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool) {\n token.decreaseAllowance(spender, subtractedValue);\n }\n}\n" + }, + "contracts/Proxy/TroveManagerScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/ITroveManager.sol\";\n\n\ncontract TroveManagerScript is CheckContract {\n string constant public NAME = \"TroveManagerScript\";\n\n ITroveManager immutable troveManager;\n\n constructor(ITroveManager _troveManager) public {\n checkContract(address(_troveManager));\n troveManager = _troveManager;\n }\n\n function redeemCollateral(\n uint _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint _partialRedemptionHintNICR,\n uint _maxIterations,\n uint _maxFee\n ) external returns (uint) {\n troveManager.redeemCollateral(\n _ZUSDAmount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n _maxIterations,\n _maxFee\n );\n }\n}\n" + }, + "contracts/Proxy/UpgradableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Proxy.sol\";\n\n/**\n * @title Upgradable Proxy contract.\n *\n * Adapted version of https://github.com/DistributedCollective/Sovryn-smart-contracts/blob/development/contracts/proxy/UpgradableProxy.sol\n * \n * @notice A disadvantage of the immutable ledger is that nobody can change the\n * source code of a smart contract after it’s been deployed. In order to fix\n * bugs or introduce new features, smart contracts need to be upgradable somehow.\n *\n * Although it is not possible to upgrade the code of an already deployed smart\n * contract, it is possible to set-up a proxy contract architecture that will\n * allow to use new deployed contracts as if the main logic had been upgraded.\n *\n * A proxy architecture pattern is such that all message calls go through a\n * Proxy contract that will redirect them to the latest deployed contract logic.\n * To upgrade, a new version of the contract is deployed, and the Proxy is\n * updated to reference the new contract address.\n * */\ncontract UpgradableProxy is Proxy {\n /**\n * @notice Set address of the implementation.\n * @dev Wrapper for _setImplementation that exposes the function\n * as public for owner to be able to set a new version of the\n * contract as current pointing implementation.\n * @param _implementation Address of the implementation.\n * */\n function setImplementation(address _implementation) public onlyOwner {\n _setImplementation(_implementation);\n }\n\n}\n" + }, + "contracts/Proxy/ZEROStakingScript.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\n\n\ncontract ZEROStakingScript is CheckContract {\n IZEROStaking immutable ZEROStaking;\n\n constructor(address _zeroStakingAddress) public {\n checkContract(_zeroStakingAddress);\n ZEROStaking = IZEROStaking(_zeroStakingAddress);\n }\n\n function stake(uint _ZEROamount) external {\n ZEROStaking.stake(_ZEROamount);\n }\n}\n" + }, + "contracts/SortedTroves.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./SortedTrovesStorage.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\n\n/**\n * A sorted doubly linked list with nodes sorted in descending order.\n *\n * Nodes map to active Troves in the system - the ID property is the address of a Trove owner.\n * Nodes are ordered according to their current nominal individual collateral ratio (NICR),\n * which is like the ICR but without the price, i.e., just collateral / debt.\n *\n * The list optionally accepts insert position hints.\n *\n * NICRs are computed dynamically at runtime, and not stored on the Node. This is because NICRs of active Troves\n * change dynamically as liquidation events occur.\n *\n * The list relies on the fact that liquidation events preserve ordering: a liquidation decreases the NICRs of all active Troves,\n * but maintains their order. A node inserted based on current NICR will maintain the correct position,\n * relative to it's peers, as rewards accumulate, as long as it's raw collateral and debt have not changed.\n * Thus, Nodes remain sorted by current NICR.\n *\n * Nodes need only be re-inserted upon a Trove operation - when the owner adds or removes collateral or debt\n * to their position.\n *\n * The list is a modification of the following audited SortedDoublyLinkedList:\n * https://github.com/livepeer/protocol/blob/master/contracts/libraries/SortedDoublyLL.sol\n *\n *\n * Changes made in the Zero implementation:\n *\n * - Keys have been removed from nodes\n *\n * - Ordering checks for insertion are performed by comparing an NICR argument to the current NICR, calculated at runtime.\n * The list relies on the property that ordering by ICR is maintained as the ETH:USD price varies.\n *\n * - Public functions with parameters have been made internal to save gas, and given an external wrapper function for external access\n */\ncontract SortedTroves is SortedTrovesStorage, CheckContract, ISortedTroves {\n using SafeMath for uint256;\n\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress);\n event NodeAdded(address _id, uint256 _NICR);\n event NodeRemoved(address _id);\n\n // --- Dependency setters ---\n\n function setParams(\n uint256 _size,\n address _troveManagerAddress,\n address _borrowerOperationsAddress\n ) external override onlyOwner {\n require(_size > 0, \"SortedTroves: Size can’t be zero\");\n checkContract(_troveManagerAddress);\n checkContract(_borrowerOperationsAddress);\n\n data.maxSize = _size;\n\n troveManager = ITroveManager(_troveManagerAddress);\n borrowerOperationsAddress = _borrowerOperationsAddress;\n\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n }\n\n /**\n * @dev Add a node to the list\n * @param _id Node's id\n * @param _NICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n\n function insert(\n address _id,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external override {\n ITroveManager troveManagerCached = troveManager;\n\n _requireCallerIsBOorTroveM(troveManagerCached);\n _insert(troveManagerCached, _id, _NICR, _prevId, _nextId);\n }\n\n function _insert(\n ITroveManager _troveManager,\n address _id,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) internal {\n // List must not be full\n require(!isFull(), \"SortedTroves: List is full\");\n // List must not already contain node\n require(!contains(_id), \"SortedTroves: List already contains the node\");\n // Node id must not be null\n require(_id != address(0), \"SortedTroves: Id cannot be zero\");\n // NICR must be non-zero\n require(_NICR > 0, \"SortedTroves: NICR must be positive\");\n\n address prevId = _prevId;\n address nextId = _nextId;\n\n if (!_validInsertPosition(_troveManager, _NICR, prevId, nextId)) {\n // Sender's hint was not a valid insert position\n // Use sender's hint to find a valid insert position\n (prevId, nextId) = _findInsertPosition(_troveManager, _NICR, prevId, nextId);\n }\n\n data.nodes[_id].exists = true;\n\n if (prevId == address(0) && nextId == address(0)) {\n // Insert as head and tail\n data.head = _id;\n data.tail = _id;\n } else if (prevId == address(0)) {\n // Insert before `prevId` as the head\n data.nodes[_id].nextId = data.head;\n data.nodes[data.head].prevId = _id;\n data.head = _id;\n } else if (nextId == address(0)) {\n // Insert after `nextId` as the tail\n data.nodes[_id].prevId = data.tail;\n data.nodes[data.tail].nextId = _id;\n data.tail = _id;\n } else {\n // Insert at insert position between `prevId` and `nextId`\n data.nodes[_id].nextId = nextId;\n data.nodes[_id].prevId = prevId;\n data.nodes[prevId].nextId = _id;\n data.nodes[nextId].prevId = _id;\n }\n\n data.size = data.size.add(1);\n emit NodeAdded(_id, _NICR);\n }\n\n function remove(address _id) external override {\n _requireCallerIsTroveManager();\n _remove(_id);\n }\n\n /**\n * @dev Remove a node from the list\n * @param _id Node's id\n */\n function _remove(address _id) internal {\n // List must contain the node\n require(contains(_id), \"SortedTroves: List does not contain the id\");\n\n if (data.size > 1) {\n // List contains more than a single node\n if (_id == data.head) {\n // The removed node is the head\n // Set head to next node\n data.head = data.nodes[_id].nextId;\n // Set prev pointer of new head to null\n data.nodes[data.head].prevId = address(0);\n } else if (_id == data.tail) {\n // The removed node is the tail\n // Set tail to previous node\n data.tail = data.nodes[_id].prevId;\n // Set next pointer of new tail to null\n data.nodes[data.tail].nextId = address(0);\n } else {\n // The removed node is neither the head nor the tail\n // Set next pointer of previous node to the next node\n data.nodes[data.nodes[_id].prevId].nextId = data.nodes[_id].nextId;\n // Set prev pointer of next node to the previous node\n data.nodes[data.nodes[_id].nextId].prevId = data.nodes[_id].prevId;\n }\n } else {\n // List contains a single node\n // Set the head and tail to null\n data.head = address(0);\n data.tail = address(0);\n }\n\n delete data.nodes[_id];\n data.size = data.size.sub(1);\n NodeRemoved(_id);\n }\n\n /**\n * @dev Re-insert the node at a new position, based on its new NICR\n * @param _id Node's id\n * @param _newNICR Node's new NICR\n * @param _prevId Id of previous node for the new insert position\n * @param _nextId Id of next node for the new insert position\n */\n function reInsert(\n address _id,\n uint256 _newNICR,\n address _prevId,\n address _nextId\n ) external override {\n ITroveManager troveManagerCached = troveManager;\n\n _requireCallerIsBOorTroveM(troveManagerCached);\n // List must contain the node\n require(contains(_id), \"SortedTroves: List does not contain the id\");\n // NICR must be non-zero\n require(_newNICR > 0, \"SortedTroves: NICR must be positive\");\n\n // Remove node from the list\n _remove(_id);\n\n _insert(troveManagerCached, _id, _newNICR, _prevId, _nextId);\n }\n\n /**\n * @dev Checks if the list contains a node\n */\n function contains(address _id) public view override returns (bool) {\n return data.nodes[_id].exists;\n }\n\n /**\n * @dev Checks if the list is full\n */\n function isFull() public view override returns (bool) {\n return data.size == data.maxSize;\n }\n\n /**\n * @dev Checks if the list is empty\n */\n function isEmpty() public view override returns (bool) {\n return data.size == 0;\n }\n\n /**\n * @dev Returns the current size of the list\n */\n function getSize() external view override returns (uint256) {\n return data.size;\n }\n\n /**\n * @dev Returns the maximum size of the list\n */\n function getMaxSize() external view override returns (uint256) {\n return data.maxSize;\n }\n\n /**\n * @dev Returns the first node in the list (node with the largest NICR)\n */\n function getFirst() external view override returns (address) {\n return data.head;\n }\n\n /**\n * @dev Returns the last node in the list (node with the smallest NICR)\n */\n function getLast() external view override returns (address) {\n return data.tail;\n }\n\n /**\n * @dev Returns the next node (with a smaller NICR) in the list for a given node\n * @param _id Node's id\n */\n function getNext(address _id) external view override returns (address) {\n return data.nodes[_id].nextId;\n }\n\n /**\n * @dev Returns the previous node (with a larger NICR) in the list for a given node\n * @param _id Node's id\n */\n function getPrev(address _id) external view override returns (address) {\n return data.nodes[_id].prevId;\n }\n\n /**\n * @dev Check if a pair of nodes is a valid insertion point for a new node with the given NICR\n * @param _NICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function validInsertPosition(\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external view override returns (bool) {\n return _validInsertPosition(troveManager, _NICR, _prevId, _nextId);\n }\n\n function _validInsertPosition(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) internal view returns (bool) {\n if (_prevId == address(0) && _nextId == address(0)) {\n // `(null, null)` is a valid insert position if the list is empty\n return isEmpty();\n } else if (_prevId == address(0)) {\n // `(null, _nextId)` is a valid insert position if `_nextId` is the head of the list\n return data.head == _nextId && _NICR >= _troveManager.getNominalICR(_nextId);\n } else if (_nextId == address(0)) {\n // `(_prevId, null)` is a valid insert position if `_prevId` is the tail of the list\n return data.tail == _prevId && _NICR <= _troveManager.getNominalICR(_prevId);\n } else {\n // `(_prevId, _nextId)` is a valid insert position if they are adjacent nodes and `_NICR` falls between the two nodes' NICRs\n return\n data.nodes[_prevId].nextId == _nextId &&\n _troveManager.getNominalICR(_prevId) >= _NICR &&\n _NICR >= _troveManager.getNominalICR(_nextId);\n }\n }\n\n /**\n * @dev Descend the list (larger NICRs to smaller NICRs) to find a valid insert position\n * @param _troveManager TroveManager contract, passed in as param to save SLOAD’s\n * @param _NICR Node's NICR\n * @param _startId Id of node to start descending the list from\n */\n function _descendList(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _startId\n ) internal view returns (address, address) {\n // If `_startId` is the head, check if the insert position is before the head\n if (data.head == _startId && _NICR >= _troveManager.getNominalICR(_startId)) {\n return (address(0), _startId);\n }\n\n address prevId = _startId;\n address nextId = data.nodes[prevId].nextId;\n\n // Descend the list until we reach the end or until we find a valid insert position\n while (\n prevId != address(0) && !_validInsertPosition(_troveManager, _NICR, prevId, nextId)\n ) {\n prevId = data.nodes[prevId].nextId;\n nextId = data.nodes[prevId].nextId;\n }\n\n return (prevId, nextId);\n }\n\n /**\n * @dev Ascend the list (smaller NICRs to larger NICRs) to find a valid insert position\n * @param _troveManager TroveManager contract, passed in as param to save SLOAD’s\n * @param _NICR Node's NICR\n * @param _startId Id of node to start ascending the list from\n */\n function _ascendList(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _startId\n ) internal view returns (address, address) {\n // If `_startId` is the tail, check if the insert position is after the tail\n if (data.tail == _startId && _NICR <= _troveManager.getNominalICR(_startId)) {\n return (_startId, address(0));\n }\n\n address nextId = _startId;\n address prevId = data.nodes[nextId].prevId;\n\n // Ascend the list until we reach the end or until we find a valid insertion point\n while (\n nextId != address(0) && !_validInsertPosition(_troveManager, _NICR, prevId, nextId)\n ) {\n nextId = data.nodes[nextId].prevId;\n prevId = data.nodes[nextId].prevId;\n }\n\n return (prevId, nextId);\n }\n\n /**\n * @dev Find the insert position for a new node with the given NICR\n * @param _NICR Node's NICR\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function findInsertPosition(\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external view override returns (address, address) {\n return _findInsertPosition(troveManager, _NICR, _prevId, _nextId);\n }\n\n function _findInsertPosition(\n ITroveManager _troveManager,\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) internal view returns (address, address) {\n address prevId = _prevId;\n address nextId = _nextId;\n\n if (prevId != address(0)) {\n if (!contains(prevId) || _NICR > _troveManager.getNominalICR(prevId)) {\n // `prevId` does not exist anymore or now has a smaller NICR than the given NICR\n prevId = address(0);\n }\n }\n\n if (nextId != address(0)) {\n if (!contains(nextId) || _NICR < _troveManager.getNominalICR(nextId)) {\n // `nextId` does not exist anymore or now has a larger NICR than the given NICR\n nextId = address(0);\n }\n }\n\n if (prevId == address(0) && nextId == address(0)) {\n // No hint - descend list starting from head\n return _descendList(_troveManager, _NICR, data.head);\n } else if (prevId == address(0)) {\n // No `prevId` for hint - ascend list starting from `nextId`\n return _ascendList(_troveManager, _NICR, nextId);\n } else if (nextId == address(0)) {\n // No `nextId` for hint - descend list starting from `prevId`\n return _descendList(_troveManager, _NICR, prevId);\n } else {\n // Descend list starting from `prevId`\n return _descendList(_troveManager, _NICR, prevId);\n }\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsTroveManager() internal view {\n require(\n msg.sender == address(troveManager),\n \"SortedTroves: Caller is not the TroveManager\"\n );\n }\n\n function _requireCallerIsBOorTroveM(ITroveManager _troveManager) internal view {\n require(\n msg.sender == borrowerOperationsAddress || msg.sender == address(_troveManager),\n \"SortedTroves: Caller is neither BO nor TroveM\"\n );\n }\n}\n" + }, + "contracts/SortedTrovesStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\n\ncontract SortedTrovesStorage is Ownable {\n string public constant NAME = \"SortedTroves\";\n\n address public borrowerOperationsAddress;\n\n ITroveManager public troveManager;\n\n // Information for a node in the list\n struct Node {\n bool exists;\n address nextId; // Id of next node (smaller NICR) in the list\n address prevId; // Id of previous node (larger NICR) in the list\n }\n\n // Information for the list\n struct Data {\n address head; // Head of the list. Also the node in the list with the largest NICR\n address tail; // Tail of the list. Also the node in the list with the smallest NICR\n uint256 maxSize; // Maximum size of the list\n uint256 size; // Current size of the list\n mapping(address => Node) nodes; // Track the corresponding ids for each node in the list\n }\n\n Data public data;\n}\n" + }, + "contracts/StabilityPool.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ICommunityIssuance.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/LiquitySafeMath128.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/Mynt/MyntLib.sol\";\nimport \"./StabilityPoolStorage.sol\";\n\n/**\n * The Stability Pool holds ZUSD tokens deposited by Stability Pool depositors.\n *\n * When a trove is liquidated, then depending on system conditions, some of its ZUSD debt gets offset with\n * ZUSD in the Stability Pool: that is, the offset debt evaporates, and an equal amount of ZUSD tokens in the Stability Pool is burned.\n *\n * Thus, a liquidation causes each depositor to receive a ZUSD loss, in proportion to their deposit as a share of total deposits.\n * They also receive an ETH gain, as the ETH collateral of the liquidated trove is distributed among Stability depositors,\n * in the same proportion.\n *\n * When a liquidation occurs, it depletes every deposit by the same fraction: for example, a liquidation that depletes 40%\n * of the total ZUSD in the Stability Pool, depletes 40% of each deposit.\n *\n * A deposit that has experienced a series of liquidations is termed a \"compounded deposit\": each liquidation depletes the deposit,\n * multiplying it by some factor in range ]0,1[\n *\n *\n * --- IMPLEMENTATION ---\n *\n * We use a highly scalable method of tracking deposits and ETH gains that has O(1) complexity.\n *\n * When a liquidation occurs, rather than updating each depositor's deposit and ETH gain, we simply update two state variables:\n * a product P, and a sum S.\n *\n * A mathematical manipulation allows us to factor out the initial deposit, and accurately track all depositors' compounded deposits\n * and accumulated ETH gains over time, as liquidations occur, using just these two variables P and S. When depositors join the\n * Stability Pool, they get a snapshot of the latest P and S: P_t and S_t, respectively.\n *\n * The formula for a depositor's accumulated ETH gain is derived here:\n * https://github.com/liquity/dev/blob/main/packages/contracts/mathProofs/Scalable%20Compounding%20Stability%20Pool%20Deposits.pdf\n *\n * For a given deposit d_t, the ratio P/P_t tells us the factor by which a deposit has decreased since it joined the Stability Pool,\n * and the term d_t * (S - S_t)/P_t gives us the deposit's total accumulated ETH gain.\n *\n * Each liquidation updates the product P and sum S. After a series of liquidations, a compounded deposit and corresponding ETH gain\n * can be calculated using the initial deposit, the depositor’s snapshots of P and S, and the latest values of P and S.\n *\n * Any time a depositor updates their deposit (withdrawal, top-up) their accumulated ETH gain is paid out, their new deposit is recorded\n * (based on their latest compounded deposit and modified by the withdrawal/top-up), and they receive new snapshots of the latest P and S.\n * Essentially, they make a fresh deposit that overwrites the old one.\n *\n *\n * --- SCALE FACTOR ---\n *\n * Since P is a running product in range ]0,1] that is always-decreasing, it should never reach 0 when multiplied by a number in range ]0,1[.\n * Unfortunately, Solidity floor division always reaches 0, sooner or later.\n *\n * A series of liquidations that nearly empty the Pool (and thus each multiply P by a very small number in range ]0,1[ ) may push P\n * to its 18 digit decimal limit, and round it to 0, when in fact the Pool hasn't been emptied: this would break deposit tracking.\n *\n * So, to track P accurately, we use a scale factor: if a liquidation would cause P to decrease to <1e-9 (and be rounded to 0 by Solidity),\n * we first multiply P by 1e9, and increment a currentScale factor by 1.\n *\n * The added benefit of using 1e9 for the scale factor (rather than 1e18) is that it ensures negligible precision loss close to the\n * scale boundary: when P is at its minimum value of 1e9, the relative precision loss in P due to floor division is only on the\n * order of 1e-9.\n *\n * --- EPOCHS ---\n *\n * Whenever a liquidation fully empties the Stability Pool, all deposits should become 0. However, setting P to 0 would make P be 0\n * forever, and break all future reward calculations.\n *\n * So, every time the Stability Pool is emptied by a liquidation, we reset P = 1 and currentScale = 0, and increment the currentEpoch by 1.\n *\n * --- TRACKING DEPOSIT OVER SCALE CHANGES AND EPOCHS ---\n *\n * When a deposit is made, it gets snapshots of the currentEpoch and the currentScale.\n *\n * When calculating a compounded deposit, we compare the current epoch to the deposit's epoch snapshot. If the current epoch is newer,\n * then the deposit was present during a pool-emptying liquidation, and necessarily has been depleted to 0.\n *\n * Otherwise, we then compare the current scale to the deposit's scale snapshot. If they're equal, the compounded deposit is given by d_t * P/P_t.\n * If it spans one scale change, it is given by d_t * P/(P_t * 1e9). If it spans more than one scale change, we define the compounded deposit\n * as 0, since it is now less than 1e-9'th of its initial value (e.g. a deposit of 1 billion ZUSD has depleted to < 1 ZUSD).\n *\n *\n * --- TRACKING DEPOSITOR'S ETH GAIN OVER SCALE CHANGES AND EPOCHS ---\n *\n * In the current epoch, the latest value of S is stored upon each scale change, and the mapping (scale -> S) is stored for each epoch.\n *\n * This allows us to calculate a deposit's accumulated ETH gain, during the epoch in which the deposit was non-sov and earned ETH.\n *\n * We calculate the depositor's accumulated ETH gain for the scale at which they made the deposit, using the ETH gain formula:\n * e_1 = d_t * (S - S_t) / P_t\n *\n * and also for scale after, taking care to divide the latter by a factor of 1e9:\n * e_2 = d_t * S / (P_t * 1e9)\n *\n * The gain in the second scale will be full, as the starting point was in the previous scale, thus no need to subtract anything.\n * The deposit therefore was present for reward events from the beginning of that second scale.\n *\n * S_i-S_t + S_{i+1}\n * .<--------.------------>\n * . .\n * . S_i . S_{i+1}\n * <--.-------->.<----------->\n * S_t. .\n * <->. .\n * t .\n * |---+---------|-------------|-----...\n * i i+1\n *\n * The sum of (e_1 + e_2) captures the depositor's total accumulated ETH gain, handling the case where their\n * deposit spanned one scale change. We only care about gains across one scale change, since the compounded\n * deposit is defined as being 0 once it has spanned more than one scale change.\n *\n *\n * --- UPDATING P WHEN A LIQUIDATION OCCURS ---\n *\n * Please see the implementation spec in the proof document, which closely follows on from the compounded deposit / ETH gain derivations:\n * https://github.com/liquity/liquity/blob/master/papers/Scalable_Reward_Distribution_with_Compounding_Stakes.pdf\n *\n *\n * --- SOV ISSUANCE TO STABILITY POOL DEPOSITORS ---\n *\n * An SOV issuance event occurs at every deposit operation, and every liquidation.\n *\n * Each deposit is tagged with the address of the front end through which it was made.\n *\n * All deposits earn a share of the issued SOV in proportion to the deposit as a share of total deposits. The SOV earned\n * by a given deposit, is split between the depositor and the front end through which the deposit was made, based on the front end's kickbackRate.\n *\n * Please see the system Readme for an overview:\n * https://github.com/liquity/dev/blob/main/README.md#zero-issuance-to-stability-providers\n *\n * We use the same mathematical product-sum approach to track SOV gains for depositors, where 'G' is the sum corresponding to SOV gains.\n * The product P (and snapshot P_t) is re-used, as the ratio P/P_t tracks a deposit's depletion due to liquidations.\n *\n */\ncontract StabilityPool is LiquityBase, StabilityPoolStorage, CheckContract, IStabilityPool {\n using LiquitySafeMath128 for uint128;\n address private constant ADDRESS_ZERO = address(0);\n\n // --- Events ---\n\n event StabilityPoolETHBalanceUpdated(uint256 _newBalance);\n event StabilityPoolZUSDBalanceUpdated(uint256 _newBalance);\n\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event TroveManagerAddressChanged(address _newTroveManagerAddress);\n event ActivePoolAddressChanged(address _newActivePoolAddress);\n event DefaultPoolAddressChanged(address _newDefaultPoolAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event SortedTrovesAddressChanged(address _newSortedTrovesAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event CommunityIssuanceAddressChanged(address _newCommunityIssuanceAddress);\n\n event P_Updated(uint256 _P);\n event S_Updated(uint256 _S, uint128 _epoch, uint128 _scale);\n event G_Updated(uint256 _G, uint128 _epoch, uint128 _scale);\n event EpochUpdated(uint128 _currentEpoch);\n event ScaleUpdated(uint128 _currentScale);\n\n event FrontEndRegistered(address indexed _frontEnd, uint256 _kickbackRate);\n event FrontEndTagSet(address indexed _depositor, address indexed _frontEnd);\n\n event DepositSnapshotUpdated(address indexed _depositor, uint256 _P, uint256 _S, uint256 _G);\n event FrontEndSnapshotUpdated(address indexed _frontEnd, uint256 _P, uint256 _G);\n event UserDepositChanged(address indexed _depositor, uint256 _newDeposit);\n event FrontEndStakeChanged(\n address indexed _frontEnd,\n uint256 _newFrontEndStake,\n address _depositor\n );\n\n event ETHGainWithdrawn(address indexed _depositor, uint256 _ETH, uint256 _ZUSDLoss);\n event SOVPaidToDepositor(address indexed _depositor, uint256 _SOV);\n event SOVPaidToFrontEnd(address indexed _frontEnd, uint256 _SOV);\n event EtherSent(address _to, uint256 _amount);\n\n // --- Contract setters ---\n\n function setAddresses(\n address _liquityBaseParamsAddress,\n address _borrowerOperationsAddress,\n address _troveManagerAddress,\n address _activePoolAddress,\n address _zusdTokenAddress,\n address _sortedTrovesAddress,\n address _priceFeedAddress,\n address _communityIssuanceAddress\n ) external override onlyOwner {\n checkContract(_liquityBaseParamsAddress);\n checkContract(_borrowerOperationsAddress);\n checkContract(_troveManagerAddress);\n checkContract(_activePoolAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_sortedTrovesAddress);\n checkContract(_priceFeedAddress);\n checkContract(_communityIssuanceAddress);\n\n P = DECIMAL_PRECISION;\n\n liquityBaseParams = ILiquityBaseParams(_liquityBaseParamsAddress);\n borrowerOperations = IBorrowerOperations(_borrowerOperationsAddress);\n troveManager = ITroveManager(_troveManagerAddress);\n activePool = IActivePool(_activePoolAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n priceFeed = IPriceFeed(_priceFeedAddress);\n communityIssuance = ICommunityIssuance(_communityIssuanceAddress);\n\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n emit TroveManagerAddressChanged(_troveManagerAddress);\n emit ActivePoolAddressChanged(_activePoolAddress);\n emit ZUSDTokenAddressChanged(_zusdTokenAddress);\n emit SortedTrovesAddressChanged(_sortedTrovesAddress);\n emit PriceFeedAddressChanged(_priceFeedAddress);\n emit CommunityIssuanceAddressChanged(_communityIssuanceAddress);\n }\n\n /**\n * @dev setter function specific for community issuance contract.\n * @param _communityIssuanceAddress address of new community issuance contract.\n */\n function setCommunityIssuanceAddress(address _communityIssuanceAddress) external onlyOwner {\n checkContract(_communityIssuanceAddress);\n communityIssuance = ICommunityIssuance(_communityIssuanceAddress);\n emit CommunityIssuanceAddressChanged(_communityIssuanceAddress);\n }\n\n // --- Getters for public variables. Required by IPool interface ---\n\n function getETH() external view override returns (uint256) {\n return ETH;\n }\n\n function getTotalZUSDDeposits() external view override returns (uint256) {\n return totalZUSDDeposits;\n }\n\n // --- External Depositor Functions ---\n\n /** provideToSP():\n *\n * - Triggers a SOV issuance, based on time passed since the last issuance and total amount of ZUSD is deposited. The SOV issuance is shared between *all* depositors and front ends\n * - Tags the deposit with the provided front end tag param, if it's a new deposit\n * - Sends depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Increases deposit and tagged front end's stake, and takes new snapshots for each.\n */\n function provideToSP(uint256 _amount, address _frontEndTag) external override {\n _provideToSP(_amount, _frontEndTag);\n }\n\n function _provideToSP(uint256 _amount, address _frontEndTag) internal {\n _requireFrontEndIsRegisteredOrZero(_frontEndTag);\n _requireFrontEndNotRegistered(msg.sender);\n _requireNonZeroAmount(_amount);\n\n uint256 initialDeposit = deposits[msg.sender].initialValue;\n\n ICommunityIssuance communityIssuanceCached = communityIssuance;\n\n _triggerSOVIssuance(communityIssuanceCached);\n\n if (initialDeposit == 0) {\n _setFrontEndTag(msg.sender, _frontEndTag);\n }\n uint256 depositorETHGain = getDepositorETHGain(msg.sender);\n uint256 compoundedZUSDDeposit = getCompoundedZUSDDeposit(msg.sender);\n uint256 ZUSDLoss = initialDeposit.sub(compoundedZUSDDeposit); // Needed only for event log\n\n // First pay out any SOV gains\n address frontEnd = deposits[msg.sender].frontEndTag;\n _payOutSOVGains(communityIssuanceCached, msg.sender, frontEnd);\n\n // Update front end stake\n uint256 compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd);\n uint256 newFrontEndStake = compoundedFrontEndStake.add(_amount);\n _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake);\n emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender);\n\n _sendZUSDtoStabilityPool(msg.sender, _amount);\n\n uint256 newDeposit = compoundedZUSDDeposit.add(_amount);\n _updateDepositAndSnapshots(msg.sender, newDeposit);\n emit UserDepositChanged(msg.sender, newDeposit);\n\n emit ETHGainWithdrawn(msg.sender, depositorETHGain, ZUSDLoss); // ZUSD Loss required for event log\n\n _sendETHGainToDepositor(depositorETHGain);\n }\n\n ///DLLR _owner or _spender can convert a specified amount of DLLR into ZUSD via Sovryn Mynt and deposit the ZUSD into the SOV Stability Pool, all in a single transaction\n function provideToSpFromDLLR(\n uint256 _dllrAmount,\n IMassetManager.PermitParams calldata _permitParams\n ) external override {\n uint256 _ZUSDAmount = MyntLib.redeemZusdFromDllrWithPermit(\n borrowerOperations.getMassetManager(),\n _dllrAmount,\n address(zusdToken),\n _permitParams\n );\n\n _provideToSP(_ZUSDAmount, ADDRESS_ZERO);\n }\n\n /** withdrawFromSP():\n *\n * - Triggers a SOV issuance, based on time passed since the last issuance and total amount of ZUSD is deposited. The SOV issuance is shared between *all* depositors and front ends\n * - Removes the deposit's front end tag if it is a full withdrawal\n * - Sends all depositor's accumulated gains (SOV, ETH) to depositor\n * - Sends the tagged front end's accumulated SOV gains to the tagged front end\n * - Decreases deposit and tagged front end's stake, and takes new snapshots for each.\n *\n * If _amount > userDeposit, the user withdraws all of their compounded deposit.\n */\n function withdrawFromSP(uint256 _amount) external override {\n _withdrawFromSpTo(_amount, msg.sender);\n }\n\n ///@return actual ZUSD amount withdrawn\n function _withdrawFromSpTo(uint256 _amount, address _receiver) internal returns (uint256) {\n require(_receiver != address(0), \"SP::_withdrawFromSpTo: _receiver is zero address\");\n if (_amount != 0) {\n _requireNoUnderCollateralizedTroves();\n }\n uint256 initialDeposit = deposits[msg.sender].initialValue;\n _requireUserHasDeposit(initialDeposit);\n\n ICommunityIssuance communityIssuanceCached = communityIssuance;\n\n _triggerSOVIssuance(communityIssuanceCached);\n\n uint256 depositorETHGain = getDepositorETHGain(msg.sender);\n\n uint256 compoundedZUSDDeposit = getCompoundedZUSDDeposit(msg.sender);\n uint256 ZUSDtoWithdraw = LiquityMath._min(_amount, compoundedZUSDDeposit);\n uint256 ZUSDLoss = initialDeposit.sub(compoundedZUSDDeposit); // Needed only for event log\n\n // First pay out any SOV gains\n address frontEnd = deposits[msg.sender].frontEndTag;\n _payOutSOVGains(communityIssuanceCached, msg.sender, frontEnd);\n\n // Update front end stake\n uint256 compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd);\n uint256 newFrontEndStake = compoundedFrontEndStake.sub(ZUSDtoWithdraw);\n _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake);\n emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender);\n\n _sendZUSDToDepositor(_receiver, ZUSDtoWithdraw);\n\n // Update deposit\n uint256 newDeposit = compoundedZUSDDeposit.sub(ZUSDtoWithdraw);\n _updateDepositAndSnapshots(msg.sender, newDeposit);\n emit UserDepositChanged(msg.sender, newDeposit);\n\n emit ETHGainWithdrawn(msg.sender, depositorETHGain, ZUSDLoss); // ZUSD Loss required for event log\n\n _sendETHGainTo(depositorETHGain, msg.sender);\n\n return ZUSDtoWithdraw;\n }\n\n ///Stability Pool depositor can withdraw a specified amount of ZUSD from the SOV Stability Pool and convert the ZUSD to DLLR via Sovryn Mynt, all in a single transaction\n function withdrawFromSpAndConvertToDLLR(uint256 _zusdAmountRequested) external override {\n IMassetManager massetManager = borrowerOperations.getMassetManager();\n uint256 amountWithdrawn = _withdrawFromSpTo(_zusdAmountRequested, address(this));\n require(\n zusdToken.approve(address(massetManager), amountWithdrawn),\n \"Failed to approve ZUSD amount for Mynt mAsset to redeem\"\n );\n massetManager.mintTo(address(zusdToken), amountWithdrawn, msg.sender);\n emit WithdrawFromSpAndConvertToDLLR(msg.sender, _zusdAmountRequested, amountWithdrawn);\n }\n\n /** withdrawETHGainToTrove:\n * - Triggers a SOV issuance, based on time passed since the last issuance. The SOV issuance is shared between *all* depositors and front ends\n * - Sends all depositor's SOV gain to depositor\n * - Sends all tagged front end's SOV gain to the tagged front end\n * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove\n * - Leaves their compounded deposit in the Stability Pool\n * - Updates snapshots for deposit and tagged front end stake */\n function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external override {\n uint256 initialDeposit = deposits[msg.sender].initialValue;\n _requireUserHasDeposit(initialDeposit);\n _requireUserHasTrove(msg.sender);\n _requireUserHasETHGain(msg.sender);\n\n ICommunityIssuance communityIssuanceCached = communityIssuance;\n\n _triggerSOVIssuance(communityIssuanceCached);\n\n uint256 depositorETHGain = getDepositorETHGain(msg.sender);\n\n uint256 compoundedZUSDDeposit = getCompoundedZUSDDeposit(msg.sender);\n uint256 ZUSDLoss = initialDeposit.sub(compoundedZUSDDeposit); // Needed only for event log\n\n // First pay out any SOV gains\n address frontEnd = deposits[msg.sender].frontEndTag;\n _payOutSOVGains(communityIssuanceCached, msg.sender, frontEnd);\n\n // Update front end stake\n uint256 compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd);\n uint256 newFrontEndStake = compoundedFrontEndStake;\n _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake);\n emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender);\n\n _updateDepositAndSnapshots(msg.sender, compoundedZUSDDeposit);\n\n /* Emit events before transferring ETH gain to Trove.\n This lets the event log make more sense (i.e. so it appears that first the ETH gain is withdrawn\n and then it is deposited into the Trove, not the other way around). */\n emit ETHGainWithdrawn(msg.sender, depositorETHGain, ZUSDLoss);\n emit UserDepositChanged(msg.sender, compoundedZUSDDeposit);\n\n ETH = ETH.sub(depositorETHGain);\n emit StabilityPoolETHBalanceUpdated(ETH);\n emit EtherSent(msg.sender, depositorETHGain);\n\n borrowerOperations.moveETHGainToTrove{ value: depositorETHGain }(\n msg.sender,\n _upperHint,\n _lowerHint\n );\n }\n\n // --- SOV issuance functions ---\n\n function _triggerSOVIssuance(ICommunityIssuance _communityIssuance) internal {\n uint256 SOVIssuance = _communityIssuance.issueSOV(totalZUSDDeposits);\n _updateG(SOVIssuance);\n }\n\n function _updateG(uint256 _SOVIssuance) internal {\n uint256 totalZUSD = totalZUSDDeposits; // cached to save an SLOAD\n /*\n * When total deposits is 0, G is not updated. In this case, the SOV issued can not be obtained by later\n * depositors - it is missed out on, and remains in the balanceof the CommunityIssuance contract.\n *\n */\n if (totalZUSD == 0 || _SOVIssuance == 0) {\n return;\n }\n\n uint256 SOVPerUnitStaked;\n SOVPerUnitStaked = _computeSOVPerUnitStaked(_SOVIssuance, totalZUSD);\n\n uint256 marginalSOVGain = SOVPerUnitStaked.mul(P);\n epochToScaleToG[currentEpoch][currentScale] = epochToScaleToG[currentEpoch][currentScale]\n .add(marginalSOVGain);\n\n emit G_Updated(epochToScaleToG[currentEpoch][currentScale], currentEpoch, currentScale);\n }\n\n function _computeSOVPerUnitStaked(uint256 _SOVIssuance, uint256 _totalZUSDDeposits)\n internal\n returns (uint256)\n {\n /*\n * Calculate the SOV-per-unit staked. Division uses a \"feedback\" error correction, to keep the\n * cumulative error low in the running total G:\n *\n * 1) Form a numerator which compensates for the floor division error that occurred the last time this\n * function was called.\n * 2) Calculate \"per-unit-staked\" ratio.\n * 3) Multiply the ratio back by its denominator, to reveal the current floor division error.\n * 4) Store this error for use in the next correction when this function is called.\n * 5) Note: static analysis tools complain about this \"division before multiplication\", however, it is intended.\n */\n uint256 SOVNumerator = _SOVIssuance.mul(DECIMAL_PRECISION).add(lastSOVError);\n\n uint256 SOVPerUnitStaked = SOVNumerator.div(_totalZUSDDeposits);\n lastSOVError = SOVNumerator.sub(SOVPerUnitStaked.mul(_totalZUSDDeposits));\n\n return SOVPerUnitStaked;\n }\n\n // --- Liquidation functions ---\n\n /**\n * Cancels out the specified debt against the ZUSD contained in the Stability Pool (as far as possible)\n * and transfers the Trove's ETH collateral from ActivePool to StabilityPool.\n * Only called by liquidation functions in the TroveManager.\n */\n function offset(uint256 _debtToOffset, uint256 _collToAdd) external override {\n _requireCallerIsTroveManager();\n uint256 totalZUSD = totalZUSDDeposits; // cached to save an SLOAD\n if (totalZUSD == 0 || _debtToOffset == 0) {\n return;\n }\n\n _triggerSOVIssuance(communityIssuance);\n\n (\n uint256 ETHGainPerUnitStaked,\n uint256 ZUSDLossPerUnitStaked\n ) = _computeRewardsPerUnitStaked(_collToAdd, _debtToOffset, totalZUSD);\n\n _updateRewardSumAndProduct(ETHGainPerUnitStaked, ZUSDLossPerUnitStaked); // updates S and P\n\n _moveOffsetCollAndDebt(_collToAdd, _debtToOffset);\n }\n\n // --- Offset helper functions ---\n\n function _computeRewardsPerUnitStaked(\n uint256 _collToAdd,\n uint256 _debtToOffset,\n uint256 _totalZUSDDeposits\n ) internal returns (uint256 ETHGainPerUnitStaked, uint256 ZUSDLossPerUnitStaked) {\n /*\n * Compute the ZUSD and ETH rewards. Uses a \"feedback\" error correction, to keep\n * the cumulative error in the P and S state variables low:\n *\n * 1) Form numerators which compensate for the floor division errors that occurred the last time this\n * function was called.\n * 2) Calculate \"per-unit-staked\" ratios.\n * 3) Multiply each ratio back by its denominator, to reveal the current floor division error.\n * 4) Store these errors for use in the next correction when this function is called.\n * 5) Note: static analysis tools complain about this \"division before multiplication\", however, it is intended.\n */\n uint256 ETHNumerator = _collToAdd.mul(DECIMAL_PRECISION).add(lastETHError_Offset);\n\n assert(_debtToOffset <= _totalZUSDDeposits);\n if (_debtToOffset == _totalZUSDDeposits) {\n ZUSDLossPerUnitStaked = DECIMAL_PRECISION; // When the Pool depletes to 0, so does each deposit\n lastZUSDLossError_Offset = 0;\n } else {\n uint256 ZUSDLossNumerator = _debtToOffset.mul(DECIMAL_PRECISION).sub(\n lastZUSDLossError_Offset\n );\n /*\n * Add 1 to make error in quotient positive. We want \"slightly too much\" ZUSD loss,\n * which ensures the error in any given compoundedZUSDDeposit favors the Stability Pool.\n */\n ZUSDLossPerUnitStaked = (ZUSDLossNumerator.div(_totalZUSDDeposits)).add(1);\n lastZUSDLossError_Offset = (ZUSDLossPerUnitStaked.mul(_totalZUSDDeposits)).sub(\n ZUSDLossNumerator\n );\n }\n\n ETHGainPerUnitStaked = ETHNumerator.div(_totalZUSDDeposits);\n lastETHError_Offset = ETHNumerator.sub(ETHGainPerUnitStaked.mul(_totalZUSDDeposits));\n\n return (ETHGainPerUnitStaked, ZUSDLossPerUnitStaked);\n }\n\n /// Update the Stability Pool reward sum S and product P\n function _updateRewardSumAndProduct(\n uint256 _ETHGainPerUnitStaked,\n uint256 _ZUSDLossPerUnitStaked\n ) internal {\n uint256 currentP = P;\n uint256 newP;\n\n assert(_ZUSDLossPerUnitStaked <= DECIMAL_PRECISION);\n /*\n * The newProductFactor is the factor by which to change all deposits, due to the depletion of Stability Pool ZUSD in the liquidation.\n * We make the product factor 0 if there was a pool-emptying. Otherwise, it is (1 - ZUSDLossPerUnitStaked)\n */\n uint256 newProductFactor = uint256(DECIMAL_PRECISION).sub(_ZUSDLossPerUnitStaked);\n\n uint128 currentScaleCached = currentScale;\n uint128 currentEpochCached = currentEpoch;\n uint256 currentS = epochToScaleToSum[currentEpochCached][currentScaleCached];\n\n /*\n * Calculate the new S first, before we update P.\n * The ETH gain for any given depositor from a liquidation depends on the value of their deposit\n * (and the value of totalDeposits) prior to the Stability being depleted by the debt in the liquidation.\n *\n * Since S corresponds to ETH gain, and P to deposit loss, we update S first.\n */\n uint256 marginalETHGain = _ETHGainPerUnitStaked.mul(currentP);\n uint256 newS = currentS.add(marginalETHGain);\n epochToScaleToSum[currentEpochCached][currentScaleCached] = newS;\n emit S_Updated(newS, currentEpochCached, currentScaleCached);\n\n // If the Stability Pool was emptied, increment the epoch, and reset the scale and product P\n if (newProductFactor == 0) {\n currentEpoch = currentEpochCached.add(1);\n emit EpochUpdated(currentEpoch);\n currentScale = 0;\n emit ScaleUpdated(currentScale);\n newP = DECIMAL_PRECISION;\n\n // If multiplying P by a non-sov product factor would reduce P below the scale boundary, increment the scale\n } else if (currentP.mul(newProductFactor).div(DECIMAL_PRECISION) < SCALE_FACTOR) {\n newP = currentP.mul(newProductFactor).mul(SCALE_FACTOR).div(DECIMAL_PRECISION);\n currentScale = currentScaleCached.add(1);\n emit ScaleUpdated(currentScale);\n } else {\n newP = currentP.mul(newProductFactor).div(DECIMAL_PRECISION);\n }\n\n assert(newP > 0);\n P = newP;\n\n emit P_Updated(newP);\n }\n\n function _moveOffsetCollAndDebt(uint256 _collToAdd, uint256 _debtToOffset) internal {\n IActivePool activePoolCached = activePool;\n\n // Cancel the liquidated ZUSD debt with the ZUSD in the stability pool\n activePoolCached.decreaseZUSDDebt(_debtToOffset);\n _decreaseZUSD(_debtToOffset);\n\n // Burn the debt that was successfully offset\n zusdToken.burn(address(this), _debtToOffset);\n\n activePoolCached.sendETH(address(this), _collToAdd);\n }\n\n function _decreaseZUSD(uint256 _amount) internal {\n uint256 newTotalZUSDDeposits = totalZUSDDeposits.sub(_amount);\n totalZUSDDeposits = newTotalZUSDDeposits;\n emit StabilityPoolZUSDBalanceUpdated(newTotalZUSDDeposits);\n }\n\n // --- Reward calculator functions for depositor and front end ---\n\n /** Calculates the ETH gain earned by the deposit since its last snapshots were taken.\n * Given by the formula: E = d0 * (S - S(0))/P(0)\n * where S(0) and P(0) are the depositor's snapshots of the sum S and product P, respectively.\n * d0 is the last recorded deposit value.\n */\n function getDepositorETHGain(address _depositor) public view override returns (uint256) {\n uint256 initialDeposit = deposits[_depositor].initialValue;\n\n if (initialDeposit == 0) {\n return 0;\n }\n\n Snapshots memory snapshots = depositSnapshots[_depositor];\n\n uint256 ETHGain = _getETHGainFromSnapshots(initialDeposit, snapshots);\n return ETHGain;\n }\n\n function _getETHGainFromSnapshots(uint256 initialDeposit, Snapshots memory snapshots)\n internal\n view\n returns (uint256)\n {\n /*\n * Grab the sum 'S' from the epoch at which the stake was made. The ETH gain may span up to one scale change.\n * If it does, the second portion of the ETH gain is scaled by 1e9.\n * If the gain spans no scale change, the second portion will be 0.\n */\n uint128 epochSnapshot = snapshots.epoch;\n uint128 scaleSnapshot = snapshots.scale;\n uint256 S_Snapshot = snapshots.S;\n uint256 P_Snapshot = snapshots.P;\n\n uint256 firstPortion = epochToScaleToSum[epochSnapshot][scaleSnapshot].sub(S_Snapshot);\n uint256 secondPortion = epochToScaleToSum[epochSnapshot][scaleSnapshot.add(1)].div(\n SCALE_FACTOR\n );\n\n uint256 ETHGain = initialDeposit.mul(firstPortion.add(secondPortion)).div(P_Snapshot).div(\n DECIMAL_PRECISION\n );\n\n return ETHGain;\n }\n\n /**\n * Calculate the SOV gain earned by a deposit since its last snapshots were taken.\n * Given by the formula: SOV = d0 * (G - G(0))/P(0)\n * where G(0) and P(0) are the depositor's snapshots of the sum G and product P, respectively.\n * d0 is the last recorded deposit value.\n */\n function getDepositorSOVGain(address _depositor) public view override returns (uint256) {\n uint256 initialDeposit = deposits[_depositor].initialValue;\n if (initialDeposit == 0) {\n return 0;\n }\n\n address frontEndTag = deposits[_depositor].frontEndTag;\n\n /*\n * If not tagged with a front end, the depositor gets a 100% cut of what their deposit earned.\n * Otherwise, their cut of the deposit's earnings is equal to the kickbackRate, set by the front end through\n * which they made their deposit.\n */\n uint256 kickbackRate = frontEndTag == ADDRESS_ZERO\n ? DECIMAL_PRECISION\n : frontEnds[frontEndTag].kickbackRate;\n\n Snapshots memory snapshots = depositSnapshots[_depositor];\n\n uint256 SOVGain = kickbackRate\n .mul(_getSOVGainFromSnapshots(initialDeposit, snapshots))\n .div(DECIMAL_PRECISION);\n\n return SOVGain;\n }\n\n /**\n * Return the SOV gain earned by the front end. Given by the formula: E = D0 * (G - G(0))/P(0)\n * where G(0) and P(0) are the depositor's snapshots of the sum G and product P, respectively.\n *\n * D0 is the last recorded value of the front end's total tagged deposits.\n */\n function getFrontEndSOVGain(address _frontEnd) public view override returns (uint256) {\n uint256 frontEndStake = frontEndStakes[_frontEnd];\n if (frontEndStake == 0) {\n return 0;\n }\n\n uint256 kickbackRate = frontEnds[_frontEnd].kickbackRate;\n uint256 frontEndShare = uint256(DECIMAL_PRECISION).sub(kickbackRate);\n\n Snapshots memory snapshots = frontEndSnapshots[_frontEnd];\n\n uint256 SOVGain = frontEndShare\n .mul(_getSOVGainFromSnapshots(frontEndStake, snapshots))\n .div(DECIMAL_PRECISION);\n return SOVGain;\n }\n\n function _getSOVGainFromSnapshots(uint256 initialStake, Snapshots memory snapshots)\n internal\n view\n returns (uint256)\n {\n /*\n * Grab the sum 'G' from the epoch at which the stake was made. The SOV gain may span up to one scale change.\n * If it does, the second portion of the SOV gain is scaled by 1e9.\n * If the gain spans no scale change, the second portion will be 0.\n */\n uint128 epochSnapshot = snapshots.epoch;\n uint128 scaleSnapshot = snapshots.scale;\n uint256 G_Snapshot = snapshots.G;\n uint256 P_Snapshot = snapshots.P;\n\n uint256 firstPortion = epochToScaleToG[epochSnapshot][scaleSnapshot].sub(G_Snapshot);\n uint256 secondPortion = epochToScaleToG[epochSnapshot][scaleSnapshot.add(1)].div(\n SCALE_FACTOR\n );\n\n uint256 SOVGain = initialStake.mul(firstPortion.add(secondPortion)).div(P_Snapshot).div(\n DECIMAL_PRECISION\n );\n\n return SOVGain;\n }\n\n // --- Compounded deposit and compounded front end stake ---\n\n /**\n * Return the user's compounded deposit. Given by the formula: d = d0 * P/P(0)\n * where P(0) is the depositor's snapshot of the product P, taken when they last updated their deposit.\n */\n function getCompoundedZUSDDeposit(address _depositor) public view override returns (uint256) {\n uint256 initialDeposit = deposits[_depositor].initialValue;\n if (initialDeposit == 0) {\n return 0;\n }\n\n Snapshots memory snapshots = depositSnapshots[_depositor];\n\n uint256 compoundedDeposit = _getCompoundedStakeFromSnapshots(initialDeposit, snapshots);\n return compoundedDeposit;\n }\n\n /**\n * Return the front end's compounded stake. Given by the formula: D = D0 * P/P(0)\n * where P(0) is the depositor's snapshot of the product P, taken at the last time\n * when one of the front end's tagged deposits updated their deposit.\n *\n * The front end's compounded stake is equal to the sum of its depositors' compounded deposits.\n */\n function getCompoundedFrontEndStake(address _frontEnd) public view override returns (uint256) {\n uint256 frontEndStake = frontEndStakes[_frontEnd];\n if (frontEndStake == 0) {\n return 0;\n }\n\n Snapshots memory snapshots = frontEndSnapshots[_frontEnd];\n\n uint256 compoundedFrontEndStake = _getCompoundedStakeFromSnapshots(\n frontEndStake,\n snapshots\n );\n return compoundedFrontEndStake;\n }\n\n // Internal function, used to calculcate compounded deposits and compounded front end stakes.\n function _getCompoundedStakeFromSnapshots(uint256 initialStake, Snapshots memory snapshots)\n internal\n view\n returns (uint256)\n {\n uint256 snapshot_P = snapshots.P;\n uint128 scaleSnapshot = snapshots.scale;\n uint128 epochSnapshot = snapshots.epoch;\n\n // If stake was made before a pool-emptying event, then it has been fully cancelled with debt -- so, return 0\n if (epochSnapshot < currentEpoch) {\n return 0;\n }\n\n uint256 compoundedStake;\n uint128 scaleDiff = currentScale.sub(scaleSnapshot);\n\n /* Compute the compounded stake. If a scale change in P was made during the stake's lifetime,\n * account for it. If more than one scale change was made, then the stake has decreased by a factor of\n * at least 1e-9 -- so return 0.\n */\n if (scaleDiff == 0) {\n compoundedStake = initialStake.mul(P).div(snapshot_P);\n } else if (scaleDiff == 1) {\n compoundedStake = initialStake.mul(P).div(snapshot_P).div(SCALE_FACTOR);\n } else {\n // if scaleDiff >= 2\n compoundedStake = 0;\n }\n\n /*\n * If compounded deposit is less than a billionth of the initial deposit, return 0.\n *\n * NOTE: originally, this line was in place to stop rounding errors making the deposit too large. However, the error\n * corrections should ensure the error in P \"favors the Pool\", i.e. any given compounded deposit should slightly less\n * than it's theoretical value.\n *\n * Thus it's unclear whether this line is still really needed.\n */\n if (compoundedStake < initialStake.div(1e9)) {\n return 0;\n }\n\n return compoundedStake;\n }\n\n // --- Sender functions for ZUSD deposit, ETH gains and SOV gains ---\n\n /// Transfer the ZUSD tokens from the user to the Stability Pool's address, and update its recorded ZUSD\n function _sendZUSDtoStabilityPool(address _address, uint256 _amount) internal {\n zusdToken.sendToPool(_address, address(this), _amount);\n uint256 newTotalZUSDDeposits = totalZUSDDeposits.add(_amount);\n totalZUSDDeposits = newTotalZUSDDeposits;\n emit StabilityPoolZUSDBalanceUpdated(newTotalZUSDDeposits);\n }\n\n function _sendETHGainToDepositor(uint256 _amount) internal {\n _sendETHGainTo(_amount, msg.sender);\n }\n\n function _sendETHGainTo(uint256 _amount, address _receiver) internal {\n require(_receiver != address(0), \"SP::_sendETHGainTo: _receiver is zero address\");\n if (_amount == 0) {\n return;\n }\n uint256 newETH = ETH.sub(_amount);\n ETH = newETH;\n emit StabilityPoolETHBalanceUpdated(newETH);\n emit EtherSent(msg.sender, _amount);\n\n (bool success, ) = msg.sender.call{ value: _amount }(\"\");\n require(success, \"StabilityPool: sending ETH failed\");\n }\n\n /// Send ZUSD to user and decrease ZUSD in Pool\n function _sendZUSDToDepositor(address _depositor, uint256 ZUSDWithdrawal) internal {\n if (ZUSDWithdrawal == 0) {\n return;\n }\n\n zusdToken.returnFromPool(address(this), _depositor, ZUSDWithdrawal);\n _decreaseZUSD(ZUSDWithdrawal);\n }\n\n // --- External Front End functions ---\n\n /// Front end makes a one-time selection of kickback rate upon registering\n function registerFrontEnd(uint256 _kickbackRate) external override {\n _requireFrontEndNotRegistered(msg.sender);\n _requireUserHasNoDeposit(msg.sender);\n _requireValidKickbackRate(_kickbackRate);\n\n frontEnds[msg.sender].kickbackRate = _kickbackRate;\n frontEnds[msg.sender].registered = true;\n\n emit FrontEndRegistered(msg.sender, _kickbackRate);\n }\n\n // --- Stability Pool Deposit Functionality ---\n\n function _setFrontEndTag(address _depositor, address _frontEndTag) internal {\n deposits[_depositor].frontEndTag = _frontEndTag;\n emit FrontEndTagSet(_depositor, _frontEndTag);\n }\n\n function _updateDepositAndSnapshots(address _depositor, uint256 _newValue) internal {\n deposits[_depositor].initialValue = _newValue;\n\n if (_newValue == 0) {\n delete deposits[_depositor].frontEndTag;\n delete depositSnapshots[_depositor];\n emit DepositSnapshotUpdated(_depositor, 0, 0, 0);\n return;\n }\n uint128 currentScaleCached = currentScale;\n uint128 currentEpochCached = currentEpoch;\n uint256 currentP = P;\n\n // Get S and G for the current epoch and current scale\n uint256 currentS = epochToScaleToSum[currentEpochCached][currentScaleCached];\n uint256 currentG = epochToScaleToG[currentEpochCached][currentScaleCached];\n\n // Record new snapshots of the latest running product P, sum S, and sum G, for the depositor\n depositSnapshots[_depositor].P = currentP;\n depositSnapshots[_depositor].S = currentS;\n depositSnapshots[_depositor].G = currentG;\n depositSnapshots[_depositor].scale = currentScaleCached;\n depositSnapshots[_depositor].epoch = currentEpochCached;\n\n emit DepositSnapshotUpdated(_depositor, currentP, currentS, currentG);\n }\n\n function _updateFrontEndStakeAndSnapshots(address _frontEnd, uint256 _newValue) internal {\n frontEndStakes[_frontEnd] = _newValue;\n\n if (_newValue == 0) {\n delete frontEndSnapshots[_frontEnd];\n emit FrontEndSnapshotUpdated(_frontEnd, 0, 0);\n return;\n }\n\n uint128 currentScaleCached = currentScale;\n uint128 currentEpochCached = currentEpoch;\n uint256 currentP = P;\n\n // Get G for the current epoch and current scale\n uint256 currentG = epochToScaleToG[currentEpochCached][currentScaleCached];\n\n // Record new snapshots of the latest running product P and sum G for the front end\n frontEndSnapshots[_frontEnd].P = currentP;\n frontEndSnapshots[_frontEnd].G = currentG;\n frontEndSnapshots[_frontEnd].scale = currentScaleCached;\n frontEndSnapshots[_frontEnd].epoch = currentEpochCached;\n\n emit FrontEndSnapshotUpdated(_frontEnd, currentP, currentG);\n }\n\n function _payOutSOVGains(\n ICommunityIssuance _communityIssuance,\n address _depositor,\n address _frontEnd\n ) internal {\n // Pay out front end's SOV gain\n if (_frontEnd != ADDRESS_ZERO) {\n uint256 frontEndSOVGain = getFrontEndSOVGain(_frontEnd);\n _communityIssuance.sendSOV(_frontEnd, frontEndSOVGain);\n emit SOVPaidToFrontEnd(_frontEnd, frontEndSOVGain);\n }\n\n // Pay out depositor's SOV gain\n uint256 depositorSOVGain = getDepositorSOVGain(_depositor);\n _communityIssuance.sendSOV(_depositor, depositorSOVGain);\n emit SOVPaidToDepositor(_depositor, depositorSOVGain);\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == address(activePool), \"StabilityPool: Caller is not ActivePool\");\n }\n\n function _requireCallerIsTroveManager() internal view {\n require(msg.sender == address(troveManager), \"StabilityPool: Caller is not TroveManager\");\n }\n\n function _requireNoUnderCollateralizedTroves() internal {\n uint256 price = priceFeed.fetchPrice();\n address lowestTrove = sortedTroves.getLast();\n uint256 ICR = troveManager.getCurrentICR(lowestTrove, price);\n require(\n ICR >= liquityBaseParams.MCR(),\n \"StabilityPool: Cannot withdraw while there are troves with ICR < MCR\"\n );\n }\n\n function _requireUserHasDeposit(uint256 _initialDeposit) internal pure {\n require(_initialDeposit > 0, \"StabilityPool: User must have a non-zero deposit\");\n }\n\n function _requireUserHasNoDeposit(address _address) internal view {\n uint256 initialDeposit = deposits[_address].initialValue;\n require(initialDeposit == 0, \"StabilityPool: User must have no deposit\");\n }\n\n function _requireNonZeroAmount(uint256 _amount) internal pure {\n require(_amount > 0, \"StabilityPool: Amount must be non-zero\");\n }\n\n function _requireUserHasTrove(address _depositor) internal view {\n require(\n troveManager.getTroveStatus(_depositor) == 1,\n \"StabilityPool: caller must have an active trove to withdraw ETHGain to\"\n );\n }\n\n function _requireUserHasETHGain(address _depositor) internal view {\n uint256 ETHGain = getDepositorETHGain(_depositor);\n require(ETHGain > 0, \"StabilityPool: caller must have non-zero ETH Gain\");\n }\n\n function _requireFrontEndNotRegistered(address _address) internal view {\n require(\n !frontEnds[_address].registered,\n \"StabilityPool: must not already be a registered front end\"\n );\n }\n\n function _requireFrontEndIsRegisteredOrZero(address _address) internal view {\n require(\n frontEnds[_address].registered || _address == ADDRESS_ZERO,\n \"StabilityPool: Tag must be a registered front end, or the zero address\"\n );\n }\n\n function _requireValidKickbackRate(uint256 _kickbackRate) internal pure {\n require(\n _kickbackRate <= DECIMAL_PRECISION,\n \"StabilityPool: Kickback rate must be in range [0,1]\"\n );\n }\n\n // --- Fallback function ---\n\n receive() external payable {\n _requireCallerIsActivePool();\n ETH = ETH.add(msg.value);\n StabilityPoolETHBalanceUpdated(ETH);\n }\n}\n" + }, + "contracts/StabilityPoolStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/IBorrowerOperations.sol\";\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/ICommunityIssuance.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/BaseMath.sol\";\n\ncontract StabilityPoolStorage is Ownable, BaseMath {\n string public constant NAME = \"StabilityPool\";\n\n IBorrowerOperations public borrowerOperations;\n\n ITroveManager public troveManager;\n\n IZUSDToken public zusdToken;\n\n // Needed to check if there are pending liquidations\n ISortedTroves public sortedTroves;\n\n ICommunityIssuance public communityIssuance;\n\n uint256 internal ETH; // deposited ether tracker\n\n // Tracker for ZUSD held in the pool. Changes when users deposit/withdraw, and when Trove debt is offset.\n uint256 internal totalZUSDDeposits;\n\n // --- Data structures ---\n\n struct FrontEnd {\n uint256 kickbackRate;\n bool registered;\n }\n\n struct Deposit {\n uint256 initialValue;\n address frontEndTag;\n }\n\n struct Snapshots {\n uint256 S;\n uint256 P;\n uint256 G;\n uint128 scale;\n uint128 epoch;\n }\n\n mapping(address => Deposit) public deposits; // depositor address -> Deposit struct\n mapping(address => Snapshots) public depositSnapshots; // depositor address -> snapshots struct\n\n mapping(address => FrontEnd) public frontEnds; // front end address -> FrontEnd struct\n mapping(address => uint256) public frontEndStakes; // front end address -> last recorded total deposits, tagged with that front end\n mapping(address => Snapshots) public frontEndSnapshots; // front end address -> snapshots struct\n\n /* Product 'P': Running product by which to multiply an initial deposit, in order to find the current compounded deposit,\n * after a series of liquidations have occurred, each of which cancel some ZUSD debt with the deposit.\n *\n * During its lifetime, a deposit's value evolves from d_t to d_t * P / P_t , where P_t\n * is the snapshot of P taken at the instant the deposit was made. 18-digit decimal.\n */\n uint256 public P;\n\n uint256 public constant SCALE_FACTOR = 1e9;\n\n // Each time the scale of P shifts by SCALE_FACTOR, the scale is incremented by 1\n uint128 public currentScale;\n\n // With each offset that fully empties the Pool, the epoch is incremented by 1\n uint128 public currentEpoch;\n\n /* ETH Gain sum 'S': During its lifetime, each deposit d_t earns an ETH gain of ( d_t * [S - S_t] )/P_t, where S_t\n * is the depositor's snapshot of S taken at the time t when the deposit was made.\n *\n * The 'S' sums are stored in a nested mapping (epoch => scale => sum):\n *\n * - The inner mapping records the sum S at different scales\n * - The outer mapping records the (scale => sum) mappings, for different epochs.\n */\n mapping(uint128 => mapping(uint128 => uint256)) public epochToScaleToSum;\n\n /*\n * Similarly, the sum 'G' is used to calculate SOV gains. During it's lifetime, each deposit d_t earns a SOV gain of\n * ( d_t * [G - G_t] )/P_t, where G_t is the depositor's snapshot of G taken at time t when the deposit was made.\n *\n * SOV reward events occur are triggered by depositor operations (new deposit, topup, withdrawal), and liquidations.\n * In each case, the SOV reward is issued (i.e. G is updated), before other state changes are made.\n */\n mapping(uint128 => mapping(uint128 => uint256)) public epochToScaleToG;\n\n // Error tracker for the error correction in the SOV issuance calculation\n uint256 public lastSOVError;\n // Error trackers for the error correction in the offset calculation\n uint256 public lastETHError_Offset;\n uint256 public lastZUSDLossError_Offset;\n}\n" + }, + "contracts/TestContracts/ActivePoolTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ActivePool.sol\";\n\ncontract ActivePoolTester is ActivePool {\n \n function unprotectedIncreaseZUSDDebt(uint _amount) external {\n ZUSDDebt = ZUSDDebt.add(_amount);\n }\n\n function unprotectedPayable() external payable {\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/TestContracts/BorrowerOperationsTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../BorrowerOperations.sol\";\n\n/* Tester contract inherits from BorrowerOperations, and provides external functions \nfor testing the parent's internal functions. */\ncontract BorrowerOperationsTester is BorrowerOperations {\n\n function getNewICRFromTroveChange\n (\n uint _coll, \n uint _debt, \n uint _collChange, \n bool isCollIncrease, \n uint _debtChange, \n bool isDebtIncrease, \n uint _price\n ) \n external\n pure\n returns (uint)\n {\n return _getNewICRFromTroveChange(_coll, _debt, _collChange, isCollIncrease, _debtChange, isDebtIncrease, _price);\n }\n\n function getNewTCRFromTroveChange\n (\n uint _collChange, \n bool isCollIncrease, \n uint _debtChange, \n bool isDebtIncrease, \n uint _price\n ) \n external \n view\n returns (uint) \n {\n return _getNewTCRFromTroveChange(_collChange, isCollIncrease, _debtChange, isDebtIncrease, _price);\n }\n\n function getUSDValue(uint _coll, uint _price) external pure returns (uint) {\n return _getUSDValue(_coll, _price);\n }\n\n function callInternalAdjustLoan\n (\n address _borrower, \n uint _collWithdrawal, \n uint _debtChange, \n bool _isDebtIncrease, \n address _upperHint,\n address _lowerHint)\n external \n {\n _adjustTrove(_borrower, _collWithdrawal, _debtChange, _isDebtIncrease, _upperHint, _lowerHint, 0);\n }\n\n\n // Payable fallback function\n receive() external payable { }\n}\n" + }, + "contracts/TestContracts/CommunityIssuanceTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/CommunityIssuance.sol\";\n\ncontract CommunityIssuanceTester is CommunityIssuance {\n function obtainSOV(uint _amount) external {\n sovToken.transfer(msg.sender, _amount);\n }\n\n function unprotectedIssueSOV(uint256 _totalZUSDDeposits) external returns (uint) {\n // No checks on caller address\n \n uint256 timePassedSinceLastIssuance = (block.timestamp.sub(lastIssuanceTime));\n uint256 latestTotalSOVIssued = _ZUSDToSOV(_totalZUSDDeposits.mul(APR).div(MAX_BPS).mul(timePassedSinceLastIssuance).div(365 days));\n \n uint256 issuance = latestTotalSOVIssued.sub(totalSOVIssued);\n\n totalSOVIssued = latestTotalSOVIssued;\n lastIssuanceTime = block.timestamp;\n emit TotalSOVIssuedUpdated(latestTotalSOVIssued);\n\n return issuance;\n }\n}\n" + }, + "contracts/TestContracts/DefaultPoolTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../DefaultPool.sol\";\n\ncontract DefaultPoolTester is DefaultPool {\n \n function unprotectedIncreaseZUSDDebt(uint _amount) external {\n ZUSDDebt = ZUSDDebt.add(_amount);\n }\n\n function unprotectedPayable() external payable {\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/TestContracts/EchidnaProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../TroveManager.sol\";\nimport \"../BorrowerOperations.sol\";\nimport \"../StabilityPool.sol\";\nimport \"../ZUSDToken.sol\";\n\ncontract EchidnaProxy {\n TroveManager troveManager;\n BorrowerOperations borrowerOperations;\n StabilityPool stabilityPool;\n ZUSDToken zusdToken;\n\n constructor(\n TroveManager _troveManager,\n BorrowerOperations _borrowerOperations,\n StabilityPool _stabilityPool,\n ZUSDToken _zusdToken\n ) public {\n troveManager = _troveManager;\n borrowerOperations = _borrowerOperations;\n stabilityPool = _stabilityPool;\n zusdToken = _zusdToken;\n }\n\n receive() external payable {\n // do nothing\n }\n\n // TroveManager\n\n function liquidatePrx(address _user) external {\n troveManager.liquidate(_user);\n }\n\n function liquidateTrovesPrx(uint _n) external {\n troveManager.liquidateTroves(_n);\n }\n\n function batchLiquidateTrovesPrx(address[] calldata _troveArray) external {\n troveManager.batchLiquidateTroves(_troveArray);\n }\n\n function redeemCollateralPrx(\n uint _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint _partialRedemptionHintNICR,\n uint _maxIterations,\n uint _maxFee\n ) external {\n troveManager.redeemCollateral(_ZUSDAmount, _firstRedemptionHint, _upperPartialRedemptionHint, _lowerPartialRedemptionHint, _partialRedemptionHintNICR, _maxIterations, _maxFee);\n }\n\n // Borrower Operations\n function openTrovePrx(uint _ETH, uint _ZUSDAmount, address _upperHint, address _lowerHint, uint _maxFee) external payable {\n borrowerOperations.openTrove{value: _ETH}(_maxFee, _ZUSDAmount, _upperHint, _lowerHint);\n }\n\n function addCollPrx(uint _ETH, address _upperHint, address _lowerHint) external payable {\n borrowerOperations.addColl{value: _ETH}(_upperHint, _lowerHint);\n }\n\n function withdrawCollPrx(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.withdrawColl(_amount, _upperHint, _lowerHint);\n }\n\n function withdrawZUSDPrx(uint _amount, address _upperHint, address _lowerHint, uint _maxFee) external {\n borrowerOperations.withdrawZUSD(_maxFee, _amount, _upperHint, _lowerHint);\n }\n\n function repayZUSDPrx(uint _amount, address _upperHint, address _lowerHint) external {\n borrowerOperations.repayZUSD(_amount, _upperHint, _lowerHint);\n }\n\n function closeTrovePrx() external {\n borrowerOperations.closeTrove();\n }\n\n function adjustTrovePrx(uint _ETH, uint _collWithdrawal, uint _debtChange, bool _isDebtIncrease, address _upperHint, address _lowerHint, uint _maxFee) external payable {\n borrowerOperations.adjustTrove{value: _ETH}(_maxFee, _collWithdrawal, _debtChange, _isDebtIncrease, _upperHint, _lowerHint);\n }\n\n // Pool Manager\n function provideToSPPrx(uint _amount, address _frontEndTag) external {\n stabilityPool.provideToSP(_amount, _frontEndTag);\n }\n\n function withdrawFromSPPrx(uint _amount) external {\n stabilityPool.withdrawFromSP(_amount);\n }\n\n // ZUSD Token\n\n function transferPrx(address recipient, uint256 amount) external returns (bool) {\n return zusdToken.transfer(recipient, amount);\n }\n\n function approvePrx(address spender, uint256 amount) external returns (bool) {\n return zusdToken.approve(spender, amount);\n }\n\n function transferFromPrx(address sender, address recipient, uint256 amount) external returns (bool) {\n return zusdToken.transferFrom(sender, recipient, amount);\n }\n\n function increaseAllowancePrx(address spender, uint256 addedValue) external returns (bool) {\n return zusdToken.increaseAllowance(spender, addedValue);\n }\n\n function decreaseAllowancePrx(address spender, uint256 subtractedValue) external returns (bool) {\n return zusdToken.decreaseAllowance(spender, subtractedValue);\n }\n}\n" + }, + "contracts/TestContracts/EchidnaTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../LiquityBaseParams.sol\";\nimport \"../Interfaces/ITroveManager.sol\";\nimport \"../TroveManager.sol\";\nimport \"../TroveManagerStorage.sol\";\nimport \"../Dependencies/TroveManagerRedeemOps.sol\";\nimport \"../BorrowerOperations.sol\";\nimport \"../ActivePool.sol\";\nimport \"../DefaultPool.sol\";\nimport \"../StabilityPool.sol\";\nimport \"../GasPool.sol\";\nimport \"../CollSurplusPool.sol\";\nimport \"../ZUSDToken.sol\";\nimport \"./PriceFeedTestnet.sol\";\nimport \"../SortedTroves.sol\";\nimport \"./EchidnaProxy.sol\";\n\n//import \"../Dependencies/console.sol\";\n\n// Run with:\n// rm -f fuzzTests/corpus/* # (optional)\n// ~/.local/bin/echidna-test contracts/TestContracts/EchidnaTester.sol --contract EchidnaTester --config fuzzTests/echidna_config.yaml\n\ncontract EchidnaTester {\n using SafeMath for uint;\n\n uint private constant NUMBER_OF_ACTORS = 100;\n uint private constant INITIAL_BALANCE = 1e24;\n uint private MCR;\n uint private CCR;\n uint private ZUSD_GAS_COMPENSATION;\n\n LiquityBaseParams public liquityBaseParams;\n TroveManagerRedeemOps public troveManagerRedeemOps;\n TroveManager public troveManager;\n BorrowerOperations public borrowerOperations;\n ActivePool public activePool;\n DefaultPool public defaultPool;\n StabilityPool public stabilityPool;\n GasPool public gasPool;\n CollSurplusPool public collSurplusPool;\n ZUSDToken public zusdToken;\n PriceFeedTestnet priceFeedTestnet;\n SortedTroves sortedTroves;\n\n EchidnaProxy[NUMBER_OF_ACTORS] public echidnaProxies;\n\n uint private numberOfTroves;\n\n constructor() public payable {\n liquityBaseParams = new LiquityBaseParams();\n troveManagerRedeemOps = new TroveManagerRedeemOps(14 * 86400);\n troveManager = new TroveManager(14 days);\n borrowerOperations = new BorrowerOperations();\n activePool = new ActivePool();\n defaultPool = new DefaultPool();\n stabilityPool = new StabilityPool();\n gasPool = new GasPool();\n zusdToken = new ZUSDToken();\n zusdToken.initialize(\n address(troveManager),\n address(stabilityPool),\n address(borrowerOperations)\n );\n\n collSurplusPool = new CollSurplusPool();\n priceFeedTestnet = new PriceFeedTestnet();\n\n sortedTroves = new SortedTroves();\n\n troveManager.setAddresses(\n ITroveManager.TroveManagerInitAddressesParams(\n address(0),\n address(troveManagerRedeemOps),\n address(liquityBaseParams),\n address(borrowerOperations),\n address(activePool),\n address(defaultPool),\n address(stabilityPool),\n address(gasPool),\n address(collSurplusPool),\n address(priceFeedTestnet),\n address(zusdToken),\n address(sortedTroves),\n address(0),\n address(0)\n )\n );\n\n borrowerOperations.setAddresses(\n address(0),\n address(liquityBaseParams),\n address(troveManager),\n address(activePool),\n address(defaultPool),\n address(stabilityPool),\n address(gasPool),\n address(collSurplusPool),\n address(priceFeedTestnet),\n address(sortedTroves),\n address(zusdToken),\n address(0)\n );\n\n activePool.setAddresses(\n address(borrowerOperations),\n address(troveManager),\n address(stabilityPool),\n address(defaultPool)\n );\n\n defaultPool.setAddresses(address(troveManager), address(activePool));\n\n stabilityPool.setAddresses(\n address(liquityBaseParams),\n address(borrowerOperations),\n address(troveManager),\n address(activePool),\n address(zusdToken),\n address(sortedTroves),\n address(priceFeedTestnet),\n address(0)\n );\n\n collSurplusPool.setAddresses(\n address(borrowerOperations),\n address(troveManager),\n address(activePool)\n );\n\n sortedTroves.setParams(1e18, address(troveManager), address(borrowerOperations));\n\n for (uint i = 0; i < NUMBER_OF_ACTORS; i++) {\n echidnaProxies[i] = new EchidnaProxy(\n troveManager,\n borrowerOperations,\n stabilityPool,\n zusdToken\n );\n (bool success, ) = address(echidnaProxies[i]).call{ value: INITIAL_BALANCE }(\"\");\n require(success);\n }\n\n MCR = borrowerOperations.liquityBaseParams().MCR();\n CCR = borrowerOperations.liquityBaseParams().CCR();\n ZUSD_GAS_COMPENSATION = borrowerOperations.ZUSD_GAS_COMPENSATION();\n require(MCR > 0);\n require(CCR > 0);\n\n // TODO:\n priceFeedTestnet.setPrice(1e22);\n }\n\n // TroveManager\n\n function liquidateExt(uint _i, address _user) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].liquidatePrx(_user);\n }\n\n function liquidateTrovesExt(uint _i, uint _n) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].liquidateTrovesPrx(_n);\n }\n\n function batchLiquidateTrovesExt(uint _i, address[] calldata _troveArray) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].batchLiquidateTrovesPrx(_troveArray);\n }\n\n function redeemCollateralExt(\n uint _i,\n uint _ZUSDAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint _partialRedemptionHintNICR\n ) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].redeemCollateralPrx(\n _ZUSDAmount,\n _firstRedemptionHint,\n _upperPartialRedemptionHint,\n _lowerPartialRedemptionHint,\n _partialRedemptionHintNICR,\n 0,\n 0\n );\n }\n\n // Borrower Operations\n\n function getAdjustedETH(\n uint actorBalance,\n uint _ETH,\n uint ratio\n ) internal view returns (uint) {\n uint price = priceFeedTestnet.getPrice();\n require(price > 0);\n uint minETH = ratio.mul(ZUSD_GAS_COMPENSATION).div(price);\n require(actorBalance > minETH);\n uint ETH = minETH + (_ETH % (actorBalance - minETH));\n return ETH;\n }\n\n function getAdjustedZUSD(uint ETH, uint _ZUSDAmount, uint ratio) internal view returns (uint) {\n uint price = priceFeedTestnet.getPrice();\n uint ZUSDAmount = _ZUSDAmount;\n uint compositeDebt = ZUSDAmount.add(ZUSD_GAS_COMPENSATION);\n uint ICR = LiquityMath._computeCR(ETH, compositeDebt, price);\n if (ICR < ratio) {\n compositeDebt = ETH.mul(price).div(ratio);\n ZUSDAmount = compositeDebt.sub(ZUSD_GAS_COMPENSATION);\n }\n return ZUSDAmount;\n }\n\n function openTroveExt(uint _i, uint _ETH, uint _ZUSDAmount) public payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n EchidnaProxy echidnaProxy = echidnaProxies[actor];\n uint actorBalance = address(echidnaProxy).balance;\n\n // we pass in CCR instead of MCR in case it’s the first one\n uint ETH = getAdjustedETH(actorBalance, _ETH, CCR);\n uint ZUSDAmount = getAdjustedZUSD(ETH, _ZUSDAmount, CCR);\n\n echidnaProxy.openTrovePrx(ETH, ZUSDAmount, address(0), address(0), 0);\n\n numberOfTroves = troveManager.getTroveOwnersCount();\n assert(numberOfTroves > 0);\n // canary\n //assert(numberOfTroves == 0);\n }\n\n function openTroveRawExt(\n uint _i,\n uint _ETH,\n uint _ZUSDAmount,\n address _upperHint,\n address _lowerHint,\n uint _maxFee\n ) public payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].openTrovePrx(_ETH, _ZUSDAmount, _upperHint, _lowerHint, _maxFee);\n }\n\n function addCollExt(uint _i, uint _ETH) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n EchidnaProxy echidnaProxy = echidnaProxies[actor];\n uint actorBalance = address(echidnaProxy).balance;\n\n uint ETH = getAdjustedETH(actorBalance, _ETH, MCR);\n\n echidnaProxy.addCollPrx(ETH, address(0), address(0));\n }\n\n function addCollRawExt(\n uint _i,\n uint _ETH,\n address _upperHint,\n address _lowerHint\n ) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].addCollPrx(_ETH, _upperHint, _lowerHint);\n }\n\n function withdrawCollExt(\n uint _i,\n uint _amount,\n address _upperHint,\n address _lowerHint\n ) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].withdrawCollPrx(_amount, _upperHint, _lowerHint);\n }\n\n function withdrawZUSDExt(\n uint _i,\n uint _amount,\n address _upperHint,\n address _lowerHint,\n uint _maxFee\n ) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].withdrawZUSDPrx(_amount, _upperHint, _lowerHint, _maxFee);\n }\n\n function repayZUSDExt(uint _i, uint _amount, address _upperHint, address _lowerHint) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].repayZUSDPrx(_amount, _upperHint, _lowerHint);\n }\n\n function closeTroveExt(uint _i) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].closeTrovePrx();\n }\n\n function adjustTroveExt(\n uint _i,\n uint _ETH,\n uint _collWithdrawal,\n uint _debtChange,\n bool _isDebtIncrease\n ) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n EchidnaProxy echidnaProxy = echidnaProxies[actor];\n uint actorBalance = address(echidnaProxy).balance;\n\n uint ETH = getAdjustedETH(actorBalance, _ETH, MCR);\n uint debtChange = _debtChange;\n if (_isDebtIncrease) {\n // TODO: add current amount already withdrawn:\n debtChange = getAdjustedZUSD(ETH, uint(_debtChange), MCR);\n }\n // TODO: collWithdrawal, debtChange\n echidnaProxy.adjustTrovePrx(\n ETH,\n _collWithdrawal,\n debtChange,\n _isDebtIncrease,\n address(0),\n address(0),\n 0\n );\n }\n\n function adjustTroveRawExt(\n uint _i,\n uint _ETH,\n uint _collWithdrawal,\n uint _debtChange,\n bool _isDebtIncrease,\n address _upperHint,\n address _lowerHint,\n uint _maxFee\n ) external payable {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].adjustTrovePrx(\n _ETH,\n _collWithdrawal,\n _debtChange,\n _isDebtIncrease,\n _upperHint,\n _lowerHint,\n _maxFee\n );\n }\n\n // Pool Manager\n\n function provideToSPExt(uint _i, uint _amount, address _frontEndTag) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].provideToSPPrx(_amount, _frontEndTag);\n }\n\n function withdrawFromSPExt(uint _i, uint _amount) external {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].withdrawFromSPPrx(_amount);\n }\n\n // ZUSD Token\n\n function transferExt(uint _i, address recipient, uint256 amount) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].transferPrx(recipient, amount);\n }\n\n function approveExt(uint _i, address spender, uint256 amount) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].approvePrx(spender, amount);\n }\n\n function transferFromExt(\n uint _i,\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].transferFromPrx(sender, recipient, amount);\n }\n\n function increaseAllowanceExt(\n uint _i,\n address spender,\n uint256 addedValue\n ) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].increaseAllowancePrx(spender, addedValue);\n }\n\n function decreaseAllowanceExt(\n uint _i,\n address spender,\n uint256 subtractedValue\n ) external returns (bool) {\n uint actor = _i % NUMBER_OF_ACTORS;\n echidnaProxies[actor].decreaseAllowancePrx(spender, subtractedValue);\n }\n\n // PriceFeed\n\n function setPriceExt(uint256 _price) external {\n bool result = priceFeedTestnet.setPrice(_price);\n assert(result);\n }\n\n // --------------------------\n // Invariants and properties\n // --------------------------\n\n function echidna_canary_number_of_troves() public view returns (bool) {\n if (numberOfTroves > 20) {\n return false;\n }\n\n return true;\n }\n\n function echidna_canary_active_pool_balance() public view returns (bool) {\n if (address(activePool).balance > 0) {\n return false;\n }\n return true;\n }\n\n function echidna_troves_order() external view returns (bool) {\n address currentTrove = sortedTroves.getFirst();\n address nextTrove = sortedTroves.getNext(currentTrove);\n\n while (currentTrove != address(0) && nextTrove != address(0)) {\n if (troveManager.getNominalICR(nextTrove) > troveManager.getNominalICR(currentTrove)) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n currentTrove = nextTrove;\n nextTrove = sortedTroves.getNext(currentTrove);\n }\n\n return true;\n }\n\n /**\n * Status\n * Minimum debt (gas compensation)\n * Stake > 0\n */\n function echidna_trove_properties() public view returns (bool) {\n address currentTrove = sortedTroves.getFirst();\n while (currentTrove != address(0)) {\n // Status\n if (\n TroveManagerStorage.Status(troveManager.getTroveStatus(currentTrove)) !=\n TroveManagerStorage.Status.active\n ) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n // Minimum debt (gas compensation)\n if (troveManager.getTroveDebt(currentTrove) < ZUSD_GAS_COMPENSATION) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n // Stake > 0\n if (troveManager.getTroveStake(currentTrove) == 0) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n currentTrove = sortedTroves.getNext(currentTrove);\n }\n return true;\n }\n\n function echidna_ETH_balances() public view returns (bool) {\n if (address(troveManager).balance > 0) {\n return false;\n }\n\n if (address(borrowerOperations).balance > 0) {\n return false;\n }\n\n if (address(activePool).balance != activePool.getETH()) {\n return false;\n }\n\n if (address(defaultPool).balance != defaultPool.getETH()) {\n return false;\n }\n\n if (address(stabilityPool).balance != stabilityPool.getETH()) {\n return false;\n }\n\n if (address(zusdToken).balance > 0) {\n return false;\n }\n\n if (address(priceFeedTestnet).balance > 0) {\n return false;\n }\n\n if (address(sortedTroves).balance > 0) {\n return false;\n }\n\n return true;\n }\n\n // TODO: What should we do with this? Should it be allowed? Should it be a canary?\n function echidna_price() public view returns (bool) {\n uint price = priceFeedTestnet.getPrice();\n\n if (price == 0) {\n return false;\n }\n // Uncomment to check that the condition is meaningful\n //else return false;\n\n return true;\n }\n\n // Total ZUSD matches\n function echidna_ZUSD_global_balances() public view returns (bool) {\n uint totalSupply = zusdToken.totalSupply();\n uint gasPoolBalance = zusdToken.balanceOf(address(gasPool));\n\n uint activePoolBalance = activePool.getZUSDDebt();\n uint defaultPoolBalance = defaultPool.getZUSDDebt();\n if (totalSupply != activePoolBalance + defaultPoolBalance) {\n return false;\n }\n\n uint stabilityPoolBalance = stabilityPool.getTotalZUSDDeposits();\n address currentTrove = sortedTroves.getFirst();\n uint trovesBalance;\n while (currentTrove != address(0)) {\n trovesBalance += zusdToken.balanceOf(address(currentTrove));\n currentTrove = sortedTroves.getNext(currentTrove);\n }\n // we cannot state equality because tranfers are made to external addresses too\n if (totalSupply <= stabilityPoolBalance + trovesBalance + gasPoolBalance) {\n return false;\n }\n\n return true;\n }\n\n /*\n function echidna_test() public view returns(bool) {\n return true;\n }\n */\n}\n" + }, + "contracts/TestContracts/ExternalPriceFeedTester.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Dependencies/PriceFeed/IExternalPriceFeed.sol\";\n\ninterface IMoCBaseOracle {\n function peek() external view returns (bytes32, bool);\n}\n\ncontract ExternalPriceFeedTester is IExternalPriceFeed {\n uint256 price;\n bool success;\n\n function setLatestAnswer(uint256 _price, bool _success) external {\n price = _price;\n success = _success;\n }\n\n function latestAnswer() external view override returns (uint256, bool) {\n return (price, success);\n }\n}\n" + }, + "contracts/TestContracts/FunctionCaller.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/ITroveManager.sol\";\nimport \"../Interfaces/ISortedTroves.sol\";\nimport \"../Interfaces/IPriceFeed.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\n\n/* Wrapper contract - used for calculating gas of read-only and internal functions. \nNot part of the Zero application. */\ncontract FunctionCaller {\n ITroveManager troveManager;\n address public troveManagerAddress;\n\n ISortedTroves sortedTroves;\n address public sortedTrovesAddress;\n\n IPriceFeed priceFeed;\n address public priceFeedAddress;\n\n // --- Dependency setters ---\n\n function setTroveManagerAddress(address _troveManagerAddress) external {\n troveManagerAddress = _troveManagerAddress;\n troveManager = ITroveManager(_troveManagerAddress);\n }\n\n function setSortedTrovesAddress(address _sortedTrovesAddress) external {\n troveManagerAddress = _sortedTrovesAddress;\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n }\n\n function setPriceFeedAddress(address _priceFeedAddress) external {\n priceFeedAddress = _priceFeedAddress;\n priceFeed = IPriceFeed(_priceFeedAddress);\n }\n\n // --- Non-view wrapper functions used for calculating gas ---\n\n function troveManager_getCurrentICR(address _address, uint256 _price)\n external\n returns (uint256)\n {\n return troveManager.getCurrentICR(_address, _price);\n }\n\n function sortedTroves_findInsertPosition(\n uint256 _NICR,\n address _prevId,\n address _nextId\n ) external returns (address, address) {\n return sortedTroves.findInsertPosition(_NICR, _prevId, _nextId);\n }\n}\n" + }, + "contracts/TestContracts/LiquityMathTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/LiquityMath.sol\";\n\n/* Tester contract for math functions in Math.sol library. */\n\ncontract LiquityMathTester {\n\n function callMax(uint _a, uint _b) external pure returns (uint) {\n return LiquityMath._max(_a, _b);\n }\n\n // Non-view wrapper for gas test\n function callDecPowTx(uint _base, uint _n) external returns (uint) {\n return LiquityMath._decPow(_base, _n);\n }\n\n // External wrapper\n function callDecPow(uint _base, uint _n) external pure returns (uint) {\n return LiquityMath._decPow(_base, _n);\n }\n}\n" + }, + "contracts/TestContracts/LiquitySafeMath128Tester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/LiquitySafeMath128.sol\";\n\n/* Tester contract for math functions in LiquitySafeMath128.sol library. */\n\ncontract LiquitySafeMath128Tester {\n using LiquitySafeMath128 for uint128;\n\n function add(uint128 a, uint128 b) external pure returns (uint128) {\n return a.add(b);\n }\n\n function sub(uint128 a, uint128 b) external pure returns (uint128) {\n return a.sub(b);\n }\n}\n" + }, + "contracts/TestContracts/MassetManagerTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { ERC20Permit } from \"@openzeppelin/contracts/drafts/ERC20Permit.sol\";\nimport \"../BorrowerOperationsStorage.sol\";\nimport \"hardhat/console.sol\";\n\n//TODO: rename NueMockToken to contract DLLRMockToken is ERC20(\"Sovryn Dollar\", \"DLLR\")\ncontract NueMockToken is ERC20(\"Nuestro\", \"NUE\"), ERC20Permit(\"Nuestro\"), Ownable {\n constructor() public {}\n\n function mint(address _account, uint256 _amount) public onlyOwner {\n _mint(_account, _amount);\n }\n\n function burn(address _account, uint256 _amount) public onlyOwner {\n _burn(_account, _amount);\n }\n\n function getChainId() external pure returns (uint256 chainID) {\n //return _chainID(); // it’s private\n assembly {\n chainID := chainid()\n }\n }\n\n function transferWithPermit(\n address _from,\n address _to,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external {\n permit(_from, msg.sender, _amount, _deadline, _v, _r, _s);\n transferFrom(_from, _to, _amount);\n }\n\n //TODO: add EIP-2612 Permit functionality\n}\n\ncontract MassetManagerTester is IMassetManager {\n NueMockToken public nueMockToken;\n\n constructor() public {\n nueMockToken = new NueMockToken();\n }\n\n function mintTo(\n address _bAsset,\n uint256 _bAssetQuantity,\n address _recipient\n ) external override returns (uint256) {\n IERC20(_bAsset).transferFrom(msg.sender, address(this), _bAssetQuantity);\n uint256 nueBalanceOfRecipientBeforeMint = nueMockToken.balanceOf(_recipient);\n nueMockToken.mint(_recipient, _bAssetQuantity);\n return nueMockToken.balanceOf(_recipient) - nueBalanceOfRecipientBeforeMint;\n }\n\n function getToken() external view override returns (address) {\n return address(nueMockToken);\n }\n\n /// @dev Transfer 'bAsset' to the recipient then burn the 'aggregator' nueMockToken\n function redeemTo(\n address _bAsset, //ZUSD nueMockToken\n uint256 _massetQuantity,\n address _recipient //user\n ) external override returns (uint256 massetRedeemed) {\n ERC20(_bAsset).transfer(_recipient, _massetQuantity);\n // nueMockToken.burn(_recipient, _massetQuantity); // _recipient used to be for the previous bridge-like implementation\n nueMockToken.burn(msg.sender, _massetQuantity);\n\n return _massetQuantity;\n }\n}\n" + }, + "contracts/TestContracts/MockFeeSharingCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/ZEROToken.sol\";\n\ninterface MockIFeeSharingCollector {\n\tfunction transferTokens(address _token, uint96 _amount) external;\n}\n\n/// @dev Simple contract that will receive ZERO tokens issued to the SOV stakers.\ncontract MockFeeSharingCollector is MockIFeeSharingCollector {\n\tfunction transferTokens(address _token, uint96 _amount) override external {\n\t\t/// Just a fake function to receive the tokens\n\t\tZEROToken(_token).transferFrom(msg.sender, address(this), _amount);\n\t}\n\n\tfunction transferRBTC() external payable {}\n}\n" + }, + "contracts/TestContracts/PriceFeedSovryn.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IPriceFeedSovryn.sol\";\nimport \"../Dependencies/SafeMath.sol\";\n\n/*\n* PriceFeed placeholder for testnet and development. The price is simply set manually and saved in a state \n* variable. The contract does not connect to a live Chainlink price feed. \n*/\ncontract PriceFeedSovryn {\n using SafeMath for uint256;\n\n mapping(address => mapping(address => uint256)) public prices;\n\n // --- Functions ---\n // Manual external price setter.\n function setPrice(address sourceToken, address destToken, uint256 price) external {\n prices[sourceToken][destToken] = price;\n }\n\n function queryRate(address sourceToken, address destToken) public view returns(uint256 rate, uint256 precision) {\n return (prices[sourceToken][destToken], 1e18);\n }\n\n function queryReturn(\n address sourceToken,\n address destToken,\n uint256 sourceAmount\n ) public view returns (uint256 destAmount) {\n (uint256 rate, uint256 precision) = queryRate(sourceToken, destToken);\n return sourceAmount.mul(rate).div(precision);\n }\n}\n" + }, + "contracts/TestContracts/PriceFeedTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../PriceFeed.sol\";\n\ncontract PriceFeedTester is PriceFeed {\n function setLastGoodPrice(uint256 _lastGoodPrice) external {\n lastGoodPrice = _lastGoodPrice;\n }\n}\n" + }, + "contracts/TestContracts/PriceFeedTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IPriceFeed.sol\";\n\n/*\n* PriceFeed placeholder for testnet and development. The price is simply set manually and saved in a state \n* variable. The contract does not connect to a live Chainlink price feed. \n*/\ncontract PriceFeedTestnet is IPriceFeed {\n \n uint256 private _price = 200 * 1e18;\n\n // --- Functions ---\n\n // View price getter for simplicity in tests\n function getPrice() external view returns (uint256) {\n return _price;\n }\n\n function fetchPrice() external override returns (uint256) {\n // Fire an event just like the mainnet version would.\n // This lets the subgraph rely on events to get the latest price even when developing locally.\n emit LastGoodPriceUpdated(_price);\n return _price;\n }\n\n // Manual external price setter.\n function setPrice(uint256 price) external returns (bool) {\n _price = price;\n return true;\n }\n}\n" + }, + "contracts/TestContracts/SortedTrovesTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/ISortedTroves.sol\";\n\n\ncontract SortedTrovesTester {\n ISortedTroves sortedTroves;\n\n function setSortedTroves(address _sortedTrovesAddress) external {\n sortedTroves = ISortedTroves(_sortedTrovesAddress);\n }\n\n function insert(address _id, uint256 _NICR, address _prevId, address _nextId) external {\n sortedTroves.insert(_id, _NICR, _prevId, _nextId);\n }\n\n function remove(address _id) external {\n sortedTroves.remove(_id);\n }\n\n function reInsert(address _id, uint256 _newNICR, address _prevId, address _nextId) external {\n sortedTroves.reInsert(_id, _newNICR, _prevId, _nextId);\n }\n\n function getNominalICR(address) external pure returns (uint) {\n return 1;\n }\n\n function getCurrentICR(address, uint) external pure returns (uint) {\n return 1;\n }\n}\n" + }, + "contracts/TestContracts/StabilityPoolTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../StabilityPool.sol\";\n\ncontract StabilityPoolTester is StabilityPool {\n \n function unprotectedPayable() external payable {\n ETH = ETH.add(msg.value);\n }\n}\n" + }, + "contracts/TestContracts/TroveManagerTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../TroveManager.sol\";\n\n/* Tester contract inherits from TroveManager, and provides external functions \nfor testing the parent's internal functions. */\n\ncontract TroveManagerTester is TroveManager(14 days) {\n function computeICR(uint _coll, uint _debt, uint _price) external pure returns (uint) {\n return LiquityMath._computeCR(_coll, _debt, _price);\n }\n\n function getCollGasCompensation(uint _coll) external view returns (uint) {\n return _getCollGasCompensation(_coll);\n }\n\n function getZUSDGasCompensation() external pure returns (uint) {\n return ZUSD_GAS_COMPENSATION;\n }\n\n function getCompositeDebt(uint _debt) external pure returns (uint) {\n return _getCompositeDebt(_debt);\n }\n\n function unprotectedDecayBaseRateFromBorrowing() external returns (uint) {\n baseRate = _calcDecayedBaseRate();\n assert(baseRate >= 0 && baseRate <= DECIMAL_PRECISION);\n\n _updateLastFeeOpTime();\n return baseRate;\n }\n\n function minutesPassedSinceLastFeeOp() external view returns (uint) {\n return _minutesPassedSinceLastFeeOp();\n }\n\n function setLastFeeOpTimeToNow() external {\n lastFeeOperationTime = block.timestamp;\n }\n\n function setBaseRate(uint _baseRate) external {\n baseRate = _baseRate;\n }\n\n function callGetRedemptionFee(uint _ETHDrawn) external view returns (uint) {\n _getRedemptionFee(_ETHDrawn);\n }\n\n function getActualDebtFromComposite(uint _debtVal) external pure returns (uint) {\n return _getNetDebt(_debtVal);\n }\n\n function callInternalRemoveTroveOwner(address _troveOwner) external {\n uint troveOwnersArrayLength = TroveOwners.length;\n _removeTroveOwner(_troveOwner, troveOwnersArrayLength);\n }\n}\n" + }, + "contracts/TestContracts/UpgradableProxyTester.sol": { + "content": "\n// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"../Proxy/UpgradableProxy.sol\";\ncontract Storage {\n uint someVar;\n}\n\ncontract ProxiableContract is Storage {\n\n function getSomeVar() public view returns (uint) {\n return someVar;\n }\n\n function setSomeVar(uint value) public {\n someVar = value;\n }\n}\n\ncontract Storage2 {\n uint anotherVar;\n}\n\ncontract ProxiableContract2 is ProxiableContract, Storage2 {\n\n function getAnotherVar() public view returns (uint) {\n return anotherVar;\n }\n\n function setAnotherVar(uint value) public {\n anotherVar = value;\n }\n\n function mulVars() public view returns (uint) {\n return someVar * anotherVar;\n }\n}\n\ncontract UpgradableProxyTester is UpgradableProxy, Storage {}\n" + }, + "contracts/TestContracts/ZEROStakingTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/ZEROStaking.sol\";\n\n\ncontract ZEROStakingTester is ZEROStaking {\n function requireCallerIsFeeDistributor() external view {\n _requireCallerIsFeeDistributor();\n }\n}\n" + }, + "contracts/TestContracts/ZEROTokenTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZERO/ZEROToken.sol\";\n\ncontract ZEROTokenTester is ZEROToken {\n constructor\n (\n address _zeroStakingAddress,\n address _marketMakerAddress,\n address _presaleAddress\n ) \n public \n {\n initialize(\n _zeroStakingAddress,\n _marketMakerAddress,\n _presaleAddress\n );\n } \n\n function unprotectedMint(address account, uint256 amount) external {\n // No check for the caller here\n\n _mint(account, amount);\n }\n\n function unprotectedSendToZEROStaking(address _sender, uint256 _amount) external {\n // No check for the caller here\n \n _transfer(_sender, zeroStakingAddress, _amount);\n }\n\n function callInternalApprove(address owner, address spender, uint256 amount) external returns (bool) {\n _approve(owner, spender, amount);\n }\n\n function callInternalTransfer(address sender, address recipient, uint256 amount) external returns (bool) {\n _transfer(sender, recipient, amount);\n }\n\n function getChainId() external pure returns (uint256 chainID) {\n //return _chainID(); // it’s private\n assembly {\n chainID := chainid()\n }\n }\n}" + }, + "contracts/TestContracts/ZUSDTokenCaller.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IZUSDToken.sol\";\n\ncontract ZUSDTokenCaller {\n IZUSDToken ZUSD;\n\n function setZUSD(IZUSDToken _ZUSD) external {\n ZUSD = _ZUSD;\n }\n\n function zusdMint(address _account, uint _amount) external {\n ZUSD.mint(_account, _amount);\n }\n\n function zusdBurn(address _account, uint _amount) external {\n ZUSD.burn(_account, _amount);\n }\n\n function zusdSendToPool(address _sender, address _poolAddress, uint256 _amount) external {\n ZUSD.sendToPool(_sender, _poolAddress, _amount);\n }\n\n function zusdReturnFromPool(address _poolAddress, address _receiver, uint256 _amount ) external {\n ZUSD.returnFromPool(_poolAddress, _receiver, _amount);\n }\n}\n" + }, + "contracts/TestContracts/ZUSDTokenTester.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../ZUSDToken.sol\";\n\ncontract ZUSDTokenTester is ZUSDToken {\n \n constructor( \n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) public {\n initialize(_troveManagerAddress, _stabilityPoolAddress, _borrowerOperationsAddress);\n }\n \n function unprotectedMint(address _account, uint256 _amount) external {\n // No check on caller here\n\n _mint(_account, _amount);\n }\n\n function unprotectedBurn(address _account, uint _amount) external {\n // No check on caller here\n \n _burn(_account, _amount);\n }\n\n function unprotectedSendToPool(address _sender, address _poolAddress, uint256 _amount) external {\n // No check on caller here\n\n _transfer(_sender, _poolAddress, _amount);\n }\n\n function unprotectedReturnFromPool(address _poolAddress, address _receiver, uint256 _amount ) external {\n // No check on caller here\n\n _transfer(_poolAddress, _receiver, _amount);\n }\n\n function callInternalApprove(address owner, address spender, uint256 amount) external returns (bool) {\n _approve(owner, spender, amount);\n }\n\n function getChainId() external pure returns (uint256 chainID) {\n //return _chainID(); // it’s private\n assembly {\n chainID := chainid()\n }\n }\n\n function getDigest(address owner, address spender, uint amount, uint nonce, uint deadline) external view returns (bytes32) {\n return keccak256(abi.encodePacked(\n uint16(0x1901),\n domainSeparator(),\n keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, amount, nonce, deadline))\n )\n );\n }\n\n function recoverAddress(bytes32 digest, uint8 v, bytes32 r, bytes32 s) external pure returns (address) {\n return ecrecover(digest, v, r, s);\n }\n}\n" + }, + "contracts/TestContracts/ZUSDTokenTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IZUSDToken.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/console.sol\";\nimport \"../ZUSDToken.sol\";\n\n/**\n *\n * Based upon OpenZeppelin's ERC20 contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol\n *\n * and their EIP2612 (ERC20Permit / ERC712) functionality:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\n *\n *\n * --- Functionality added specific to the ZUSDToken ---\n *\n * 1) Transfer protection: blacklist of addresses that are invalid recipients (i.e. core Zero contracts) in external\n * transfer() and transferFrom() calls. The purpose is to protect users from losing tokens by mistakenly sending ZUSD directly to a Zero\n * core contract, when they should rather call the right function.\n *\n * 2) sendToPool() and returnFromPool(): functions callable only Zero core contracts, which move ZUSD tokens between Zero <-> user.\n */\n\n/// @dev ZUSDTokenTestnet has unptotected initialize function to bypass initializer() modifier validation\n/// @notice use if need to redeploy the token logic AND run initialize() again on the proxy\ncontract ZUSDTokenTestnet is ZUSDToken {\n function initialize(\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) public override onlyOwner {\n _initialize(_troveManagerAddress, _stabilityPoolAddress, _borrowerOperationsAddress);\n }\n}\n" + }, + "contracts/TroveManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./Interfaces/ITroveManager.sol\";\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROToken.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/LiquityBase.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./Dependencies/TroveManagerBase.sol\";\nimport \"./TroveManagerStorage.sol\";\n\ncontract TroveManager is TroveManagerBase, CheckContract, ITroveManager {\n event FeeDistributorAddressChanged(address _feeDistributorAddress);\n event TroveManagerRedeemOpsAddressChanged(address _troveManagerRedeemOps);\n event LiquityBaseParamsAddressChanges(address _borrowerOperationsAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n event PriceFeedAddressChanged(address _newPriceFeedAddress);\n event ZUSDTokenAddressChanged(address _newZUSDTokenAddress);\n event ActivePoolAddressChanged(address _activePoolAddress);\n event DefaultPoolAddressChanged(address _defaultPoolAddress);\n event StabilityPoolAddressChanged(address _stabilityPoolAddress);\n event GasPoolAddressChanged(address _gasPoolAddress);\n event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress);\n event SortedTrovesAddressChanged(address _sortedTrovesAddress);\n event ZEROTokenAddressChanged(address _zeroTokenAddress);\n event ZEROStakingAddressChanged(address _zeroStakingAddress);\n\n ///@param _bootstrapPeriod During bootsrap period redemptions are not allowed\n constructor(uint256 _bootstrapPeriod) public TroveManagerBase(_bootstrapPeriod) {}\n\n // --- Dependency setter ---\n function setAddresses(\n TroveManagerInitAddressesParams memory _troveManagerInitAddressesParams\n ) external override onlyOwner {\n {\n checkContract(_troveManagerInitAddressesParams._feeDistributorAddress);\n checkContract(_troveManagerInitAddressesParams._troveManagerRedeemOps);\n checkContract(_troveManagerInitAddressesParams._liquityBaseParamsAddress);\n checkContract(_troveManagerInitAddressesParams._borrowerOperationsAddress);\n checkContract(_troveManagerInitAddressesParams._activePoolAddress);\n checkContract(_troveManagerInitAddressesParams._defaultPoolAddress);\n checkContract(_troveManagerInitAddressesParams._stabilityPoolAddress);\n checkContract(_troveManagerInitAddressesParams._gasPoolAddress);\n checkContract(_troveManagerInitAddressesParams._collSurplusPoolAddress);\n checkContract(_troveManagerInitAddressesParams._priceFeedAddress);\n checkContract(_troveManagerInitAddressesParams._zusdTokenAddress);\n checkContract(_troveManagerInitAddressesParams._sortedTrovesAddress);\n checkContract(_troveManagerInitAddressesParams._zeroTokenAddress);\n checkContract(_troveManagerInitAddressesParams._zeroStakingAddress);\n }\n\n feeDistributor = IFeeDistributor(_troveManagerInitAddressesParams._feeDistributorAddress);\n troveManagerRedeemOps = _troveManagerInitAddressesParams._troveManagerRedeemOps;\n liquityBaseParams = ILiquityBaseParams(\n _troveManagerInitAddressesParams._liquityBaseParamsAddress\n );\n {\n borrowerOperationsAddress = _troveManagerInitAddressesParams\n ._borrowerOperationsAddress;\n activePool = IActivePool(_troveManagerInitAddressesParams._activePoolAddress);\n defaultPool = IDefaultPool(_troveManagerInitAddressesParams._defaultPoolAddress);\n _stabilityPool = IStabilityPool(\n _troveManagerInitAddressesParams._stabilityPoolAddress\n );\n gasPoolAddress = _troveManagerInitAddressesParams._gasPoolAddress;\n collSurplusPool = ICollSurplusPool(\n _troveManagerInitAddressesParams._collSurplusPoolAddress\n );\n priceFeed = IPriceFeed(_troveManagerInitAddressesParams._priceFeedAddress);\n _zusdToken = IZUSDToken(_troveManagerInitAddressesParams._zusdTokenAddress);\n sortedTroves = ISortedTroves(_troveManagerInitAddressesParams._sortedTrovesAddress);\n _zeroToken = IZEROToken(_troveManagerInitAddressesParams._zeroTokenAddress);\n _zeroStaking = IZEROStaking(_troveManagerInitAddressesParams._zeroStakingAddress);\n }\n\n emit FeeDistributorAddressChanged(_troveManagerInitAddressesParams._feeDistributorAddress);\n emit TroveManagerRedeemOpsAddressChanged(\n _troveManagerInitAddressesParams._troveManagerRedeemOps\n );\n emit LiquityBaseParamsAddressChanges(\n _troveManagerInitAddressesParams._borrowerOperationsAddress\n );\n emit BorrowerOperationsAddressChanged(\n _troveManagerInitAddressesParams._borrowerOperationsAddress\n );\n emit ActivePoolAddressChanged(_troveManagerInitAddressesParams._activePoolAddress);\n emit DefaultPoolAddressChanged(_troveManagerInitAddressesParams._defaultPoolAddress);\n emit StabilityPoolAddressChanged(_troveManagerInitAddressesParams._stabilityPoolAddress);\n emit GasPoolAddressChanged(_troveManagerInitAddressesParams._gasPoolAddress);\n emit CollSurplusPoolAddressChanged(\n _troveManagerInitAddressesParams._collSurplusPoolAddress\n );\n emit PriceFeedAddressChanged(_troveManagerInitAddressesParams._priceFeedAddress);\n emit ZUSDTokenAddressChanged(_troveManagerInitAddressesParams._zusdTokenAddress);\n emit SortedTrovesAddressChanged(_troveManagerInitAddressesParams._sortedTrovesAddress);\n emit ZEROTokenAddressChanged(_troveManagerInitAddressesParams._zeroTokenAddress);\n emit ZEROStakingAddressChanged(_troveManagerInitAddressesParams._zeroStakingAddress);\n }\n\n function setTroveManagerRedeemOps(address _troveManagerRedeemOps) external override onlyOwner {\n checkContract(_troveManagerRedeemOps);\n troveManagerRedeemOps = _troveManagerRedeemOps;\n emit TroveManagerRedeemOpsAddressChanged(_troveManagerRedeemOps);\n }\n\n // --- Getters ---\n\n function getTroveOwnersCount() external view override returns (uint256) {\n return TroveOwners.length;\n }\n\n function getTroveFromTroveOwnersArray(\n uint256 _index\n ) external view override returns (address) {\n return TroveOwners[_index];\n }\n\n // --- Trove Liquidation functions ---\n\n /// Single liquidation function. Closes the trove if its ICR is lower than the minimum collateral ratio.\n function liquidate(address _borrower) external override {\n _requireTroveIsActive(_borrower);\n\n address[] memory borrowers = new address[](1);\n borrowers[0] = _borrower;\n batchLiquidateTroves(borrowers);\n }\n\n // --- Inner single liquidation functions ---\n\n /// Liquidate one trove, in Normal Mode.\n function _liquidateNormalMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n address _borrower,\n uint256 _ZUSDInStabPool\n ) internal returns (LiquidationValues memory singleLiquidation) {\n LocalVariables_InnerSingleLiquidateFunction memory vars;\n\n (\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n vars.pendingDebtReward,\n vars.pendingCollReward\n ) = getEntireDebtAndColl(_borrower);\n\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n _removeStake(_borrower);\n\n singleLiquidation.collGasCompensation = _getCollGasCompensation(\n singleLiquidation.entireTroveColl\n );\n singleLiquidation.ZUSDGasCompensation = ZUSD_GAS_COMPENSATION;\n uint256 collToLiquidate = singleLiquidation.entireTroveColl.sub(\n singleLiquidation.collGasCompensation\n );\n\n (\n singleLiquidation.debtToOffset,\n singleLiquidation.collToSendToSP,\n singleLiquidation.debtToRedistribute,\n singleLiquidation.collToRedistribute\n ) = _getOffsetAndRedistributionVals(\n singleLiquidation.entireTroveDebt,\n collToLiquidate,\n _ZUSDInStabPool\n );\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n TroveManagerOperation.liquidateInNormalMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInNormalMode);\n return singleLiquidation;\n }\n\n /// Liquidate one trove, in Recovery Mode.\n function _liquidateRecoveryMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n address _borrower,\n uint256 _ICR,\n uint256 _ZUSDInStabPool,\n uint256 _TCR,\n uint256 _price\n ) internal returns (LiquidationValues memory singleLiquidation) {\n LocalVariables_InnerSingleLiquidateFunction memory vars;\n if (TroveOwners.length <= 1) {\n return singleLiquidation;\n } // don't liquidate if last trove\n (\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n vars.pendingDebtReward,\n vars.pendingCollReward\n ) = getEntireDebtAndColl(_borrower);\n\n singleLiquidation.collGasCompensation = _getCollGasCompensation(\n singleLiquidation.entireTroveColl\n );\n singleLiquidation.ZUSDGasCompensation = ZUSD_GAS_COMPENSATION;\n vars.collToLiquidate = singleLiquidation.entireTroveColl.sub(\n singleLiquidation.collGasCompensation\n );\n\n // If ICR <= 100%, purely redistribute the Trove across all active Troves\n if (_ICR <= _100pct) {\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n _removeStake(_borrower);\n\n singleLiquidation.debtToOffset = 0;\n singleLiquidation.collToSendToSP = 0;\n singleLiquidation.debtToRedistribute = singleLiquidation.entireTroveDebt;\n singleLiquidation.collToRedistribute = vars.collToLiquidate;\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n TroveManagerOperation.liquidateInRecoveryMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode);\n\n // If 100% < ICR < MCR, offset as much as possible, and redistribute the remainder\n } else if ((_ICR > _100pct) && (_ICR < liquityBaseParams.MCR())) {\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n _removeStake(_borrower);\n\n (\n singleLiquidation.debtToOffset,\n singleLiquidation.collToSendToSP,\n singleLiquidation.debtToRedistribute,\n singleLiquidation.collToRedistribute\n ) = _getOffsetAndRedistributionVals(\n singleLiquidation.entireTroveDebt,\n vars.collToLiquidate,\n _ZUSDInStabPool\n );\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n TroveManagerOperation.liquidateInRecoveryMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode);\n /*\n * If 110% <= ICR < current TCR (accounting for the preceding liquidations in the current sequence)\n * and there is ZUSD in the Stability Pool, only offset, with no redistribution,\n * but at a capped rate of 1.1 and only if the whole debt can be liquidated.\n * The remainder due to the capped rate will be claimable as collateral surplus.\n */\n } else if (\n (_ICR >= liquityBaseParams.MCR()) &&\n (_ICR < _TCR) &&\n (singleLiquidation.entireTroveDebt <= _ZUSDInStabPool)\n ) {\n _movePendingTroveRewardsToActivePool(\n _activePool,\n _defaultPool,\n vars.pendingDebtReward,\n vars.pendingCollReward\n );\n assert(_ZUSDInStabPool != 0);\n\n _removeStake(_borrower);\n singleLiquidation = _getCappedOffsetVals(\n singleLiquidation.entireTroveDebt,\n singleLiquidation.entireTroveColl,\n _price\n );\n\n _closeTrove(_borrower, Status.closedByLiquidation);\n if (singleLiquidation.collSurplus > 0) {\n collSurplusPool.accountSurplus(_borrower, singleLiquidation.collSurplus);\n }\n\n emit TroveLiquidated(\n _borrower,\n singleLiquidation.entireTroveDebt,\n singleLiquidation.collToSendToSP,\n TroveManagerOperation.liquidateInRecoveryMode\n );\n emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode);\n } else {\n // if (_ICR >= liquityBaseParams.MCR() && ( _ICR >= _TCR || singleLiquidation.entireTroveDebt > _ZUSDInStabPool))\n LiquidationValues memory zeroVals;\n return zeroVals;\n }\n\n return singleLiquidation;\n }\n\n /** In a full liquidation, returns the values for a trove's coll and debt to be offset, and coll and debt to be\n * redistributed to active troves.\n */\n function _getOffsetAndRedistributionVals(\n uint256 _debt,\n uint256 _coll,\n uint256 _ZUSDInStabPool\n )\n internal\n pure\n returns (\n uint256 debtToOffset,\n uint256 collToSendToSP,\n uint256 debtToRedistribute,\n uint256 collToRedistribute\n )\n {\n if (_ZUSDInStabPool > 0) {\n /*\n * Offset as much debt & collateral as possible against the Stability Pool, and redistribute the remainder\n * between all active troves.\n *\n * If the trove's debt is larger than the deposited ZUSD in the Stability Pool:\n *\n * - Offset an amount of the trove's debt equal to the ZUSD in the Stability Pool\n * - Send a fraction of the trove's collateral to the Stability Pool, equal to the fraction of its offset debt\n *\n */\n debtToOffset = LiquityMath._min(_debt, _ZUSDInStabPool);\n collToSendToSP = _coll.mul(debtToOffset).div(_debt);\n debtToRedistribute = _debt.sub(debtToOffset);\n collToRedistribute = _coll.sub(collToSendToSP);\n } else {\n debtToOffset = 0;\n collToSendToSP = 0;\n debtToRedistribute = _debt;\n collToRedistribute = _coll;\n }\n }\n\n /**\n * Get its offset coll/debt and ETH gas comp, and close the trove.\n */\n function _getCappedOffsetVals(\n uint256 _entireTroveDebt,\n uint256 _entireTroveColl,\n uint256 _price\n ) internal view returns (LiquidationValues memory singleLiquidation) {\n singleLiquidation.entireTroveDebt = _entireTroveDebt;\n singleLiquidation.entireTroveColl = _entireTroveColl;\n uint256 collToOffset = _entireTroveDebt.mul(liquityBaseParams.MCR()).div(_price);\n\n singleLiquidation.collGasCompensation = _getCollGasCompensation(collToOffset);\n singleLiquidation.ZUSDGasCompensation = ZUSD_GAS_COMPENSATION;\n\n singleLiquidation.debtToOffset = _entireTroveDebt;\n singleLiquidation.collToSendToSP = collToOffset.sub(singleLiquidation.collGasCompensation);\n singleLiquidation.collSurplus = _entireTroveColl.sub(collToOffset);\n singleLiquidation.debtToRedistribute = 0;\n singleLiquidation.collToRedistribute = 0;\n }\n\n /**\n * Liquidate a sequence of troves. Closes a maximum number of n under-collateralized Troves,\n * starting from the one with the lowest collateral ratio in the system, and moving upwards\n */\n function liquidateTroves(uint256 _n) external override {\n ContractsCache memory contractsCache = ContractsCache(\n activePool,\n defaultPool,\n IZUSDToken(address(0)),\n IZEROStaking(address(0)),\n sortedTroves,\n ICollSurplusPool(address(0)),\n address(0)\n );\n IStabilityPool stabilityPoolCached = _stabilityPool;\n\n LocalVariables_OuterLiquidationFunction memory vars;\n\n LiquidationTotals memory totals;\n\n vars.price = priceFeed.fetchPrice();\n vars.ZUSDInStabPool = stabilityPoolCached.getTotalZUSDDeposits();\n vars.recoveryModeAtStart = _checkRecoveryMode(vars.price);\n\n // Perform the appropriate liquidation sequence - tally the values, and obtain their totals\n if (vars.recoveryModeAtStart) {\n totals = _getTotalsFromLiquidateTrovesSequence_RecoveryMode(\n contractsCache,\n vars.price,\n vars.ZUSDInStabPool,\n _n\n );\n } else {\n // if !vars.recoveryModeAtStart\n totals = _getTotalsFromLiquidateTrovesSequence_NormalMode(\n contractsCache.activePool,\n contractsCache.defaultPool,\n vars.price,\n vars.ZUSDInStabPool,\n _n\n );\n }\n\n require(totals.totalDebtInSequence > 0, \"TroveManager: nothing to liquidate\");\n\n // Move liquidated ETH and ZUSD to the appropriate pools\n stabilityPoolCached.offset(totals.totalDebtToOffset, totals.totalCollToSendToSP);\n _redistributeDebtAndColl(\n contractsCache.activePool,\n contractsCache.defaultPool,\n totals.totalDebtToRedistribute,\n totals.totalCollToRedistribute\n );\n if (totals.totalCollSurplus > 0) {\n contractsCache.activePool.sendETH(address(collSurplusPool), totals.totalCollSurplus);\n }\n\n // Update system snapshots\n _updateSystemSnapshots_excludeCollRemainder(\n contractsCache.activePool,\n totals.totalCollGasCompensation\n );\n\n vars.liquidatedDebt = totals.totalDebtInSequence;\n vars.liquidatedColl = totals.totalCollInSequence.sub(totals.totalCollGasCompensation).sub(\n totals.totalCollSurplus\n );\n emit Liquidation(\n vars.liquidatedDebt,\n vars.liquidatedColl,\n totals.totalCollGasCompensation,\n totals.totalZUSDGasCompensation\n );\n\n // Send gas compensation to caller\n _sendGasCompensation(\n contractsCache.activePool,\n msg.sender,\n totals.totalZUSDGasCompensation,\n totals.totalCollGasCompensation\n );\n }\n\n /**\n * This function is used when the liquidateTroves sequence starts during Recovery Mode. However, it\n * handle the case where the system *leaves* Recovery Mode, part way through the liquidation sequence\n */\n function _getTotalsFromLiquidateTrovesSequence_RecoveryMode(\n ContractsCache memory _contractsCache,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n uint256 _n\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n vars.backToNormalMode = false;\n vars.entireSystemDebt = getEntireSystemDebt();\n vars.entireSystemColl = getEntireSystemColl();\n\n vars.user = _contractsCache.sortedTroves.getLast();\n address firstUser = _contractsCache.sortedTroves.getFirst();\n for (vars.i = 0; vars.i < _n && vars.user != firstUser; vars.i++) {\n // we need to cache it, because current user is likely going to be deleted\n address nextUser = _contractsCache.sortedTroves.getPrev(vars.user);\n\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (!vars.backToNormalMode) {\n // Break the loop if ICR is greater than liquityBaseParams.MCR() and Stability Pool is empty\n if (vars.ICR >= liquityBaseParams.MCR() && vars.remainingZUSDInStabPool == 0) {\n break;\n }\n\n uint256 TCR = LiquityMath._computeCR(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n\n singleLiquidation = _liquidateRecoveryMode(\n _contractsCache.activePool,\n _contractsCache.defaultPool,\n vars.user,\n vars.ICR,\n vars.remainingZUSDInStabPool,\n TCR,\n _price\n );\n\n // Update aggregate trackers\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n vars.entireSystemDebt = vars.entireSystemDebt.sub(singleLiquidation.debtToOffset);\n vars.entireSystemColl = vars\n .entireSystemColl\n .sub(singleLiquidation.collToSendToSP)\n .sub(singleLiquidation.collSurplus);\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n\n vars.backToNormalMode = !_checkPotentialRecoveryMode(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n } else if (vars.backToNormalMode && vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _contractsCache.activePool,\n _contractsCache.defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n } else break; // break if the loop reaches a Trove with ICR >= MCR\n\n vars.user = nextUser;\n }\n }\n\n function _getTotalsFromLiquidateTrovesSequence_NormalMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n uint256 _n\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n ISortedTroves sortedTrovesCached = sortedTroves;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n\n for (vars.i = 0; vars.i < _n; vars.i++) {\n vars.user = sortedTrovesCached.getLast();\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n } else break; // break if the loop reaches a Trove with ICR >= MCR\n }\n }\n\n /**\n * Attempt to liquidate a custom list of troves provided by the caller.\n */\n function batchLiquidateTroves(address[] memory _troveArray) public override {\n require(_troveArray.length != 0, \"TroveManager: Calldata address array must not be empty\");\n\n IActivePool activePoolCached = activePool;\n IDefaultPool defaultPoolCached = defaultPool;\n IStabilityPool stabilityPoolCached = _stabilityPool;\n\n LocalVariables_OuterLiquidationFunction memory vars;\n LiquidationTotals memory totals;\n\n vars.price = priceFeed.fetchPrice();\n vars.ZUSDInStabPool = stabilityPoolCached.getTotalZUSDDeposits();\n vars.recoveryModeAtStart = _checkRecoveryMode(vars.price);\n\n // Perform the appropriate liquidation sequence - tally values and obtain their totals.\n if (vars.recoveryModeAtStart) {\n totals = _getTotalFromBatchLiquidate_RecoveryMode(\n activePoolCached,\n defaultPoolCached,\n vars.price,\n vars.ZUSDInStabPool,\n _troveArray\n );\n } else {\n // if !vars.recoveryModeAtStart\n totals = _getTotalsFromBatchLiquidate_NormalMode(\n activePoolCached,\n defaultPoolCached,\n vars.price,\n vars.ZUSDInStabPool,\n _troveArray\n );\n }\n\n require(totals.totalDebtInSequence > 0, \"TroveManager: nothing to liquidate\");\n\n // Move liquidated ETH and ZUSD to the appropriate pools\n stabilityPoolCached.offset(totals.totalDebtToOffset, totals.totalCollToSendToSP);\n _redistributeDebtAndColl(\n activePoolCached,\n defaultPoolCached,\n totals.totalDebtToRedistribute,\n totals.totalCollToRedistribute\n );\n if (totals.totalCollSurplus > 0) {\n activePoolCached.sendETH(address(collSurplusPool), totals.totalCollSurplus);\n }\n\n // Update system snapshots\n _updateSystemSnapshots_excludeCollRemainder(\n activePoolCached,\n totals.totalCollGasCompensation\n );\n\n vars.liquidatedDebt = totals.totalDebtInSequence;\n vars.liquidatedColl = totals.totalCollInSequence.sub(totals.totalCollGasCompensation).sub(\n totals.totalCollSurplus\n );\n emit Liquidation(\n vars.liquidatedDebt,\n vars.liquidatedColl,\n totals.totalCollGasCompensation,\n totals.totalZUSDGasCompensation\n );\n\n // Send gas compensation to caller\n _sendGasCompensation(\n activePoolCached,\n msg.sender,\n totals.totalZUSDGasCompensation,\n totals.totalCollGasCompensation\n );\n }\n\n /**\n * This function is used when the batch liquidation sequence starts during Recovery Mode. However, it\n * handle the case where the system *leaves* Recovery Mode, part way through the liquidation sequence\n */\n function _getTotalFromBatchLiquidate_RecoveryMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n address[] memory _troveArray\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n vars.backToNormalMode = false;\n vars.entireSystemDebt = getEntireSystemDebt();\n vars.entireSystemColl = getEntireSystemColl();\n\n for (vars.i = 0; vars.i < _troveArray.length; vars.i++) {\n vars.user = _troveArray[vars.i];\n // Skip non-active troves\n if (Troves[vars.user].status != Status.active) {\n continue;\n }\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (!vars.backToNormalMode) {\n // Skip this trove if ICR is greater than liquityBaseParams.MCR() and Stability Pool is empty\n if (vars.ICR >= liquityBaseParams.MCR() && vars.remainingZUSDInStabPool == 0) {\n continue;\n }\n\n uint256 TCR = LiquityMath._computeCR(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n\n singleLiquidation = _liquidateRecoveryMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.ICR,\n vars.remainingZUSDInStabPool,\n TCR,\n _price\n );\n\n // Update aggregate trackers\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n vars.entireSystemDebt = vars.entireSystemDebt.sub(singleLiquidation.debtToOffset);\n vars.entireSystemColl = vars.entireSystemColl.sub(\n singleLiquidation.collToSendToSP\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n\n vars.backToNormalMode = !_checkPotentialRecoveryMode(\n vars.entireSystemColl,\n vars.entireSystemDebt,\n _price\n );\n } else if (vars.backToNormalMode && vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n } else continue; // In Normal Mode skip troves with ICR >= MCR\n }\n }\n\n function _getTotalsFromBatchLiquidate_NormalMode(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _price,\n uint256 _ZUSDInStabPool,\n address[] memory _troveArray\n ) internal returns (LiquidationTotals memory totals) {\n LocalVariables_LiquidationSequence memory vars;\n LiquidationValues memory singleLiquidation;\n\n vars.remainingZUSDInStabPool = _ZUSDInStabPool;\n\n for (vars.i = 0; vars.i < _troveArray.length; vars.i++) {\n vars.user = _troveArray[vars.i];\n vars.ICR = _getCurrentICR(vars.user, _price);\n\n if (vars.ICR < liquityBaseParams.MCR()) {\n singleLiquidation = _liquidateNormalMode(\n _activePool,\n _defaultPool,\n vars.user,\n vars.remainingZUSDInStabPool\n );\n vars.remainingZUSDInStabPool = vars.remainingZUSDInStabPool.sub(\n singleLiquidation.debtToOffset\n );\n\n // Add liquidation values to their respective running totals\n totals = _addLiquidationValuesToTotals(totals, singleLiquidation);\n }\n }\n }\n\n // --- Liquidation helper functions ---\n\n function _addLiquidationValuesToTotals(\n LiquidationTotals memory oldTotals,\n LiquidationValues memory singleLiquidation\n ) internal pure returns (LiquidationTotals memory newTotals) {\n // Tally all the values with their respective running totals\n newTotals.totalCollGasCompensation = oldTotals.totalCollGasCompensation.add(\n singleLiquidation.collGasCompensation\n );\n newTotals.totalZUSDGasCompensation = oldTotals.totalZUSDGasCompensation.add(\n singleLiquidation.ZUSDGasCompensation\n );\n newTotals.totalDebtInSequence = oldTotals.totalDebtInSequence.add(\n singleLiquidation.entireTroveDebt\n );\n newTotals.totalCollInSequence = oldTotals.totalCollInSequence.add(\n singleLiquidation.entireTroveColl\n );\n newTotals.totalDebtToOffset = oldTotals.totalDebtToOffset.add(\n singleLiquidation.debtToOffset\n );\n newTotals.totalCollToSendToSP = oldTotals.totalCollToSendToSP.add(\n singleLiquidation.collToSendToSP\n );\n newTotals.totalDebtToRedistribute = oldTotals.totalDebtToRedistribute.add(\n singleLiquidation.debtToRedistribute\n );\n newTotals.totalCollToRedistribute = oldTotals.totalCollToRedistribute.add(\n singleLiquidation.collToRedistribute\n );\n newTotals.totalCollSurplus = oldTotals.totalCollSurplus.add(singleLiquidation.collSurplus);\n\n return newTotals;\n }\n\n function _sendGasCompensation(\n IActivePool _activePool,\n address _liquidator,\n uint256 _ZUSD,\n uint256 _ETH\n ) internal {\n if (_ZUSD > 0) {\n _zusdToken.returnFromPool(gasPoolAddress, _liquidator, _ZUSD);\n }\n\n if (_ETH > 0) {\n _activePool.sendETH(_liquidator, _ETH);\n }\n }\n\n // --- Helper functions ---\n\n /// @return the nominal collateral ratio (ICR) of a given Trove, without the price. Takes a trove's pending coll and debt rewards from redistributions into account.\n function getNominalICR(address _borrower) public view override returns (uint256) {\n (uint256 currentETH, uint256 currentZUSDDebt) = _getCurrentTroveAmounts(_borrower);\n\n uint256 NICR = LiquityMath._computeNominalCR(currentETH, currentZUSDDebt);\n return NICR;\n }\n\n function applyPendingRewards(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _applyPendingRewards(activePool, defaultPool, _borrower);\n }\n\n /// Update borrower's snapshots of L_ETH and L_ZUSDDebt to reflect the current values\n function updateTroveRewardSnapshots(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _updateTroveRewardSnapshots(_borrower);\n }\n\n /// Return the Troves entire debt and coll, including pending rewards from redistributions.\n function getEntireDebtAndColl(\n address _borrower\n )\n public\n view\n override\n returns (\n uint256 debt,\n uint256 coll,\n uint256 pendingZUSDDebtReward,\n uint256 pendingETHReward\n )\n {\n debt = Troves[_borrower].debt;\n coll = Troves[_borrower].coll;\n\n pendingZUSDDebtReward = getPendingZUSDDebtReward(_borrower);\n pendingETHReward = getPendingETHReward(_borrower);\n\n debt = debt.add(pendingZUSDDebtReward);\n coll = coll.add(pendingETHReward);\n }\n\n function removeStake(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _removeStake(_borrower);\n }\n\n function updateStakeAndTotalStakes(address _borrower) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n return _updateStakeAndTotalStakes(_borrower);\n }\n\n function _redistributeDebtAndColl(\n IActivePool _activePool,\n IDefaultPool _defaultPool,\n uint256 _debt,\n uint256 _coll\n ) internal {\n if (_debt == 0) {\n return;\n }\n\n /*\n * Add distributed coll and debt rewards-per-unit-staked to the running totals. Division uses a \"feedback\"\n * error correction, to keep the cumulative error low in the running totals L_ETH and L_ZUSDDebt:\n *\n * 1) Form numerators which compensate for the floor division errors that occurred the last time this\n * function was called.\n * 2) Calculate \"per-unit-staked\" ratios.\n * 3) Multiply each ratio back by its denominator, to reveal the current floor division error.\n * 4) Store these errors for use in the next correction when this function is called.\n * 5) Note: static analysis tools complain about this \"division before multiplication\", however, it is intended.\n */\n uint256 ETHNumerator = _coll.mul(DECIMAL_PRECISION).add(lastETHError_Redistribution);\n uint256 ZUSDDebtNumerator = _debt.mul(DECIMAL_PRECISION).add(\n lastZUSDDebtError_Redistribution\n );\n\n // Get the per-unit-staked terms\n uint256 ETHRewardPerUnitStaked = ETHNumerator.div(totalStakes);\n uint256 ZUSDDebtRewardPerUnitStaked = ZUSDDebtNumerator.div(totalStakes);\n\n lastETHError_Redistribution = ETHNumerator.sub(ETHRewardPerUnitStaked.mul(totalStakes));\n lastZUSDDebtError_Redistribution = ZUSDDebtNumerator.sub(\n ZUSDDebtRewardPerUnitStaked.mul(totalStakes)\n );\n\n // Add per-unit-staked terms to the running totals\n L_ETH = L_ETH.add(ETHRewardPerUnitStaked);\n L_ZUSDDebt = L_ZUSDDebt.add(ZUSDDebtRewardPerUnitStaked);\n\n emit LTermsUpdated(L_ETH, L_ZUSDDebt);\n\n // Transfer coll and debt from ActivePool to DefaultPool\n _activePool.decreaseZUSDDebt(_debt);\n _defaultPool.increaseZUSDDebt(_debt);\n _activePool.sendETH(address(_defaultPool), _coll);\n }\n\n function closeTrove(address _borrower) external override {\n _requireCallerIsBorrowerOperations();\n return _closeTrove(_borrower, Status.closedByOwner);\n }\n\n /**\n * Updates snapshots of system total stakes and total collateral, excluding a given collateral remainder from the calculation.\n * Used in a liquidation sequence.\n *\n * The calculation excludes a portion of collateral that is in the ActivePool:\n *\n * the total ETH gas compensation from the liquidation sequence\n *\n * The ETH as compensation must be excluded as it is always sent out at the very end of the liquidation sequence.\n */\n function _updateSystemSnapshots_excludeCollRemainder(\n IActivePool _activePool,\n uint256 _collRemainder\n ) internal {\n totalStakesSnapshot = totalStakes;\n\n uint256 activeColl = _activePool.getETH();\n uint256 liquidatedColl = defaultPool.getETH();\n totalCollateralSnapshot = activeColl.sub(_collRemainder).add(liquidatedColl);\n\n emit SystemSnapshotsUpdated(totalStakesSnapshot, totalCollateralSnapshot);\n }\n\n /// Push the owner's address to the Trove owners list, and record the corresponding array index on the Trove struct\n function addTroveOwnerToArray(address _borrower) external override returns (uint256 index) {\n _requireCallerIsBorrowerOperations();\n return _addTroveOwnerToArray(_borrower);\n }\n\n function _addTroveOwnerToArray(address _borrower) internal returns (uint128 index) {\n /* Max array size is 2**128 - 1, i.e. ~3e30 troves. No risk of overflow, since troves have minimum ZUSD\n debt of liquidation reserve plus MIN_NET_DEBT. 3e30 ZUSD dwarfs the value of all wealth in the world ( which is < 1e15 USD). */\n\n // Push the Troveowner to the array\n TroveOwners.push(_borrower);\n\n // Record the index of the new Troveowner on their Trove struct\n index = uint128(TroveOwners.length.sub(1));\n Troves[_borrower].arrayIndex = index;\n\n return index;\n }\n\n // --- Recovery Mode and TCR functions ---\n\n function getTCR(uint256 _price) external view override returns (uint256) {\n return _getTCR(_price);\n }\n\n function MCR() external view override returns (uint256) {\n return liquityBaseParams.MCR();\n }\n\n function CCR() external view override returns (uint256) {\n return liquityBaseParams.CCR();\n }\n\n function checkRecoveryMode(uint256 _price) external view override returns (bool) {\n return _checkRecoveryMode(_price);\n }\n\n // Check whether or not the system *would be* in Recovery Mode, given an ETH:USD price, and the entire system coll and debt.\n function _checkPotentialRecoveryMode(\n uint256 _entireSystemColl,\n uint256 _entireSystemDebt,\n uint256 _price\n ) internal view returns (bool) {\n uint256 TCR = LiquityMath._computeCR(_entireSystemColl, _entireSystemDebt, _price);\n\n return TCR < liquityBaseParams.CCR();\n }\n\n function getRedemptionRateWithDecay() public view override returns (uint256) {\n return _calcRedemptionRate(_calcDecayedBaseRate());\n }\n\n function getRedemptionFeeWithDecay(\n uint256 _ETHDrawn\n ) external view override returns (uint256) {\n return _calcRedemptionFee(getRedemptionRateWithDecay(), _ETHDrawn);\n }\n\n // --- Borrowing fee functions ---\n\n function getBorrowingRate() public view override returns (uint256) {\n return _calcBorrowingRate(baseRate);\n }\n\n function getBorrowingRateWithDecay() public view override returns (uint256) {\n return _calcBorrowingRate(_calcDecayedBaseRate());\n }\n\n function _calcBorrowingRate(uint256 _baseRate) internal view returns (uint256) {\n return\n LiquityMath._min(\n liquityBaseParams.BORROWING_FEE_FLOOR().add(_baseRate),\n liquityBaseParams.MAX_BORROWING_FEE()\n );\n }\n\n function getBorrowingFee(uint256 _ZUSDDebt) external view override returns (uint256) {\n return _calcBorrowingFee(getBorrowingRate(), _ZUSDDebt);\n }\n\n function getBorrowingFeeWithDecay(uint256 _ZUSDDebt) external view override returns (uint256) {\n return _calcBorrowingFee(getBorrowingRateWithDecay(), _ZUSDDebt);\n }\n\n function _calcBorrowingFee(\n uint256 _borrowingRate,\n uint256 _ZUSDDebt\n ) internal pure returns (uint256) {\n return _borrowingRate.mul(_ZUSDDebt).div(DECIMAL_PRECISION);\n }\n\n /// Updates the baseRate state variable based on time elapsed since the last redemption or ZUSD borrowing operation.\n function decayBaseRateFromBorrowing() external override {\n _requireCallerIsBorrowerOperations();\n\n uint256 decayedBaseRate = _calcDecayedBaseRate();\n assert(decayedBaseRate <= DECIMAL_PRECISION); // The baseRate can decay to 0\n\n baseRate = decayedBaseRate;\n emit BaseRateUpdated(decayedBaseRate);\n\n _updateLastFeeOpTime();\n }\n\n // --- Internal fee functions ---\n\n // --- Trove property getters ---\n\n function getTroveStatus(address _borrower) external view override returns (uint256) {\n return uint256(Troves[_borrower].status);\n }\n\n function getTroveStake(address _borrower) external view override returns (uint256) {\n return Troves[_borrower].stake;\n }\n\n function getTroveDebt(address _borrower) external view override returns (uint256) {\n return Troves[_borrower].debt;\n }\n\n function getTroveColl(address _borrower) external view override returns (uint256) {\n return Troves[_borrower].coll;\n }\n\n // --- Trove property setters, called by BorrowerOperations ---\n\n function setTroveStatus(address _borrower, uint256 _num) external override {\n _requireCallerIsBorrowerOperations();\n Troves[_borrower].status = Status(_num);\n }\n\n function increaseTroveColl(\n address _borrower,\n uint256 _collIncrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newColl = Troves[_borrower].coll.add(_collIncrease);\n Troves[_borrower].coll = newColl;\n return newColl;\n }\n\n function decreaseTroveColl(\n address _borrower,\n uint256 _collDecrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newColl = Troves[_borrower].coll.sub(_collDecrease);\n Troves[_borrower].coll = newColl;\n return newColl;\n }\n\n function increaseTroveDebt(\n address _borrower,\n uint256 _debtIncrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newDebt = Troves[_borrower].debt.add(_debtIncrease);\n Troves[_borrower].debt = newDebt;\n return newDebt;\n }\n\n function decreaseTroveDebt(\n address _borrower,\n uint256 _debtDecrease\n ) external override returns (uint256) {\n _requireCallerIsBorrowerOperations();\n uint256 newDebt = Troves[_borrower].debt.sub(_debtDecrease);\n Troves[_borrower].debt = newDebt;\n return newDebt;\n }\n\n function getCurrentICR(\n address _borrower,\n uint256 _price\n ) external view override returns (uint256) {\n return _getCurrentICR(_borrower, _price);\n }\n\n function getPendingETHReward(address _borrower) public view override returns (uint256) {\n return _getPendingETHReward(_borrower);\n }\n\n function getPendingZUSDDebtReward(address _borrower) public view override returns (uint256) {\n return _getPendingZUSDDebtReward(_borrower);\n }\n\n function hasPendingRewards(address _borrower) public view override returns (bool) {\n return _hasPendingRewards(_borrower);\n }\n\n function getRedemptionRate() public view override returns (uint256) {\n return _getRedemptionRate();\n }\n\n /// @dev this function forwards the call to the troveManagerRedeemOps in a delegate call fashion\n /// so the parameters are not needed\n function redeemCollateral(\n uint256 _ZUSDamount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage\n ) external override {\n (bool success, bytes memory returndata) = troveManagerRedeemOps.delegatecall(msg.data);\n require(success, string(returndata));\n }\n\n /// @dev this function forwards the call to the troveManagerRedeemOps in a delegate call fashion\n /// so the parameters are not needed\n ///DLLR _owner or _spender can use Sovryn Mynt to convert DLLR to ZUSD, then use the Zero redemption mechanism to redeem ZUSD for RBTC, all in a single transaction\n function redeemCollateralViaDLLR(\n uint256 _dllrAmount,\n address _firstRedemptionHint,\n address _upperPartialRedemptionHint,\n address _lowerPartialRedemptionHint,\n uint256 _partialRedemptionHintNICR,\n uint256 _maxIterations,\n uint256 _maxFeePercentage,\n IMassetManager.PermitParams calldata _permitParams\n ) external override {\n (bool success, bytes memory returndata) = troveManagerRedeemOps.delegatecall(msg.data);\n require(success, string(returndata));\n }\n}\n" + }, + "contracts/TroveManagerStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IStabilityPool.sol\";\nimport \"./Interfaces/ICollSurplusPool.sol\";\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Interfaces/ISortedTroves.sol\";\nimport \"./Interfaces/IZEROToken.sol\";\nimport \"./Interfaces/IZEROStaking.sol\";\nimport \"./Interfaces/IFeeDistributor.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/BaseMath.sol\";\nimport \"./Dependencies/console.sol\";\n\ncontract TroveManagerStorage is Ownable, BaseMath {\n string public constant NAME = \"TroveManager\";\n\n // --- Connected contract declarations ---\n\n address public troveManagerRedeemOps;\n\n address public borrowerOperationsAddress;\n\n IStabilityPool public _stabilityPool;\n\n address gasPoolAddress;\n\n ICollSurplusPool collSurplusPool;\n\n IZUSDToken public _zusdToken;\n\n IZEROToken public _zeroToken;\n\n IZEROStaking public _zeroStaking;\n\n IFeeDistributor public feeDistributor;\n\n // A doubly linked list of Troves, sorted by their sorted by their collateral ratios\n ISortedTroves public sortedTroves;\n\n // --- Data structures ---\n\n uint256 public baseRate;\n\n // The timestamp of the latest fee operation (redemption or new ZUSD issuance)\n uint256 public lastFeeOperationTime;\n\n enum Status {\n nonExistent,\n active,\n closedByOwner,\n closedByLiquidation,\n closedByRedemption\n }\n\n // Store the necessary data for a trove\n struct Trove {\n uint256 debt;\n uint256 coll;\n uint256 stake;\n Status status;\n uint128 arrayIndex;\n }\n\n mapping(address => Trove) public Troves;\n\n uint256 public totalStakes;\n\n // Snapshot of the value of totalStakes, taken immediately after the latest liquidation\n uint256 public totalStakesSnapshot;\n\n // Snapshot of the total collateral across the ActivePool and DefaultPool, immediately after the latest liquidation.\n uint256 public totalCollateralSnapshot;\n\n /*\n * L_ETH and L_ZUSDDebt track the sums of accumulated liquidation rewards per unit staked. During its lifetime, each stake earns:\n *\n * An ETH gain of ( stake * [L_ETH - L_ETH(0)] )\n * A ZUSDDebt increase of ( stake * [L_ZUSDDebt - L_ZUSDDebt(0)] )\n *\n * Where L_ETH(0) and L_ZUSDDebt(0) are snapshots of L_ETH and L_ZUSDDebt for the active Trove taken at the instant the stake was made\n */\n uint256 public L_ETH;\n uint256 public L_ZUSDDebt;\n\n // Map addresses with active troves to their RewardSnapshot\n mapping(address => RewardSnapshot) public rewardSnapshots;\n\n // Object containing the ETH and ZUSD snapshots for a given active trove\n struct RewardSnapshot {\n uint256 ETH;\n uint256 ZUSDDebt;\n }\n\n // Array of all active trove addresses - used to to compute an approximate hint off-chain, for the sorted list insertion\n address[] public TroveOwners;\n\n // Error trackers for the trove redistribution calculation\n uint256 public lastETHError_Redistribution;\n uint256 public lastZUSDDebtError_Redistribution;\n}\n" + }, + "contracts/ZERO/CommunityIssuance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"../Interfaces/ICommunityIssuance.sol\";\nimport \"../Dependencies/BaseMath.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"./CommunityIssuanceStorage.sol\";\nimport \"../Interfaces/IStabilityPool.sol\";\n\ncontract CommunityIssuance is\n CommunityIssuanceStorage,\n CheckContract,\n BaseMath\n{\n using SafeMath for uint256;\n\n // --- Events ---\n\n event SOVTokenAddressSet(address _sovTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event StabilityPoolAddressSet(address _stabilityPoolAddress);\n event PriceFeedAddressSet(address _priceFeed);\n event RewardManagerAddressSet(address _rewardManagerAddress);\n event TotalSOVIssuedUpdated(uint256 _latestSOVIssued);\n event APRSet(uint256 _APR);\n\n // --- Modifier ---\n modifier onlyRewardManager() {\n require(msg.sender == rewardManager, \"Permission::rewardManager: access denied\");\n _;\n }\n\n // --- Functions ---\n\n /**\n * @dev initialization function to set configs.\n * can only be initialized by owner.\n * @param _sovTokenAddress sov token address.\n * @param _zusdTokenAddress zero token address.\n * @param _stabilityPoolAddress stability pool address.\n * @param _priceFeed price feed address.\n * @param _APR apr in basis points.\n */\n function initialize(\n address _sovTokenAddress,\n address _zusdTokenAddress,\n address _stabilityPoolAddress,\n address _priceFeed,\n uint256 _APR\n ) external initializer onlyOwner {\n checkContract(_sovTokenAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_priceFeed);\n\n _validateAPR(_APR);\n\n sovToken = IERC20(_sovTokenAddress);\n zusdToken = IERC20(_zusdTokenAddress);\n stabilityPoolAddress = _stabilityPoolAddress;\n priceFeed = IPriceFeedSovryn(_priceFeed);\n APR = _APR;\n lastIssuanceTime = block.timestamp;\n\n emit SOVTokenAddressSet(_sovTokenAddress);\n emit StabilityPoolAddressSet(_stabilityPoolAddress);\n emit PriceFeedAddressSet(_priceFeed);\n emit APRSet(_APR);\n }\n\n /**\n * @dev setter function to set the APR value in basis points.\n * can only be called by reward manager.\n * @param _APR apr value in basis points.\n */\n function setAPR(uint256 _APR) external onlyRewardManager {\n _validateAPR(_APR);\n\n // We need to trigger issueSOV function before set the new APR\n // because otherwise, we will change the APR retrospectively for the time passed since last issuance.\n uint256 _totalZUSDDeposits = IStabilityPool(stabilityPoolAddress).getTotalZUSDDeposits();\n _issueSOV(_totalZUSDDeposits);\n\n APR = _APR;\n\n emit APRSet(_APR);\n }\n\n /**\n * @dev setter function to set the price feed.\n * can only be called by the owner.\n * @param _priceFeedAddress price feed address.\n */\n function setPriceFeed(address _priceFeedAddress) external onlyOwner {\n checkContract(_priceFeedAddress);\n\n priceFeed = IPriceFeedSovryn(_priceFeedAddress);\n\n emit PriceFeedAddressSet(_priceFeedAddress);\n }\n\n /**\n * @dev setter function to set reward manager.\n * can only be called by the owner.\n * @param _rewardManagerAddress reward manager address.\n */\n function setRewardManager(address _rewardManagerAddress) external onlyOwner {\n require(_rewardManagerAddress != address(0), \"Account cannot be zero address\");\n\n rewardManager = _rewardManagerAddress;\n\n emit RewardManagerAddressSet(_rewardManagerAddress);\n }\n\n /**\n * @dev validate the APR value.\n * the value must be >= 0 <= MAX_BPS (10000)\n */\n function _validateAPR(uint256 _APR) private {\n require(_APR <= MAX_BPS, \"APR must be less than 10000\");\n }\n\n\n function issueSOV(uint256 _totalZUSDDeposits) public returns (uint256) {\n _requireCallerIsStabilityPool();\n\n return _issueSOV(_totalZUSDDeposits);\n }\n\n function _issueSOV(uint256 _totalZUSDDeposits) private returns (uint256) {\n uint256 timePassedSinceLastIssuance = (block.timestamp.sub(lastIssuanceTime));\n uint256 issuance = _ZUSDToSOV(_totalZUSDDeposits.mul(APR).div(MAX_BPS).mul(timePassedSinceLastIssuance).div(365 days));\n\n totalSOVIssued = totalSOVIssued + issuance;\n lastIssuanceTime = block.timestamp;\n emit TotalSOVIssuedUpdated(totalSOVIssued);\n\n return issuance;\n }\n\n function sendSOV(address _account, uint256 _SOVamount) public {\n _requireCallerIsStabilityPool();\n\n bool success = sovToken.transfer(_account, _SOVamount);\n require(success, \"Failed to send ZERO\");\n }\n\n function _requireCallerIsStabilityPool() internal view {\n require(msg.sender == stabilityPoolAddress, \"CommunityIssuance: caller is not SP\");\n }\n\n /**\n * @dev get the ZUSD to SOV rate conversion. Mostly will be using Sovryn's PriceFeed.\n * @param _zusdAmount zusd amount to get the rate conversion\n * @return the total SOV will be returned.\n */\n function _ZUSDToSOV(uint256 _zusdAmount) internal view returns (uint256) {\n return priceFeed.queryReturn(address(zusdToken), address(sovToken), _zusdAmount);\n }\n}\n" + }, + "contracts/ZERO/CommunityIssuanceStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/IERC20.sol\";\nimport \"../Interfaces/IPriceFeedSovryn.sol\";\nimport \"../Dependencies/Initializable.sol\";\n\ncontract CommunityIssuanceStorage is Ownable, Initializable {\n // --- Data ---\n\n string constant public NAME = \"CommunityIssuance\";\n\n uint256 constant MAX_BPS = 10000;\n\n IERC20 public sovToken;\n\n IERC20 public zusdToken;\n\n address public stabilityPoolAddress;\n\n uint256 public totalSOVIssued;\n\n uint256 public lastIssuanceTime;\n\n uint256 public APR; //in basis points\n\n address public rewardManager;\n\n IPriceFeedSovryn public priceFeed;\n}\n" + }, + "contracts/ZERO/ZEROStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/BaseMath.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/console.sol\";\nimport \"../Interfaces/IZEROToken.sol\";\nimport \"../Interfaces/IZEROStaking.sol\";\nimport \"../Dependencies/LiquityMath.sol\";\nimport \"../Interfaces/IZUSDToken.sol\";\nimport \"./ZEROStakingStorage.sol\";\n\ncontract ZEROStaking is ZEROStakingStorage, IZEROStaking, CheckContract, BaseMath {\n using SafeMath for uint256;\n\n // --- Events ---\n\n event ZEROTokenAddressSet(address _zeroTokenAddress);\n event ZUSDTokenAddressSet(address _zusdTokenAddress);\n event FeeDistributorAddressSet(address _feeDistributorAddress);\n event ActivePoolAddressSet(address _activePoolAddress);\n\n event StakeChanged(address indexed staker, uint256 newStake);\n event StakingGainsWithdrawn(address indexed staker, uint256 ZUSDGain, uint256 ETHGain);\n event F_ETHUpdated(uint256 _F_ETH);\n event F_ZUSDUpdated(uint256 _F_ZUSD);\n event TotalZEROStakedUpdated(uint256 _totalZEROStaked);\n event EtherSent(address _account, uint256 _amount);\n event StakerSnapshotsUpdated(address _staker, uint256 _F_ETH, uint256 _F_ZUSD);\n\n // --- Functions ---\n\n function setAddresses(\n address _zeroTokenAddress,\n address _zusdTokenAddress,\n address _feeDistributorAddress,\n address _activePoolAddress\n ) external override onlyOwner {\n checkContract(_zeroTokenAddress);\n checkContract(_zusdTokenAddress);\n checkContract(_feeDistributorAddress);\n checkContract(_activePoolAddress);\n\n zeroToken = IZEROToken(_zeroTokenAddress);\n zusdToken = IZUSDToken(_zusdTokenAddress);\n feeDistributorAddress = _feeDistributorAddress;\n activePoolAddress = _activePoolAddress;\n\n emit ZEROTokenAddressSet(_zeroTokenAddress);\n emit ZEROTokenAddressSet(_zusdTokenAddress);\n emit FeeDistributorAddressSet(_feeDistributorAddress);\n emit ActivePoolAddressSet(_activePoolAddress);\n }\n\n // If caller has a pre-existing stake, send any accumulated ETH and ZUSD gains to them.\n function stake(uint256 _ZEROamount) external override {\n _requireNonZeroAmount(_ZEROamount);\n\n uint256 currentStake = stakes[msg.sender];\n\n uint256 ETHGain;\n uint256 ZUSDGain;\n // Grab any accumulated ETH and ZUSD gains from the current stake\n if (currentStake != 0) {\n ETHGain = _getPendingETHGain(msg.sender);\n ZUSDGain = _getPendingZUSDGain(msg.sender);\n }\n\n _updateUserSnapshots(msg.sender);\n\n uint256 newStake = currentStake.add(_ZEROamount);\n\n // Increase user’s stake and total ZERO staked\n stakes[msg.sender] = newStake;\n totalZEROStaked = totalZEROStaked.add(_ZEROamount);\n emit TotalZEROStakedUpdated(totalZEROStaked);\n\n // Transfer ZERO from caller to this contract\n zeroToken.sendToZEROStaking(msg.sender, _ZEROamount);\n\n emit StakeChanged(msg.sender, newStake);\n emit StakingGainsWithdrawn(msg.sender, ZUSDGain, ETHGain);\n\n // Send accumulated ZUSD and ETH gains to the caller\n if (currentStake != 0) {\n require(zusdToken.transfer(msg.sender, ZUSDGain), \"Coudn't execute ZUSD transfer\");\n _sendETHGainToUser(ETHGain);\n }\n }\n\n /// Unstake the ZERO and send the it back to the caller, along with their accumulated ZUSD & ETH gains.\n /// If requested amount > stake, send their entire stake.\n function unstake(uint256 _ZEROamount) external override {\n uint256 currentStake = stakes[msg.sender];\n _requireUserHasStake(currentStake);\n\n // Grab any accumulated ETH and ZUSD gains from the current stake\n uint256 ETHGain = _getPendingETHGain(msg.sender);\n uint256 ZUSDGain = _getPendingZUSDGain(msg.sender);\n\n _updateUserSnapshots(msg.sender);\n\n if (_ZEROamount > 0) {\n uint256 ZEROToWithdraw = LiquityMath._min(_ZEROamount, currentStake);\n\n uint256 newStake = currentStake.sub(ZEROToWithdraw);\n\n // Decrease user's stake and total ZERO staked\n stakes[msg.sender] = newStake;\n totalZEROStaked = totalZEROStaked.sub(ZEROToWithdraw);\n emit TotalZEROStakedUpdated(totalZEROStaked);\n\n // Transfer unstaked ZERO to user\n require(\n zeroToken.transfer(msg.sender, ZEROToWithdraw),\n \"Couldn't execute ZUSD transfer\"\n );\n\n emit StakeChanged(msg.sender, newStake);\n }\n\n emit StakingGainsWithdrawn(msg.sender, ZUSDGain, ETHGain);\n\n // Send accumulated ZUSD and ETH gains to the caller\n require(zusdToken.transfer(msg.sender, ZUSDGain), \"Couldn't execute ZUSD transfer\");\n _sendETHGainToUser(ETHGain);\n }\n\n // --- Reward-per-unit-staked increase functions. Called by Zero core contracts ---\n\n function increaseF_ETH(uint256 _ETHFee) external override {\n _requireCallerIsFeeDistributor();\n uint256 ETHFeePerZEROStaked;\n\n if (totalZEROStaked > 0) {\n ETHFeePerZEROStaked = _ETHFee.mul(DECIMAL_PRECISION).div(totalZEROStaked);\n }\n\n F_ETH = F_ETH.add(ETHFeePerZEROStaked);\n emit F_ETHUpdated(F_ETH);\n }\n\n function increaseF_ZUSD(uint256 _ZUSDFee) external override {\n _requireCallerIsFeeDistributor();\n uint256 ZUSDFeePerZEROStaked;\n\n if (totalZEROStaked > 0) {\n ZUSDFeePerZEROStaked = _ZUSDFee.mul(DECIMAL_PRECISION).div(totalZEROStaked);\n }\n\n F_ZUSD = F_ZUSD.add(ZUSDFeePerZEROStaked);\n emit F_ZUSDUpdated(F_ZUSD);\n }\n\n // --- Pending reward functions ---\n\n function getPendingETHGain(address _user) external view override returns (uint256) {\n return _getPendingETHGain(_user);\n }\n\n function _getPendingETHGain(address _user) internal view returns (uint256) {\n uint256 F_ETH_Snapshot = snapshots[_user].F_ETH_Snapshot;\n uint256 ETHGain = stakes[_user].mul(F_ETH.sub(F_ETH_Snapshot)).div(DECIMAL_PRECISION);\n return ETHGain;\n }\n\n function getPendingZUSDGain(address _user) external view override returns (uint256) {\n return _getPendingZUSDGain(_user);\n }\n\n function _getPendingZUSDGain(address _user) internal view returns (uint256) {\n uint256 F_ZUSD_Snapshot = snapshots[_user].F_ZUSD_Snapshot;\n uint256 ZUSDGain = stakes[_user].mul(F_ZUSD.sub(F_ZUSD_Snapshot)).div(DECIMAL_PRECISION);\n return ZUSDGain;\n }\n\n // --- Internal helper functions ---\n\n function _updateUserSnapshots(address _user) internal {\n snapshots[_user].F_ETH_Snapshot = F_ETH;\n snapshots[_user].F_ZUSD_Snapshot = F_ZUSD;\n emit StakerSnapshotsUpdated(_user, F_ETH, F_ZUSD);\n }\n\n function _sendETHGainToUser(uint256 ETHGain) internal {\n emit EtherSent(msg.sender, ETHGain);\n (bool success, ) = msg.sender.call{value: ETHGain}(\"\");\n require(success, \"ZEROStaking: Failed to send accumulated ETHGain\");\n }\n\n // --- 'require' functions ---\n\n function _requireCallerIsFeeDistributor() internal view {\n require(msg.sender == feeDistributorAddress, \"ZEROStaking: caller is not FeeDistributor\");\n }\n\n function _requireCallerIsActivePool() internal view {\n require(msg.sender == activePoolAddress, \"ZEROStaking: caller is not ActivePool\");\n }\n\n function _requireUserHasStake(uint256 currentStake) internal pure {\n require(currentStake > 0, \"ZEROStaking: User must have a non-zero stake\");\n }\n\n function _requireNonZeroAmount(uint256 _amount) internal pure {\n require(_amount > 0, \"ZEROStaking: Amount must be non-zero\");\n }\n\n receive() external payable {\n _requireCallerIsFeeDistributor();\n }\n}\n" + }, + "contracts/ZERO/ZEROStakingStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/Ownable.sol\";\nimport \"../Interfaces/IZEROToken.sol\";\nimport \"../Interfaces/IZUSDToken.sol\";\n\ncontract ZEROStakingStorage is Ownable {\n // --- Data ---\n string constant public NAME = \"ZEROStaking\";\n\n mapping( address => uint) public stakes;\n uint public totalZEROStaked;\n\n uint public F_ETH; // Running sum of ETH fees per-ZERO-staked\n uint public F_ZUSD; // Running sum of ZERO fees per-ZERO-staked\n\n // User snapshots of F_ETH and F_ZUSD, taken at the point at which their latest deposit was made\n mapping (address => Snapshot) public snapshots; \n\n struct Snapshot {\n uint F_ETH_Snapshot;\n uint F_ZUSD_Snapshot;\n }\n \n IZEROToken public zeroToken;\n IZUSDToken public zusdToken;\n\n address public feeDistributorAddress;\n address public activePoolAddress;\n\n}\n" + }, + "contracts/ZERO/ZEROToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Dependencies/CheckContract.sol\";\nimport \"../Dependencies/SafeMath.sol\";\nimport \"../Interfaces/IZEROToken.sol\";\nimport \"./ZEROTokenStorage.sol\";\n\n/**\n * Based upon OpenZeppelin's ERC20 contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol\n *\n * and their EIP2612 (ERC20Permit / ERC712) functionality:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\n *\n *\n * --- Functionality added specific to the ZEROToken ---\n *\n * 1) Transfer protection: blacklist of addresses that are invalid recipients (i.e. core Zero contracts) in external\n * transfer() and transferFrom() calls. The purpose is to protect users from losing tokens by mistakenly sending ZERO directly to a Zero\n * core contract, when they should rather call the right function.\n *\n * 2) sendToZEROStaking(): callable only by Zero core contracts, which move ZERO tokens from user -> ZEROStaking contract.\n *\n */\n\ncontract ZEROToken is ZEROTokenStorage, CheckContract, IZEROToken {\n using SafeMath for uint256;\n\n // --- Functions ---\n\n function initialize(\n address _zeroStakingAddress,\n address _marketMakerAddress,\n address _presaleAddress\n ) public initializer {\n // checkContract(_marketMakerAddress);\n // checkContract(_presaleAddress);\n\n deploymentStartTime = block.timestamp;\n\n zeroStakingAddress = _zeroStakingAddress;\n marketMakerAddress = _marketMakerAddress;\n presale = IBalanceRedirectPresale(_presaleAddress);\n\n bytes32 hashedName = keccak256(bytes(_NAME));\n bytes32 hashedVersion = keccak256(bytes(_VERSION));\n\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = _chainID();\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(_TYPE_HASH, hashedName, hashedVersion);\n }\n\n // --- External functions ---\n\n /// @notice Generates `amount` tokens that are assigned to `account`\n /// @param account The address that will be assigned the new tokens\n /// @param amount The quantity of tokens generated\n function mint(address account, uint256 amount) external {\n require(\n msg.sender == marketMakerAddress || msg.sender == address(presale),\n \"Invalid caller\"\n );\n _mint(account, amount);\n }\n\n /// @notice Burns `amount` tokens from `account`\n /// @param account The address that will lose the tokens\n /// @param amount The quantity of tokens to burn\n function burn(address account, uint256 amount) external {\n require(msg.sender == marketMakerAddress, \"Invalid caller\");\n _burn(account, amount);\n }\n\n function totalSupply() external view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) external view override returns (uint256) {\n return _balances[account];\n }\n\n function getDeploymentStartTime() external view override returns (uint256) {\n return deploymentStartTime;\n }\n\n function transfer(address recipient, uint256 amount) external override returns (bool) {\n _requireValidRecipient(recipient);\n\n // Otherwise, standard transfer functionality\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) external view override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) external override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external override returns (bool) {\n _requireValidRecipient(recipient);\n\n _transfer(sender, recipient, amount);\n _approve(\n sender,\n msg.sender,\n _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\")\n );\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue)\n external\n override\n returns (bool)\n {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue)\n external\n override\n returns (bool)\n {\n _approve(\n msg.sender,\n spender,\n _allowances[msg.sender][spender].sub(\n subtractedValue,\n \"ERC20: decreased allowance below zero\"\n )\n );\n return true;\n }\n\n function sendToZEROStaking(address _sender, uint256 _amount) external override {\n _requireCallerIsZEROStaking();\n _transfer(_sender, zeroStakingAddress, _amount);\n }\n\n // --- EIP 2612 functionality ---\n\n function domainSeparator() public view override returns (bytes32) {\n if (_chainID() == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external override {\n require(deadline >= now, \"ZERO: expired deadline\");\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n domainSeparator(),\n keccak256(\n abi.encode(_PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner]++, deadline)\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress == owner, \"ZERO: invalid signature\");\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) external view override returns (uint256) {\n // FOR EIP 2612\n return _nonces[owner];\n }\n\n // --- Internal operations ---\n\n function _chainID() private pure returns (uint256 chainID) {\n assembly {\n chainID := chainid()\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 name,\n bytes32 version\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, name, version, _chainID(), address(this)));\n }\n\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal {\n return; // disable the func call - ZEROToken is not used in beta\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n require(presale.isClosed(), \"Presale is not over yet\");\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account, uint256 amount) internal {\n return; // disable the func call - ZEROToken is not used in beta\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n function _burn(address account, uint256 amount) internal {\n return; // disable the func call - ZEROToken is not used in beta\n require(account != address(0), \"ERC20: mint to the zero address\");\n require(amount <= _balances[account], \"balance too low\");\n\n _totalSupply = _totalSupply.sub(amount);\n _balances[account] = _balances[account].sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n // --- Helper functions ---\n\n // --- 'require' functions ---\n\n function _requireValidRecipient(address _recipient) internal view {\n require(\n _recipient != address(0) && _recipient != address(this),\n \"ZERO: Cannot transfer tokens directly to the ZERO token contract or the zero address\"\n );\n }\n\n function _requireCallerIsZEROStaking() internal view {\n require(\n msg.sender == zeroStakingAddress,\n \"ZEROToken: caller must be the ZEROStaking contract\"\n );\n }\n\n // --- Optional functions ---\n\n function name() external view override returns (string memory) {\n return _NAME;\n }\n\n function symbol() external view override returns (string memory) {\n return _SYMBOL;\n }\n\n function decimals() external view override returns (uint8) {\n return _DECIMALS;\n }\n\n function version() external view override returns (string memory) {\n return _VERSION;\n }\n\n function permitTypeHash() external view override returns (bytes32) {\n return _PERMIT_TYPEHASH;\n }\n}\n" + }, + "contracts/ZERO/ZEROTokenStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"../Interfaces/IBalanceRedirectPresale.sol\";\nimport \"../Dependencies/Initializable.sol\";\n\ncontract ZEROTokenStorage is Initializable {\n // --- ERC20 Data ---\n\n string constant internal _NAME = \"ZERO\";\n string constant internal _SYMBOL = \"ZERO\";\n string constant internal _VERSION = \"1\";\n uint8 constant internal _DECIMALS = 18;\n\n mapping (address => uint256) internal _balances;\n mapping (address => mapping (address => uint256)) internal _allowances;\n uint internal _totalSupply;\n\n // --- EIP 2612 Data ---\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 internal constant _PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n // keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n bytes32 internal constant _TYPE_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 internal _CACHED_DOMAIN_SEPARATOR;\n uint256 internal _CACHED_CHAIN_ID;\n\n bytes32 internal _HASHED_NAME;\n bytes32 internal _HASHED_VERSION;\n \n mapping (address => uint256) internal _nonces;\n\n // --- ZEROToken specific data ---\n\n uint public constant ONE_YEAR_IN_SECONDS = 31536000; // 60 * 60 * 24 * 365\n\n // uint for use with SafeMath\n uint internal constant _1_MILLION = 1e24; // 1e6 * 1e18 = 1e24\n\n uint internal deploymentStartTime;\n\n address public zeroStakingAddress;\n address public marketMakerAddress;\n IBalanceRedirectPresale public presale;\n\n}\n" + }, + "contracts/ZUSDToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.11;\n\nimport \"./Interfaces/IZUSDToken.sol\";\nimport \"./Dependencies/SafeMath.sol\";\nimport \"./Dependencies/Ownable.sol\";\nimport \"./Dependencies/CheckContract.sol\";\nimport \"./Dependencies/console.sol\";\nimport \"./ZUSDTokenStorage.sol\";\n\n/**\n *\n * Based upon OpenZeppelin's ERC20 contract:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol\n *\n * and their EIP2612 (ERC20Permit / ERC712) functionality:\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\n *\n *\n * --- Functionality added specific to the ZUSDToken ---\n *\n * 1) Transfer protection: blacklist of addresses that are invalid recipients (i.e. core Zero contracts) in external\n * transfer() and transferFrom() calls. The purpose is to protect users from losing tokens by mistakenly sending ZUSD directly to a Zero\n * core contract, when they should rather call the right function.\n *\n * 2) sendToPool() and returnFromPool(): functions callable only Zero core contracts, which move ZUSD tokens between Zero <-> user.\n */\n\ncontract ZUSDToken is ZUSDTokenStorage, CheckContract, IZUSDToken, Ownable {\n using SafeMath for uint256;\n // --- Events ---\n event TroveManagerAddressChanged(address _troveManagerAddress);\n event StabilityPoolAddressChanged(address _newStabilityPoolAddress);\n event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress);\n\n function initialize(\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) public virtual initializer onlyOwner {\n _initialize(_troveManagerAddress, _stabilityPoolAddress, _borrowerOperationsAddress);\n }\n\n function _initialize(\n address _troveManagerAddress,\n address _stabilityPoolAddress,\n address _borrowerOperationsAddress\n ) internal {\n checkContract(_troveManagerAddress);\n checkContract(_stabilityPoolAddress);\n checkContract(_borrowerOperationsAddress);\n\n troveManagerAddress = _troveManagerAddress;\n emit TroveManagerAddressChanged(_troveManagerAddress);\n\n stabilityPoolAddress = _stabilityPoolAddress;\n emit StabilityPoolAddressChanged(_stabilityPoolAddress);\n\n borrowerOperationsAddress = _borrowerOperationsAddress;\n emit BorrowerOperationsAddressChanged(_borrowerOperationsAddress);\n\n bytes32 hashedName = keccak256(bytes(_NAME));\n bytes32 hashedVersion = keccak256(bytes(_VERSION));\n\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = _chainID();\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(_TYPE_HASH, hashedName, hashedVersion);\n }\n\n // --- Functions for intra-Zero calls ---\n\n function mint(address _account, uint256 _amount) external override {\n _requireCallerIsBorrowerOperations();\n _mint(_account, _amount);\n }\n\n function burn(address _account, uint256 _amount) external override {\n _requireCallerIsBOorTroveMorSP();\n _burn(_account, _amount);\n }\n\n function sendToPool(\n address _sender,\n address _poolAddress,\n uint256 _amount\n ) external override {\n _requireCallerIsStabilityPool();\n _transfer(_sender, _poolAddress, _amount);\n }\n\n function returnFromPool(\n address _poolAddress,\n address _receiver,\n uint256 _amount\n ) external override {\n _requireCallerIsTroveMorSP();\n _transfer(_poolAddress, _receiver, _amount);\n }\n\n // --- External functions ---\n\n function totalSupply() external view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) external view override returns (uint256) {\n return _balances[account];\n }\n\n function transfer(address recipient, uint256 amount) external override returns (bool) {\n _requireValidRecipient(recipient);\n _transfer(msg.sender, recipient, amount);\n return true;\n }\n\n function allowance(address owner, address spender) external view override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function approve(address spender, uint256 amount) external override returns (bool) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external override returns (bool) {\n _requireValidRecipient(recipient);\n _transfer(sender, recipient, amount);\n _approve(\n sender,\n msg.sender,\n _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\")\n );\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue)\n external\n override\n returns (bool)\n {\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue)\n external\n override\n returns (bool)\n {\n _approve(\n msg.sender,\n spender,\n _allowances[msg.sender][spender].sub(\n subtractedValue,\n \"ERC20: decreased allowance below zero\"\n )\n );\n return true;\n }\n\n // --- EIP 2612 Functionality ---\n\n function domainSeparator() public view override returns (bytes32) {\n if (_chainID() == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function permit(\n address owner,\n address spender,\n uint256 amount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external override {\n require(deadline >= now, \"ZUSD: expired deadline\");\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n domainSeparator(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n _nonces[owner]++,\n deadline\n )\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress == owner, \"ZUSD: invalid signature\");\n _approve(owner, spender, amount);\n }\n\n function nonces(address owner) external view override returns (uint256) {\n // FOR EIP 2612\n return _nonces[owner];\n }\n\n // --- Internal operations ---\n\n function _chainID() private pure returns (uint256 chainID) {\n assembly {\n chainID := chainid()\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 name,\n bytes32 version\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, name, version, _chainID(), address(this)));\n }\n\n // --- Internal operations ---\n // Warning: sanity checks (for sender and recipient) should have been done before calling these internal functions\n\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal {\n assert(sender != address(0));\n assert(recipient != address(0));\n\n _balances[sender] = _balances[sender].sub(\n amount,\n \"ERC20: transfer amount exceeds balance\"\n );\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n function _mint(address account, uint256 amount) internal {\n assert(account != address(0));\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n function _burn(address account, uint256 amount) internal {\n assert(account != address(0));\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal {\n assert(owner != address(0));\n assert(spender != address(0));\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n // --- 'require' functions ---\n\n function _requireValidRecipient(address _recipient) internal view {\n require(\n _recipient != address(0) && _recipient != address(this),\n \"ZUSD: Cannot transfer tokens directly to the ZUSD token contract or the zero address\"\n );\n }\n\n function _requireCallerIsBorrowerOperations() internal view {\n require(\n msg.sender == borrowerOperationsAddress,\n \"ZUSDToken: Caller is not BorrowerOperations\"\n );\n }\n\n function _requireCallerIsBOorTroveMorSP() internal view {\n require(\n msg.sender == borrowerOperationsAddress ||\n msg.sender == troveManagerAddress ||\n msg.sender == stabilityPoolAddress,\n \"ZUSD: Caller is neither BorrowerOperations nor TroveManager nor StabilityPool\"\n );\n }\n\n function _requireCallerIsStabilityPool() internal view {\n require(msg.sender == stabilityPoolAddress, \"ZUSD: Caller is not the StabilityPool\");\n }\n\n function _requireCallerIsTroveMorSP() internal view {\n require(\n msg.sender == troveManagerAddress || msg.sender == stabilityPoolAddress,\n \"ZUSD: Caller is neither TroveManager nor StabilityPool\"\n );\n }\n\n // --- Optional functions ---\n\n function name() external view override returns (string memory) {\n return _NAME;\n }\n\n function symbol() external view override returns (string memory) {\n return _SYMBOL;\n }\n\n function decimals() external view override returns (uint8) {\n return _DECIMALS;\n }\n\n function version() external view override returns (string memory) {\n return _VERSION;\n }\n\n function permitTypeHash() external view override returns (bytes32) {\n return _PERMIT_TYPEHASH;\n }\n}\n" + }, + "contracts/ZUSDTokenStorage.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.11;\n\nimport \"./Dependencies/Initializable.sol\";\n\ncontract ZUSDTokenStorage is Initializable {\n uint256 internal _totalSupply;\n string internal constant _NAME = \"ZUSD Stablecoin\";\n string internal constant _SYMBOL = \"ZUSD\";\n string internal constant _VERSION = \"1\";\n uint8 internal constant _DECIMALS = 18;\n\n // --- Data for EIP2612 ---\n\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 internal constant _PERMIT_TYPEHASH =\n 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n // keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n bytes32 internal constant _TYPE_HASH =\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n // Cache the domain separator, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 internal _CACHED_DOMAIN_SEPARATOR;\n uint256 internal _CACHED_CHAIN_ID;\n\n bytes32 internal _HASHED_NAME;\n bytes32 internal _HASHED_VERSION;\n\n mapping(address => uint256) internal _nonces;\n\n // User data for ZUSD token\n mapping(address => uint256) internal _balances;\n mapping(address => mapping(address => uint256)) internal _allowances;\n\n // --- Addresses ---\n address internal troveManagerAddress;\n address internal stabilityPoolAddress;\n address internal borrowerOperationsAddress;\n}\n" + }, + "hardhat/console.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >= 0.4.22 <0.9.0;\n\nlibrary console {\n\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n\tfunction _sendLogPayload(bytes memory payload) private view {\n\t\tuint256 payloadLength = payload.length;\n\t\taddress consoleAddress = CONSOLE_ADDRESS;\n\t\tassembly {\n\t\t\tlet payloadStart := add(payload, 32)\n\t\t\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n\t\t}\n\t}\n\n\tfunction log() internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log()\"));\n\t}\n\n\tfunction logInt(int256 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n\t}\n\n\tfunction logUint(uint256 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n\t}\n\n\tfunction logString(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction logBool(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction logAddress(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction logBytes(bytes memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n\t}\n\n\tfunction logBytes1(bytes1 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n\t}\n\n\tfunction logBytes2(bytes2 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n\t}\n\n\tfunction logBytes3(bytes3 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n\t}\n\n\tfunction logBytes4(bytes4 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n\t}\n\n\tfunction logBytes5(bytes5 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n\t}\n\n\tfunction logBytes6(bytes6 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n\t}\n\n\tfunction logBytes7(bytes7 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n\t}\n\n\tfunction logBytes8(bytes8 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n\t}\n\n\tfunction logBytes9(bytes9 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n\t}\n\n\tfunction logBytes10(bytes10 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n\t}\n\n\tfunction logBytes11(bytes11 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n\t}\n\n\tfunction logBytes12(bytes12 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n\t}\n\n\tfunction logBytes13(bytes13 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n\t}\n\n\tfunction logBytes14(bytes14 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n\t}\n\n\tfunction logBytes15(bytes15 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n\t}\n\n\tfunction logBytes16(bytes16 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n\t}\n\n\tfunction logBytes17(bytes17 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n\t}\n\n\tfunction logBytes18(bytes18 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n\t}\n\n\tfunction logBytes19(bytes19 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n\t}\n\n\tfunction logBytes20(bytes20 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n\t}\n\n\tfunction logBytes21(bytes21 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n\t}\n\n\tfunction logBytes22(bytes22 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n\t}\n\n\tfunction logBytes23(bytes23 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n\t}\n\n\tfunction logBytes24(bytes24 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n\t}\n\n\tfunction logBytes25(bytes25 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n\t}\n\n\tfunction logBytes26(bytes26 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n\t}\n\n\tfunction logBytes27(bytes27 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n\t}\n\n\tfunction logBytes28(bytes28 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n\t}\n\n\tfunction logBytes29(bytes29 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n\t}\n\n\tfunction logBytes30(bytes30 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n\t}\n\n\tfunction logBytes31(bytes31 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n\t}\n\n\tfunction logBytes32(bytes32 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n\t}\n\n\tfunction log(uint256 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n\t}\n\n\tfunction log(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction log(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction log(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n\t}\n\n\tfunction log(address p0, uint256 p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256)\", p0, p1));\n\t}\n\n\tfunction log(address p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n\t}\n\n\tfunction log(address p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n\t}\n\n\tfunction log(address p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint256)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 100 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/rskSovrynTestnet/sortedTroves_Proxy.json b/packages/contracts/deployment/deployments/rskSovrynTestnet/sortedTroves_Proxy.json deleted file mode 100644 index e63cdb00..00000000 --- a/packages/contracts/deployment/deployments/rskSovrynTestnet/sortedTroves_Proxy.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "UpgradableProxy", - "sourceName": "contracts/Proxy/UpgradableProxy.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_oldImplementation", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_newImplementation", - "type": "address" - } - ], - "name": "ImplementationChanged", - "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" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "setImplementation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b610110565b6001600160a01b03811661006d5760405162461bcd60e51b81526004018080602001828103825260228152602001806105e26022913960400191505060405180910390fd5b6001600160a01b0381166100886001600160e01b036100e616565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b6104c38061011f6000396000f3fe6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b00334f776e61626c653a3a7365744f776e65723a20696e76616c69642061646472657373", - "deployedBytecode": "0x6080604052600436106100435760003560e01c806313af40351461005a578063893d20e81461008d578063aaf10f42146100be578063d784d426146100d357610052565b3661005257610050610106565b005b610050610106565b34801561006657600080fd5b506100506004803603602081101561007d57600080fd5b50356001600160a01b031661017c565b34801561009957600080fd5b506100a26101ef565b604080516001600160a01b039092168252519081900360200190f35b3480156100ca57600080fd5b506100a2610219565b3480156100df57600080fd5b50610050600480360360208110156100f657600080fd5b50356001600160a01b0316610244565b6000610110610219565b90506001600160a01b0381166101575760405162461bcd60e51b815260040180806020018281038252602381526020018061046b6023913960400191505060405180910390fd5b60405136600082376000803683855af43d806000843e818015610178578184f35b8184fd5b6101846101ef565b6001600160a01b0316336001600160a01b0316146101e3576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec816102b4565b50565b604080517035b2bc9737bbb730b136329737bbb732b960791b815290519081900360110190205490565b604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205490565b61024c6101ef565b6001600160a01b0316336001600160a01b0316146102ab576040805162461bcd60e51b815260206004820152601760248201527613dddb98589b194e8e881858d8d95cdcc819195b9a5959604a1b604482015290519081900360640190fd5b6101ec81610369565b6001600160a01b0381166102f95760405162461bcd60e51b81526004018080602001828103825260228152602001806104206022913960400191505060405180910390fd5b806001600160a01b031661030b6101ef565b6001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3604080517035b2bc9737bbb730b136329737bbb732b960791b8152905190819003601101902055565b6001600160a01b0381166103ae5760405162461bcd60e51b81526004018080602001828103825260298152602001806104426029913960400191505060405180910390fd5b806001600160a01b03166103c0610219565b6001600160a01b03167fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d360405160405180910390a3604080517135b2bc9734b6b83632b6b2b73a30ba34b7b760711b815290519081900360120190205556fe4f776e61626c653a3a7365744f776e65723a20696e76616c6964206164647265737350726f78793a3a736574496d706c656d656e746174696f6e3a20696e76616c6964206164647265737350726f78793a3a28293a20696d706c656d656e746174696f6e206e6f7420666f756e64a2646970667358221220f84db5b0f5dd60cbb7d66141de13219d0da4edbe3006d54bb4d362cbc0da0dfa64736f6c634300060b0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "address": "0x9414974B00A4E5d8437E6402d44821ee4C2A08F1" -} \ No newline at end of file diff --git a/packages/contracts/deployment/deployments/testnetAddressListQA.json b/packages/contracts/deployment/deployments/testnetAddressListQA.json index c3060940..92dd87a4 100644 --- a/packages/contracts/deployment/deployments/testnetAddressListQA.json +++ b/packages/contracts/deployment/deployments/testnetAddressListQA.json @@ -1,16 +1,16 @@ { -"ActivePool": "0xAD16eBA4EF0ff4C1aB5ffd89c485D5CfC51b5E61", -"BorrowerOperations": "0xba8d7B80bcb3A01A5e713c356fD18EeD299B70D0", -"TroveManager": "0xd8aB7EC3bd20A0Ce3084e124bFBC9Aa96a6D7FdD", -"CollSurplusPool": "0x6b74D66210f78dF0Ffb3A0D6A87471A1345C1284", -"CommunityIssuance": "0xbBCaE94A535b72fFdBEB95Ba256aFc1C15762fb1", -"DefaultPool": "0x037216Fa1916E37d82E1456469B635112CF372dd", -"HintHelpers": "0xc7Bf159d6259ce5a4Fbdd0e3d060875F76605Dba", -"PriceFeedTestnet": "0x89627aa178C7d587f07Df7B863032a47f53540BD", -"SortedTroves": "0x9414974B00A4E5d8437E6402d44821ee4C2A08F1", -"StabilityPool": "0x176D218CaB70002CEF08e15271476187c37ed25f", -"LiquityBaseParams": "0x8B1cB2Ffc9aFe4344503824898098d2E4c883873", -"FeeDistributor": "0x6e825a3569D46510c0f707eb625e456679dff721", -"ZUSDToken": "0xe67cbA98C183A1693fC647d63AeeEC4053656dBB", -"MultiTroveGetter": "0x3adF6FAe3C494F0CF151abA537E60fCCbAC0e0a0" + "ActivePool": "0xAD16eBA4EF0ff4C1aB5ffd89c485D5CfC51b5E61", + "BorrowerOperations": "0xba8d7B80bcb3A01A5e713c356fD18EeD299B70D0", + "TroveManager": "0xd8aB7EC3bd20A0Ce3084e124bFBC9Aa96a6D7FdD", + "CollSurplusPool": "0x6b74D66210f78dF0Ffb3A0D6A87471A1345C1284", + "CommunityIssuance": "0xD017396d2284699e0Ce34b236CcE5321Ee3078e5", + "DefaultPool": "0x037216Fa1916E37d82E1456469B635112CF372dd", + "HintHelpers": "0xc7Bf159d6259ce5a4Fbdd0e3d060875F76605Dba", + "PriceFeedTestnet": "0x89627aa178C7d587f07Df7B863032a47f53540BD", + "SortedTroves": "0x9414974B00A4E5d8437E6402d44821ee4C2A08F1", + "StabilityPool": "0x176D218CaB70002CEF08e15271476187c37ed25f", + "LiquityBaseParams": "0x8B1cB2Ffc9aFe4344503824898098d2E4c883873", + "FeeDistributor": "0x6e825a3569D46510c0f707eb625e456679dff721", + "ZUSDToken": "0xe67cbA98C183A1693fC647d63AeeEC4053656dBB", + "MultiTroveGetter": "0x3adF6FAe3C494F0CF151abA537E60fCCbAC0e0a0" } \ No newline at end of file