-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Bob Lu
committed
Nov 10, 2023
1 parent
eb009af
commit 26ad73b
Showing
57 changed files
with
14,872 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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": "*" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>] | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.