Skip to content

Commit

Permalink
feat: init lending sdk - aavev3
Browse files Browse the repository at this point in the history
  • Loading branch information
Bob Lu committed Nov 10, 2023
1 parent eb009af commit 26ad73b
Show file tree
Hide file tree
Showing 57 changed files with 14,872 additions and 1 deletion.
17 changes: 17 additions & 0 deletions packages/lending/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# @protocolink/lending

The lending sdk for Protocolink.

## Install

Install the package via `npm`:

```sh
npm install @protocolink/lending
```

or `yarn`:

```sh
yarn add @protocolink/lending
```
13 changes: 13 additions & 0 deletions packages/lending/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { HardhatUserConfig } from 'hardhat/config';
import rootConfig from '../../hardhat.config';
import { setup } from 'test/hooks';

const config: HardhatUserConfig = {
...rootConfig,
mocha: {
...rootConfig.mocha,
rootHooks: { beforeAll: [setup] },
},
};

export default config;
40 changes: 40 additions & 0 deletions packages/lending/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "@protocolink/lending",
"version": "0.0.1",
"description": "Protocolink Lending SDK",
"repository": {
"type": "git",
"url": "https://github.com/dinngo/protocolink-js-sdk.git",
"directory": "packages/lending"
},
"license": "MIT",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist/**/*"
],
"scripts": {
"build": "rm -rf dist && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
"format": "yarn sort-package-json",
"lint": "eslint --fix src",
"prepublishOnly": "yarn build",
"test": "mocha",
"test:e2e": "hardhat test",
"test:unit": "mocha --recursive src examples"
},
"dependencies": {
"@aave/math-utils": "^1.21.0",
"@nomicfoundation/hardhat-chai-matchers": "^1.0.6",
"@nomicfoundation/hardhat-network-helpers": "^1.0.8",
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@protocolink/api": "^0.4.4",
"@protocolink/common": "^0.3.3",
"@protocolink/core": "^0.4.2",
"@protocolink/logics": "^0.4.4",
"decimal.js-light": "^2.5.1",
"hardhat": "^2.15.0"
},
"devDependencies": {
"@protocolink/test-helpers": "*"
}
}
42 changes: 42 additions & 0 deletions packages/lending/src/adapter.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as common from '@protocolink/common';
import { mainnetTokens, polygonTokens, arbitrumTokens } from '@protocolink/test-helpers';

interface Config {
chainId: number;
primaryStablecoin: common.Token;
secondaryStablecoin: common.Token;
primaryNonstablecoin: common.Token;
}

export const configs: Config[] = [
{
chainId: common.ChainId.mainnet,
primaryStablecoin: mainnetTokens.USDC,
secondaryStablecoin: mainnetTokens.DAI,
primaryNonstablecoin: mainnetTokens.ETH,
},
{
chainId: common.ChainId.polygon,
primaryStablecoin: polygonTokens.USDC,
secondaryStablecoin: polygonTokens.DAI,
primaryNonstablecoin: polygonTokens.WETH,
},
{
chainId: common.ChainId.arbitrum,
primaryStablecoin: arbitrumTokens['USDC.e'],
secondaryStablecoin: arbitrumTokens.DAI,
primaryNonstablecoin: arbitrumTokens.ETH,
},
];

export const [supportedChainIds, configMap] = configs.reduce(
(accumulator, config) => {
const { chainId } = config;

accumulator[0].push(chainId);
accumulator[1][chainId] = config;

return accumulator;
},
[[], {}] as [number[], Record<number, Config>]
);
237 changes: 237 additions & 0 deletions packages/lending/src/adapter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
import { Adapter } from './adapter';
import {
CollateralSwapParams,
DebtSwapParams,
DeleverageParams,
LeverageLongParams,
LeverageShortParams,
ZapBorrowParams,
ZapSupplyParams,
ZapRepayParams,
ZapWithdrawParams,
} from './adapter.type';
import { LendingFlashLoaner } from './protocols/aave-v3/lending-flashloaner';
import { LendingProtocol } from './protocols/aave-v3/lending-protocol';
import { LendingSwaper } from './protocols/paraswap-v5/lending-swaper';
import { Portfolio } from './protocol.portfolio';
import { expect } from 'chai';
import { mainnetTokens } from '@protocolink/test-helpers';
import { providers } from 'ethers';

const account = '0xa3C1C91403F0026b9dd086882aDbC8Cdbc3b3cfB';
const rpcUrl = 'https://rpc.ankr.com/eth';
const provider = new providers.JsonRpcProvider(rpcUrl);

const collateralSwapTestCases: CollateralSwapParams[] = [
{
srcToken: mainnetTokens.USDC,
srcAmount: '1',
destToken: mainnetTokens.USDT,
},
];

const debtSwapTestCases: DebtSwapParams[] = [
{
srcToken: mainnetTokens.USDC,
srcAmount: '1',
destToken: mainnetTokens.USDT,
},
];

const leverageLongTestCases: LeverageLongParams[] = [
{
srcToken: mainnetTokens.USDC,
srcAmount: '1',
destToken: mainnetTokens.USDT,
},
];

const leverageShortTestCases: LeverageShortParams[] = [
{
srcToken: mainnetTokens.USDC,
srcAmount: '1',
destToken: mainnetTokens.USDT,
},
];

const deleverageTestCases: DeleverageParams[] = [
{
srcToken: mainnetTokens.USDC,
srcAmount: '1',
destToken: mainnetTokens.USDT,
},
];

const zapSupplyTestCases: ZapSupplyParams[] = [
{
srcToken: mainnetTokens.USDC,
srcAmount: '1',
destToken: mainnetTokens.USDT,
},
];

