hey @filip pls help me check this my contract it keeps giving me paser error, saying : ParserError: Expected ‘(’ but got identifier
–> project:/contracts/LoanEngine.sol:118:18:
|
118 | function getIdentifier(uint256 index) public view returns (bytes32){
below is the code :
| `// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import “State.sol”;
import “node_modules/@openzeppelin/contracts/acesss/ownable.sol”;
import “node_modules/@openzeppelin/contracts/interfaces/IERC20.sol”;
contract p2plending {
/*//Just Chainlink things
address private oracle = 0x2f90A6D021db21e1B2A077c5a37B3C7E75D15b7e;
bytes32 private jobId = “29fa9aa13bf1468788b7cc4a500a45b8”;
uint256 private fee = 0.1 * 10 ** 18; // 0.1 LINK
*/
enum Status { initial, lent, paid, destroyed }
Status status;
Status constant defaultStatus = Status.initial;
struct Approbation {
bool approved;
bytes data;
bytes32 checksum;
}
struct loan {
Status status;
address lender;
address borrower;
// address IERC20; //collateral and loan token
bytes32 chainlinkRequestId;
uint256 amount;
uint256 interest;
uint256 punitoryInterest;
uint256 interestTimeStamp;
uint256 paid;
uint256 interestRate;
uint256 interestRatePunitory;
uint256 dueTime;
uint256 DuesIn;
address ERC20Token; //collateral and loan token
uint256 cancelableAt;
uint256 lenderBalance;
uint256 expirationRequest;
mapping(address => bool) approbations;
}
//Two mappings. One to get the loans for a user. And the other to get the the loans based off id
// mapping(uint256 => loan) public loanLookup;
// mapping(address => uint256[]) public loanIDs;
mapping(bytes32 => uint256) public identifierToIndex;
Loan[] private loans;
// mapping(bytes32 => bytes32) public merkleRoots;
function configureNew(
// _erc20, // contract address of the token used for payment
address _borrower,
address _IERC20,
uint256 _amount,
uint256 _interestRate,
uint256 _interestRatePunitory,
uint256 _duesIn,
uint256 _cancealableAt,
uint256 _expirationRequest
// string memory _metadata
)
public
returns(uint256)
{
require(!deprecated);
require(_cancealableAt <= duesIn);
// require(address( oracle));
require(_borrower != address(0));
require(_amount != 0);
require(_interstRatePunitory != 0);
require(_interestRate != 0);
require(_expirationRequest > block.timestamp);
Loan memory loan = loan(
Status.initial,
address(0), //lender
msg.sender, // borrower
_IERC20, //collateral and loan token
0x0,
_amount,
0,
0,
0,
0,
_interestRate,
_interestRatePunitory,
0,
_DuesIn,
_cancelableAt,
0,
_expirationRequest
);
uint256 index = loans.push(loan) -1;
emit configureNew(index, _borrower);
bytes32 identifier = getIdentifier(index);
require(identifierToIndex[identifier] == 0);
identifierToIndex[identifier] = index;
return index;
function getIdentifier(uint256 index) public view returns (bytes32){
Loan memory loan = loans[index];
return buildIdentifier(loan.borrower, loan.IERC20, loan.amount, loan.interestRate, loan.interestRatePunitory, loan.duesIn, loan.cancelableAt, loan.expirationRequest
);
}
function buildIdentifier(address borrower, address IERC20, uint256 amount, uint256 interestRate, uint256 interestRatePunitory, uint256 duesIn, uint256 cancelableAt, uint256 expirationRequest) public view returns(bytes32) {
return keccak256(
abi.encode(
this,
borrower,
IERC20,
amount,
interestRate
interestRatePunitory
duesIn,
cancelableAt,
expirationRequest
)
);
}
function isApproved(uint256 index) public view returns(bool) {
Loan storage loan = loans[index];
return loan.approbations[loan.borrower];
//require(loan.issued == issued: false);
}
function approveLoan(uint256 index) public view returns (bool) {
Loan storage loan = loan[index];
require(loan.status == Status.initial);
loan.approbations[msg.sender] = true;
emit ApprovedBy(index, msg.sender);
return true;
}
function approveLoanIdentifier(bytes32 identifier) public returns (bool) {
uint256 index = identifierToIndex[identifier];
require(index != 0);
return approveLoan(index);
}
function lend(uint256 index) public returns (bool) {
Loan storage loan =loans[index];
require(loan.status == Status.initial);
require(isApproved(index));
require(block.timestamp <= loan.expirationRequest);
loan.lender = msg.sender;
loan.dueTime = safeAdd(block.timestamp, loan.duesIn);
loan.interestTimeStamp = block.timestamp;
loan.issued = issued:true;
emit Transfer(loan.lender, index);
ativeLoans += 1;
lendersBalance[loan.lender] += 1;
if (loan.cancelableAt > 0)
internalAddInterest(loan, safeAdd(block.timestamp, loan.cancelableAt));
// Transfer the money to the borrower
uint256 transferValue = isApproved(uint256 index);
//convertRate(loan.oracle, loan.currency, oracleData, loan.amount);
require(IERC20.transferFrom(msg.sender, loan.borrower, transferValue));
emit Lent(index, loan.lender);
return true;
}
// destroy a loan request if not needed anymore.
function destroy(uint index) public returns (bool) {
Loan storage loan = loans[index];
require(loan.status != Status.destroyed);
require(msg.sender == loan.lender || (msg.sender == loan.borrower && loan.status == issued:false));
emit DestroyedBy(index, msg.sender);
// ERC721, remove loan from circulation
if (loan.status != issued:false) {
lendersBalance[loan.lender] -= 1;
activeLoans -= 1;
emit Transfer(loan.lender, index);
}
loan.status = Status.destroyed;
return true;
}
/**
@notice Returns the pending amount to complete de payment of the loan, keep in mind that this number increases
every second.
@dev This method also computes the interest and updates the loan
@param index Index of the loan
@return Aprox pending payment amount
*/
function getPendingAmount(uint index) public returns (uint256) {
addInterest(index);
return getRawPendingAmount(index);
}
/**
@notice Returns the pending amount up to the last time of the interest update. This is not the real pending amount
@dev This method is exact only if "addInterest(loan)" was before and in the same block.
@param index Index of the loan
@return The past pending amount
*/
function getRawPendingAmount(uint index) public view returns (uint256) {
Loan memory loan = loans[index];
return safeSubtract(safeAdd(safeAdd(loan.amount, loan.interest), loan.punitoryInterest), loan.paid);
}
/**
@notice Calculates the interest of a given amount, interest rate and delta time.
@param timeDelta Elapsed time
@param interestRate Interest rate expressed as the denominator of 10 000 000.
@param amount Amount to apply interest
@return realDelta The real timeDelta applied
@return interest The interest gained in the realDelta time
*/
function calculateInterest(uint256 timeDelta, uint256 interestRate, uint256 amount) internal pure returns (uint256 realDelta, uint256 interest) {
if (amount == 0) {
interest = 0;
realDelta = timeDelta;
} else {
interest = safeMult(safeMult(10000, amount), timeDelta) / interestRate;
realDelta = safeMult(interest, interestRate) / (amount * 10000);
}
}
/**
@notice Computes loan interest
Computes the punitory and non-punitory interest of a given loan and only applies the change.
@param loan Loan to compute interest
@param timestamp Target absolute unix time to calculate interest.
*/
function internalAddInterest(Loan storage loan, uint256 timestamp) internal {
if (timestamp > loan.interestTimestamp) {
uint256 newInterest = loan.interest;
uint256 newPunitoryInterest = loan.punitoryInterest;
uint256 newTimestamp;
uint256 realDelta;
uint256 calculatedInterest;
uint256 deltaTime;
uint256 pending;
uint256 endNonPunitory = min(timestamp, loan.dueTime);
if (endNonPunitory > loan.interestTimestamp) {
deltaTime = endNonPunitory - loan.interestTimestamp;
if (loan.paid < loan.amount) {
pending = loan.amount - loan.paid;
} else {
pending = 0;
}
(realDelta, calculatedInterest) = calculateInterest(deltaTime, loan.interestRate, pending);
newInterest = safeAdd(calculatedInterest, newInterest);
newTimestamp = loan.interestTimestamp + realDelta;
}
if (timestamp > loan.dueTime) {
uint256 startPunitory = max(loan.dueTime, loan.interestTimestamp);
deltaTime = timestamp - startPunitory;
uint256 debt = safeAdd(loan.amount, newInterest);
pending = min(debt, safeSubtract(safeAdd(debt, newPunitoryInterest), loan.paid));
(realDelta, calculatedInterest) = calculateInterest(deltaTime, loan.interestRatePunitory, pending);
newPunitoryInterest = safeAdd(newPunitoryInterest, calculatedInterest);
newTimestamp = startPunitory + realDelta;
}
if (newInterest != loan.interest || newPunitoryInterest != loan.punitoryInterest) {
loan.interestTimestamp = newTimestamp;
loan.interest = newInterest;
loan.punitoryInterest = newPunitoryInterest;
}
}
}
/**
@notice Updates the loan accumulated interests up to the current Unix time.
@param index Index of the loan
@return true If the interest was updated
*/
function addInterest(uint index) public returns (bool) {
Loan storage loan = loans[index];
require(loan.status == Status.lent);
internalAddInterest(loan, block.timestamp);
}
/*=========borrower pay up loan=========*/
function pay(uint index, uint256 _amount, address _from) public returns (bool) {
Loan storage loan = loans[index];
require(loan.status == issued:true);
addInterest(index);
uint256 toPay = min(getPendingAmount(index), _amount);
emit PartialPayment(index, msg.sender, _from, toPay);
loan.paid = safeAdd(loan.paid, toPay);
if (getRawPendingAmount(index) == 0) {
emit TotalPayment(index);
loan.status = Status.paid;
// ERC721, remove loan from circulation
lendersBalance[loan.lender] -= 1;
activeLoans -= 1;
emit Transfer(loan.lender address(0), index);
}
uint256 transferValue = convertRate( loan.ERC20Token, toPay);
require(transferValue > 0 || toPay < _amount);
lockTokens(address(IERC20), transferValue);
require(IERC20.transferFrom(msg.sender, address(this), transferValue));
loan.lenderBalance = safeAdd(transferValue, loan.lenderBalance);
return true;
}
}`
pls fam help me check what could be wrong here and why i m getting error…thanks fam.