Security News
The Risks of Misguided Research in Supply Chain Security
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.
JavaScript library to connect with the APIs of the Aave ecosystem.
Initially, the library allows you to interact with the API of the decentralized lending marketplace ETHLend.
npm install aave-js
On the ETHLend marketplace, the user is able to be borrower or lender of crypto loans.
As a borrower, he can create a request defining the conditions of the loan, and registering it in an Ethereum smart contract.
The different loan requests stored on the Ethereum smart contracts are available for the other users to fund, acting as lenders.
Practical example:
Through the Marketplace object, it is possible to execute all the previous steps without interacting with the ETHLend client.
All the features of the API will be available after initializing the Marketplace object, using a valid API secret Key.
You can get an API secret key using directly the library as following:
import { Marketplace } from "aave-js";
const signupParams = [
"an-email@email.com", //email
"my-name", //name
"a-super-random-password", //password
"my-team-name" // Optional, organisation name
]
const marketplace = new Marketplace("");
const API_SECRET_KEY = await marketplace.utils.signup(...signupParams)
You can also send an HTTP POST request to https://ethdenver-api.aave.com/auth/signup with the body:
{
"email": "an-email@email.com",
"name": "my-name",
"password": "a-super-random-password",
"organisation": "my-team-name"
}
In this early access version, the library allows to interact only with the requests in testnet version of the platform (Kovan smart contracts). Collateral call and default functionality is not available.
The library functions that only fetch information will return formatted plain data, for example the information of a loan request.
For the functions that modify the marketplace state (like creating a new request or funding one), the functions will return a transaction object prepare to submit using an external instance of the web3 library, with whatever necessary provider.
Once you have the API secret key, you can initialize the Marketplace object with:
import { Marketplace } from "aave-js";
const MY_API_SECRET_KEY = "A_VALID_API_SECRET_KEY";
const marketplace = new Marketplace(MY_API_SECRET_KEY);
During it's lifecycle, the loan request goes through the following states, that will be returned in the field state of the request data (marketplace.requests.getLoanData(requestAddress)).
First we create a loan request with the parameters we want.
const borrowerAddress = "0x94D5E24B4c3cb244b9E48eB33AE6ccAD6b715456"; // The wallet that creates the request
const collateralAmount = 10000;
const collateralType = "LEND";
const loanCurrency = "ETH";
// We get the maximum loan amount, depending on the Loan-To-Value ratio allowed
const maxLoanAmount = await marketplace.requests.getMaxLoanAmountFromCollateral(
collateralAmount, collateralType, loanCurrency
);
const loanRequestParams = {
loanAmount: maxLoanAmount,
moe: loanCurrency,
collateralAmount: collateralAmount,
collateralType: collateralType,
mpr: 1.5,
duration: 4
};
const tx = await marketplace.requests.create(borrowerAddress,loanRequestParams);
await web3.eth.sendTransaction(tx);
After the creation of the loan request, as borrower we need to place the collateral in the Ethereum smart contract.
This action can be executed only if the loan request is in state WaitingForCollateral and if the price of the collateral price is correct.
If the collateral is an ERC20 token, we need to approve the marketplace smart contract first, as with place collateral, the smart contract tries to transfer the required collateral amount from the borrower wallet, to the loan request smart contract.
// loanData comes from calling await marketplace.requests.getLoanData(requestAddress);
const { loanAddress, collateralType, collateralAmount, state } = loanData;
const borrowerAddress = '0x27499a2aaaa3a7a4a98a3274dad897' // The wallet that places collateral
const isCollateralPriceUpdated = await marketplace.requests.isCollateralPriceUpdated(loanAddress);
if (state === "WaitingForCollateral" && isCollateralPriceUpdated) {
const isApproved = await marketplace.utils.isTransferApproved(
borrowerAddress, collateralType, collateralAmount
);
if (!isApproved) {
const approveTx = await marketplace.utils.approveTransfer(borrowerAddress, collateralType);
await web3.eth.sendTransaction(approveTx);
}
const tx = await marketplace.requests.placeCollateral(loanAddress, borrowerAddress);
await web3.eth.sendTransaction(tx);
}
Like placing the collateral, if the loan currency is an ERC20 token, it's necessary to approve the marketplace smart contract first, as it will transfer the required loan amount from the lender wallet, to the loan request smart contract.
const { loanAddress, moe, loanAmount } = loanData;
const lenderAddress = "0x94D5E24B4c3cb244b9E48eB33AE6ccAD6b715456"; // The wallet that funds the request
const isApproved = await marketplace.utils.isTransferApproved(lenderAddress, moe, loanAmount);
if (!isApproved) {
const approveTx = await marketplace.utils.approveTransfer(lenderAddress, moe);
await web3.eth.sendTransaction(approveTx);
}
const tx = marketplace.requests.fund(loanAddress, lenderAddress, loanAmount);
await web3.eth.sendTransaction(tx);
Create a new loan offer with the specific parameters.
const lenderAddress = "0x94D5E24B4c3cb244b9E48eB33AE6ccAD6b715456"; // The wallet that creates the request
const minimumLoanAmount = 1000;
const maximumLoanAmount = 10000;
const collaterals = {id: 0, symbol: "LEND", mpr: 0.25, ltv: 50, valid: true};
const durationRange = {min: 1, max: 12};
const loanOfferParams = {
minimumLoanAmount,
maximumLoanAmount,
moe: "LEND",
collaterals,
durationRange
};
const tx = await marketplace.offers.create(lenderAddress,loanOfferParams);
await web3.eth.sendTransaction(tx);
const borrowerAddress = "0x94D5E24B4c3cb244b9E48eB33AE6ccAD6b715456"; // The wallet that creates the request
// borrower params need to be in the range of params specified for the particular loan offer the borrower wants to take. this is enforced at smart contracts level
const loanAmount = 1000; //needs to be between maximumLoanAmount and minimumLoanAmount specified in the offer
const loanCurrency = "ETH"; //same currency as the offer
const collateralType = "LEND"; //needs to be in the list of the specified collaterals
const collateralAmount = await marketplace.utils.getCollateralFromLoanAmount(loanAmount, collateralType, loanCurrency);
const borrowerParams = {
loanAmount,
moe: loanCurrency,
collateralAmount,
collateralType,
duration: 4 //needs to be in the duration range of the offer
};
const tx = await marketplace.offers.takeLoanOffer(borrowerAddress,borrowerParams);
await web3.eth.sendTransaction(tx);
These methods are available on both the offers
and requests
objects. Here we will use the requests
object as reference.
const allRequestsAddresses = await marketplace.requests.getAllAddresses();
const requestsData = await marketplace.requests.getDataAllLoans();
const loanRequestAddress = "0x94D5E24B4c3cb244b9E48eB33AE6ccAD6b715456";
const loanRequestData = await marketplace.requests.getLoanData(loanRequestAddress);
const borrowerAddress = "0x94D5E24B4c3cb244b9E48eB33AE6ccAD6b715456";
const requestsAddressesByBorrower = await marketplace.requests.getDataAllLoansByBorrower(borrowerAddress);
const lenderAddress = "0x94D5E24B4c3cb244b9E48eB33AE6ccAD6b715456";
const requestsAddressesByLender = await marketplace.requests.getDataAllLoansByLender(lenderAddress);
This data will be necessary to know, for example, the symbols of the available collaterals and mediums (loan currencies) in the platform.
const metadata = await marketplace.requests.getMetadata();
// We can see the cryptocurrencies allowed as collateral
console.log(metadata.collateral);
// ... the cryptocurrencies allowed as loan currency
console.log(metadata.mediums);
// ... and the available duration range for a loan
console.log(metadata.durationRange);
const { loanAddress, borrower, moe, nextInstalmentAmount } = loanData;
const isApproved = await marketplace.utils.isTransferApproved(borrower, moe, nextInstalmentAmount);
if (!isApproved) {
const approveTx = await marketplace.utils.approveTransfer(borrower, moe);
await web3.eth.sendTransaction(approveTx);
}
const tx = marketplace.requests.payback(loanAddress, borrower);
await web3.eth.sendTransaction(tx);
If the collateral of a request is not placed within 30 minutes after the creation, it's gonna be necessary to update the collateral price.
const { loanAddress } = loanData;
await.marketplace.requests.refreshCollateralPrice(loanAddress);
In the event of a borrower not paying back the loan installments, the lender has the possibility of executing what we call a partial default call. This means he can automatically withdraw a portion of the collateral equivalent to the amount of installments that the borrower has not paid back. If the partial default call includes the last installment, the remaining collateral is automatically sent back to the borrower and the loan relationship is concluded.
const { loanAddress } = loanData;
const lenderAddress = ... // fetch from web3
// lender address must be a valid lender for the loan. The requirement is enforced at a smart contract level
const tx = marketplace.requests.partialCallDefault(loanAddress, lenderAddress);
await web3.eth.sendTransaction(tx);
If the partial defaulted loan is a crowdlending loan (it means it can be funded by multiple people) other lenders partecipating in the loan will be able to withdraw their part of the collateral, proportional to the amount the borrower didn't pay and the amount the specific lender funded in the loan. The lender(s) executing this action must be different from the lender that first called the partialCallDefault().
const { loanAddress } = loanData;
const lenderAddress = ... // fetch from web3
// lender address must be a valid lender for the loan, and a different lender than the one that performed the partialCallDefault(). The requirement is enforced at a smart contract level
const tx = marketplace.requests.withdrawPartialDefaultAmount(loanAddress, lenderAddress);
await web3.eth.sendTransaction(tx);
In the event of the collateral value dropping below 110% of the loan amount value, the lender can perform a collateral call. The lender will receive the collateral at a 5% discount on price and he will have the freedom to liquidate. After a collateral call event, the loan relationship is concluded.
const { loanAddress } = loanData;
const lenderAddress = ... // fetch from web3
// lender address must be a valid lender for the loan. The requirement is enforced at a smart contract level
const tx = marketplace.requests.callCollateral(loanAddress, lenderAddress);
await web3.eth.sendTransaction(tx);
This project is licensed under the MIT License - see the LICENSE file for details.
FAQs
js wrapper for Aave ETHLend marketplace
The npm package aave-js receives a total of 7 weekly downloads. As such, aave-js popularity was classified as not popular.
We found that aave-js demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.
Research
Security News
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.