const zapWithdrawTestCases: ZapWithdrawParams[] = [
{
srcToken: mainnetTokens.USDC,
srcAmount: '1',
destToken: mainnetTokens.USDT,
},
];

const zapBorrowTestCases: ZapBorrowParams[] = [
{
srcToken: mainnetTokens.USDC,
srcAmount: '1',
destToken: mainnetTokens.USDT,
},
];

const zapRepayTestCases: ZapRepayParams[] = [
{
srcToken: mainnetTokens.USDC,
srcAmount: '1',
destToken: mainnetTokens.USDT,
},
];

describe('Lending AaveV3 SDK', function () {
Adapter.registerProtocol(LendingProtocol);
Adapter.registerFlashLoaner(LendingFlashLoaner);
Adapter.registerSwaper(LendingSwaper);
const adapter = new Adapter(1, provider);
const protocolId = 'aavev3';

let portfolio: Portfolio;

before(async function () {
const portfolios = await adapter.getPortfolios(account);
console.log('portfolios', portfolios);
portfolio = portfolios.find((portfolio) => portfolio.protocolId === protocolId)!;
});

it('Test Portfolios', async function () {
expect(portfolio.supplies).to.have.lengthOf.above(0);
expect(portfolio.borrows).to.have.lengthOf.above(0);
});

context('Test CollateralSwap', function () {
collateralSwapTestCases.forEach((params, i) => {
it(`case ${i + 1}`, async function () {
const collateralSwapInfo = await adapter.getCollateralSwapQuotationAndLogics(
protocolId,
params,
account,
portfolio
);

expect(collateralSwapInfo).to.include.all.keys('fields', 'logics');
expect(parseFloat(collateralSwapInfo.fields.destAmount)).above(0);
expect(collateralSwapInfo.logics).to.have.lengthOf(6); // TODO: 7 after implement add fund logic
});
});
});

context('Test DebtSwap', function () {
debtSwapTestCases.forEach((params, i) => {
it(`case ${i + 1}`, async function () {
const debtSwapInfo = await adapter.getDebtSwapQuotationAndLogics(protocolId, params, account, portfolio);

expect(debtSwapInfo).to.include.all.keys('fields', 'logics');
expect(parseFloat(debtSwapInfo.fields.destAmount)).above(0);
expect(debtSwapInfo.logics).to.have.lengthOf(5);
});
});
});

context('Test LeverageLong', function () {
leverageLongTestCases.forEach((params, i) => {
it(`case ${i + 1}`, async function () {
const leverageLongInfo = await adapter.getLeverageLongQuotationAndLogics(
protocolId,
params,
account,
portfolio
);

expect(leverageLongInfo).to.include.all.keys('fields', 'logics');
expect(leverageLongInfo.logics).to.have.lengthOf(6);
});
});
});

context('Test LeverageShort', function () {
leverageShortTestCases.forEach((params, i) => {
it(`case ${i + 1}`, async function () {
const leverageShortInfo = await adapter.getLeverageShortQuotationAndLogics(
protocolId,
params,
account,
portfolio
);

expect(leverageShortInfo).to.include.all.keys('fields', 'logics');
expect(leverageShortInfo.logics).to.have.lengthOf(6);
});
});
});

context('Test Deleverage', function () {
deleverageTestCases.forEach((params, i) => {
it(`case ${i + 1}`, async function () {
const deleverageInfo = await adapter.getDeleverageQuotationAndLogics(protocolId, params, account, portfolio);

expect(deleverageInfo).to.include.all.keys('fields', 'logics');
expect(parseFloat(deleverageInfo.fields.destAmount)).above(0);
expect(deleverageInfo.logics).to.have.lengthOf(5); // TODO: 6 after implement add fund logic
});
});
});

context('Test ZapSupply', function () {
zapSupplyTestCases.forEach((params, i) => {
it(`case ${i + 1}`, async function () {
const zapSupplyInfo = await adapter.getZapSupplyQuotationAndLogics(protocolId, params, account, portfolio);

expect(zapSupplyInfo).to.include.all.keys('fields', 'logics');
expect(parseFloat(zapSupplyInfo.fields.destAmount)).above(0);
expect(zapSupplyInfo.logics).to.have.lengthOf(2);
});
});
});

context('Test ZapWithdraw', function () {
zapWithdrawTestCases.forEach((params, i) => {
it(`case ${i + 1}`, async function () {
const zapWithdrawInfo = await adapter.getZapWithdrawQuotationAndLogics(protocolId, params, account, portfolio);

expect(zapWithdrawInfo).to.include.all.keys('fields', 'logics');
expect(parseFloat(zapWithdrawInfo.fields.destAmount)).above(0);
expect(zapWithdrawInfo.logics).to.have.lengthOf(2);
});
});
});

context('Test ZapBorrow', function () {
zapBorrowTestCases.forEach((params, i) => {
it(`case ${i + 1}`, async function () {
const ZapBorrowInfo = await adapter.getZapBorrowQuotationAndLogics(protocolId, params, account, portfolio);

expect(ZapBorrowInfo).to.include.all.keys('fields', 'logics');
expect(parseFloat(ZapBorrowInfo.fields.destAmount)).above(0);
expect(ZapBorrowInfo.logics).to.have.lengthOf(2);
});
});
});

context('Test ZapRepay', function () {
zapRepayTestCases.forEach((params, i) => {
it(`case ${i + 1}`, async function () {
const zapRepayInfo = await adapter.getZapRepayQuotationAndLogics(protocolId, params, account, portfolio);

expect(zapRepayInfo).to.include.all.keys('fields', 'logics');
expect(parseFloat(zapRepayInfo.fields.destAmount)).above(0);
expect(zapRepayInfo.logics).to.have.lengthOf(2);
});
});
});
});
Loading

0 comments on commit 26ad73b

Please sign in to comment.