-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
zkCRA PR into merge-create-loan #378
base: develop
Are you sure you want to change the base?
Changes from 50 commits
7fc20ca
dfffc22
7c513d1
eee923c
95eb4d5
1ccb5a4
031cbc3
d427b2d
cb26dae
e08f40f
c6eb931
b206dea
07252f2
059c03c
0d6dcd3
3b40eea
3f3ed56
6443352
08f7020
7a0c7c4
8c2e977
3cc58ab
e76a85b
3025c2f
23162c0
aa3fe79
dadfc00
26992f1
8776bb9
cb7ffd1
5728e29
be9bd3d
58efe8b
fca10a3
9d94bfb
c83a425
fce6a8b
1f1ee5f
5044652
cc8dccf
fa6c4c6
5c79e38
40e8a65
892e58a
ec8187b
c5da9b5
e584254
3765885
3ab1604
ee8c659
e72d8ba
e9651ab
43e8f23
f9b9f51
70aac4e
e8426f0
e1e8058
cbe2e82
90382a7
bfdb832
020d131
1a489ce
4e9d18c
d6a73af
0a35fd5
55e7edf
35d182b
3a70f50
c6bdbf7
84f4c23
3831705
82ffaf2
0a53985
c6c50a2
b9d8bc9
0a60b7a
20aefc5
d9aec33
2df3405
af9c5fa
04087de
996c352
302ea5b
619181e
3b0459c
c724a92
28a7010
34eb446
6a7a0ee
da73525
3cd3cc2
7409780
402f868
61faa69
ddbd7ac
1648bbc
6bb792e
ebcbefb
464f372
f24b050
023284a
22080ea
02dcfa7
94be52a
b0e6cf5
7307e4d
ee9d83d
1165739
a37e0fe
7b6e983
3fe5a75
66700fa
9596241
0aae7a7
bd6766f
dbab14a
b730f9f
4cf9167
7d71c35
b7baa43
addc0ff
d1fab5e
babd58a
b870397
268d5c5
aae851a
420bded
a77ccd9
852f1ee
29b2792
94ac369
fb49df4
3587f25
addb731
6959c2b
d03861b
4990170
a199943
735c85c
8b14b53
f301a6d
96bef47
351ae5d
805ae56
0aa513b
c9040de
ebef161
13def46
9e2ee4e
688bb99
50a1f36
c30bc65
784171e
47d4887
c6b2a29
aeabdd3
6114b1e
ce38b12
b395cd6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,14 +7,14 @@ import { | |
ReentryMods | ||
} from "../contexts2/access-control/reentry/ReentryMods.sol"; | ||
import { RolesMods } from "../contexts2/access-control/roles/RolesMods.sol"; | ||
import { AUTHORIZED } from "../shared/roles.sol"; | ||
import { AUTHORIZED, ADMIN } from "../shared/roles.sol"; | ||
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | ||
|
||
// Libraries | ||
import { LibLoans } from "./libraries/LibLoans.sol"; | ||
import { LibEscrow } from "../escrow/libraries/LibEscrow.sol"; | ||
import { LibCollateral } from "./libraries/LibCollateral.sol"; | ||
import { LibConsensus } from "./libraries/LibConsensus.sol"; | ||
import { MarketLib } from "./cra/MarketLib.sol"; | ||
import { LendingLib } from "../lending/libraries/LendingLib.sol"; | ||
import { | ||
PlatformSettingsLib | ||
|
@@ -31,6 +31,9 @@ import { | |
} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; | ||
import { NumbersLib } from "../shared/libraries/NumbersLib.sol"; | ||
import { NFTLib } from "../nft/libraries/NFTLib.sol"; | ||
import { Verifier } from "./cra/verifier.sol"; | ||
import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; | ||
import { MarketLib } from "./cra/MarketLib.sol"; | ||
|
||
// Interfaces | ||
import { ILoansEscrow } from "../escrow/escrow/ILoansEscrow.sol"; | ||
|
@@ -48,10 +51,15 @@ import { | |
LoanStatus, | ||
LoanTerms, | ||
Loan, | ||
MarketStorageLib | ||
MarketStorageLib, | ||
Signature, | ||
SignatureData | ||
} from "../storage/market.sol"; | ||
import { AppStorageLib } from "../storage/app.sol"; | ||
|
||
// hardhat helpers | ||
import "hardhat/console.sol"; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please remove and any logs in the contracts |
||
contract CreateLoanFacet is RolesMods, ReentryMods, PausableMods { | ||
/** | ||
* @notice This event is emitted when a loan has been successfully taken out | ||
|
@@ -72,6 +80,7 @@ contract CreateLoanFacet is RolesMods, ReentryMods, PausableMods { | |
* @param request Struct of the protocol loan request | ||
*/ | ||
modifier __createLoan(LoanRequest calldata request, bool withNFT) { | ||
console.log("creating loan"); | ||
Loan storage loan = CreateLoanLib.createLoan(request, withNFT); | ||
|
||
_; | ||
|
@@ -81,6 +90,28 @@ contract CreateLoanFacet is RolesMods, ReentryMods, PausableMods { | |
loan.duration = request.request.duration; | ||
} | ||
|
||
// used for testing our zkcra function | ||
function initializeMarketAdmins() external authorized(ADMIN, msg.sender) { | ||
// setting market admin | ||
MarketLib.m(bytes32(0)).admin[msg.sender] = true; | ||
// setting providers admin | ||
MarketLib.p(bytes32(0)).admin[msg.sender] = true; | ||
MarketLib.p(bytes32(uint256(1))).admin[msg.sender] = true; | ||
MarketLib.p(bytes32(uint256(2))).admin[msg.sender] = true; | ||
} | ||
|
||
function setProviderInformation( | ||
bytes32 providerId, | ||
uint32 maxAge, | ||
address signer, | ||
bool signerValue | ||
) external { | ||
console.log("solidity: about to set provider signer"); | ||
MarketLib.setProviderSigner(providerId, signer, signerValue); | ||
console.log("solidity: about to set provider max age"); | ||
MarketLib.setProviderMaxAge(providerId, maxAge); | ||
} | ||
|
||
/** | ||
* @notice Creates a loan with the loan request and NFTs without any collateral | ||
* @param request Struct of the protocol loan request | ||
|
@@ -145,6 +176,7 @@ contract CreateLoanFacet is RolesMods, ReentryMods, PausableMods { | |
authorized(AUTHORIZED, msg.sender) | ||
__createLoan(request, false) | ||
{ | ||
console.log("taking out loan"); | ||
// Check if collateral token is zero | ||
require( | ||
collateralToken != address(0x0), | ||
|
@@ -211,7 +243,7 @@ library CreateLoanLib { | |
|
||
// Get consensus values from request | ||
(uint16 interestRate, uint16 collateralRatio, uint256 maxLoanAmount) = | ||
LibConsensus.processLoanTerms(request); | ||
processMarketRequest(request); | ||
|
||
// Perform loan value checks | ||
require( | ||
|
@@ -254,6 +286,133 @@ library CreateLoanLib { | |
); | ||
} | ||
|
||
/** | ||
* @notice it uses our request to verify the returned proof and witness with each other, | ||
* verifies our signature data with our respective data providers, then retrieves our interest rate, | ||
* collateral ratio and max loan amount | ||
* @param request contains all the needed data to do the above | ||
* @return interestRate the rate of the loan | ||
* @return collateralRatio the collateral ratio required for the loan, if any | ||
* @return maxLoanAmount the max loan amount the user is entitled to | ||
*/ | ||
function processMarketRequest(LoanRequest memory request) | ||
internal | ||
returns ( | ||
uint16 interestRate, | ||
uint16 collateralRatio, | ||
uint256 maxLoanAmount | ||
) | ||
{ | ||
console.log("processing market request"); | ||
// Overwrite the first snark witness item with the on-chain identifier | ||
// for the loan (msg.sender ^ nonce). This forces the CRA to have been | ||
// run with the proper identifier. | ||
request.witness[0] = | ||
uint256(uint160(msg.sender)) ^ | ||
LibLoans.s().borrowerLoans[msg.sender].length; | ||
|
||
// Verify the snark proof. | ||
// call from deployed contract | ||
// SnarkVerifier sv = new SnarkVerifier(contract address) | ||
|
||
// deploy verifier library and integrate into create loan facet | ||
console.log("about to verify tx"); | ||
require( | ||
Verifier.verifyTx(request.proof, request.witness), | ||
"Proof not verified" | ||
); | ||
|
||
bytes32[3] memory commitments = [bytes32(0), bytes32(0), bytes32(0)]; | ||
|
||
// constructing our commitments to verify with our signature data | ||
for (uint8 i = 0; i < commitments.length; i++) { | ||
for (uint8 j = 0; j < 8; j++) { | ||
commitments[i] = | ||
(commitments[i] << 32) ^ | ||
bytes32(request.witness[2 + i * 8 + j]); | ||
} | ||
commitments[i] ^= bytes32(request.signatureData[i].signedAt); | ||
} | ||
|
||
require(request.signatureData.length == 3, "Must have 3 providers!"); | ||
|
||
// Verify that the commitment signatures are valid and that the data | ||
// is not too old for the market's liking. | ||
_verifySignatures(commitments, request.signatureData); | ||
|
||
// The second witness item (after identifier) is the market | ||
// score | ||
uint256 marketScore = uint256(request.witness[1]); | ||
|
||
// Let the market handle the loan request and disperse the loan. | ||
|
||
// create default teller market handler | ||
// pass it the marketId and return max loan amount, collateral ratio, interest rate | ||
// upper and lower bound for loan amount, interest rate and collateral ratio depending on | ||
// market id | ||
(interestRate, collateralRatio, maxLoanAmount) = MarketLib.handler( | ||
marketScore, | ||
request | ||
); | ||
return (interestRate, collateralRatio, maxLoanAmount); | ||
} | ||
|
||
function _verifySignatures( | ||
bytes32[3] memory commitments, | ||
SignatureData[] memory signatureData | ||
) private { | ||
for (uint256 i = 0; i < signatureData.length; i++) { | ||
bytes32 providerId = bytes32(i); | ||
require( | ||
signatureData[i].signedAt > | ||
// solhint-disable-next-line | ||
block.timestamp - MarketLib.p(providerId).maxAge, | ||
"Signed at less than max age" | ||
); | ||
require( | ||
MarketLib.s().usedCommitments[commitments[i]] == false, | ||
"Teller: commitment already used" | ||
); | ||
|
||
MarketLib.s().usedCommitments[commitments[i]] = true; | ||
|
||
_validateSignature( | ||
signatureData[i].signature, | ||
commitments[i], | ||
providerId | ||
); | ||
} | ||
} | ||
|
||
/** | ||
* @notice It validates whether a signature is valid or not. | ||
* @param signature signature to validate. | ||
* @param commitment used to recover the signer. | ||
* @param providerId the expected signer address. | ||
*/ | ||
function _validateSignature( | ||
Signature memory signature, | ||
bytes32 commitment, | ||
bytes32 providerId | ||
) private view { | ||
address recoveredSigner = | ||
ECDSA.recover( | ||
keccak256( | ||
abi.encodePacked( | ||
"\x19Ethereum Signed Message:\n32", | ||
uint256(commitment) | ||
) | ||
), | ||
signature.v, | ||
signature.r, | ||
signature.s | ||
); | ||
require( | ||
MarketLib.p(providerId).signer[recoveredSigner], | ||
"Teller: not valid signature" | ||
); | ||
} | ||
|
||
/** | ||
* @notice increments the loanIDCounter | ||
* @return id_ the new ID requested, which stores it in the loan data | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
contract LendingPool { | ||
function deposit(uint256 loanAsset, uint256 depositAmount) external {} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this file needed? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// // SPDX-License-Identifier: MIT | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this file needed? |
||
|
||
// pragma solidity ^0.8.0; | ||
|
||
// // import { TellerAssets } from "./utils.sol"; | ||
// import { LoanRequest } from "./Borrow.sol"; | ||
|
||
// interface IMarket { | ||
// // Called by teller. | ||
// function handler(bytes memory input) external; | ||
// } | ||
|
||
// contract BasicMarket is IMarket { | ||
// struct Storage { | ||
// mapping(uint256 => bool) supportedCollateralAssets; | ||
// mapping(uint256 => bool) supportedLoanAssets; | ||
// } | ||
|
||
// bytes32 internal constant POS = keccak256("teller.finance.market.storage"); | ||
|
||
// function handler(bytes memory input) external override { | ||
// (address borrower, uint256 marketScore, LoanRequest memory request) = | ||
// abi.decode(input, (address, uint256, LoanRequest)); | ||
|
||
// uint256 maxDebtRatio = 6666; | ||
// uint256 minLoanValue = 1000 * 10**18; | ||
// uint256 maxLoanValue = 5000 * 10**18; | ||
// uint256 minCollateralRatio = 2000; | ||
// uint256 maxCollateralRatio = 13500; | ||
// uint256 minDuration = 1 days; | ||
// uint256 maxDuration = 180 days; | ||
|
||
// require(s().supportedLoanAssets[request.loanToken], "ME00"); | ||
// require( | ||
// getDebtRatioFor(request.loanToken, request.loanAmount) <= | ||
// maxDebtRatio, | ||
// "ME06" | ||
// ); | ||
// require( | ||
// request.duration >= minDuration && request.duration <= maxDuration, | ||
// "ME01" | ||
// ); | ||
|
||
// uint256 collateralValue; | ||
|
||
// for (uint8 i = 0; i < request.collateralAssets.length; i++) { | ||
// require( | ||
// s().supportedCollateralAssets[request.collateralAssets[i]], | ||
// "ME03" | ||
// ); | ||
// collateralValue += 100; | ||
// // collateralValue += priceFor( | ||
// // collateralAssets[i], | ||
// // collateralAmounts[i] | ||
// // ); | ||
// } | ||
|
||
// uint256 loanValue = 100; | ||
// // uint256 loanValue = priceFor(loanAsset, loanAmount); | ||
// require(loanValue >= minLoanValue && loanValue <= maxLoanValue, "ME04"); | ||
|
||
// uint256 collateralRatio = (collateralValue * 10000) / loanValue; | ||
// require( | ||
// collateralRatio >= minCollateralRatio && | ||
// collateralRatio <= maxCollateralRatio, | ||
// "ME05" | ||
// ); | ||
|
||
// uint256 interestRate = | ||
// (((maxCollateralRatio - collateralRatio) / 10)) + | ||
// ((30 - marketScore) * 20); | ||
|
||
// // teller.lend( | ||
// // borrower, | ||
// // loanAsset, | ||
// // loanAmount, | ||
// // collateralRatio, | ||
// // interestRate, | ||
// // duration | ||
// // ); | ||
// } | ||
|
||
// function getDebtRatioFor(uint256 loanAsset, uint256 loanAmount) | ||
// internal | ||
// view | ||
// returns (uint256 debtRatio) | ||
// { | ||
// // TellerAssets.AssetType assetType = _assetType(loanAsset); | ||
// return 10000; | ||
// } | ||
|
||
// function s() internal pure returns (Storage storage s_) { | ||
// bytes32 pos = POS; | ||
// assembly { | ||
// s_.slot := pos | ||
// } | ||
// } | ||
// } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicate import
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which import is the duplicate import?