Skip to content

Commit

Permalink
feat: add aave-like supply and borrow enable status to reserve tokens (
Browse files Browse the repository at this point in the history
…#69)

feat: add aave-like supply and borrow enable status to reserve tokens

---------

Co-authored-by: Bob Lu <[email protected]>
  • Loading branch information
LuPoYi and Bob Lu authored Jul 22, 2024
1 parent dca7a5d commit 2e2c829
Show file tree
Hide file tree
Showing 97 changed files with 22,796 additions and 1,436 deletions.
5 changes: 5 additions & 0 deletions .changeset/gorgeous-items-complain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@protocolink/logics': minor
---

add aave-like supply and borrow enable status to reserve tokens
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
},
"dependencies": {
"@paraswap/sdk": "^6.6.0",
"@protocolink/common": "^0.4.1",
"@protocolink/common": "^0.4.2",
"@protocolink/core": "^0.5.0",
"@protocolink/smart-accounts": "^0.1.3",
"@types/lodash": "^4.14.195",
Expand Down
2 changes: 2 additions & 0 deletions src/logics/aave-v2/configs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import * as common from '@protocolink/common';

export const protocolId = 'aave-v2';

type ContractNames = 'ProtocolDataProvider' | 'AaveV2FlashLoanCallback';

export interface Config {
Expand Down
56 changes: 13 additions & 43 deletions src/logics/aave-v2/logic.borrow.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,23 @@
import { InterestRateMode } from './types';
import { LendingPool__factory } from './contracts';
import { Service } from './service';
import * as common from '@protocolink/common';
import * as aavev2 from 'src/modules/aavev2';
import * as core from '@protocolink/core';
import { supportedChainIds } from './configs';
import { protocolId, supportedChainIds } from './configs';
import { providers } from 'ethers';

export type BorrowLogicTokenList = common.Token[];
export type BorrowLogicFields = aavev2.BorrowLogicFields;

export type BorrowLogicFields = core.TokenOutFields<{ interestRateMode: InterestRateMode; referralCode?: number }>;
export type BorrowLogicOptions = aavev2.BorrowLogicOptions;

export type BorrowLogicOptions = Pick<core.GlobalOptions, 'account'>;
export type BorrowLogicTokenList = aavev2.BorrowLogicTokenList;

export class BorrowLogic extends core.Logic implements core.LogicTokenListInterface, core.LogicBuilderInterface {
static id = 'borrow';
static protocolId = 'aave-v2';
export class BorrowLogic
extends aavev2.BorrowLogic
implements core.LogicTokenListInterface, core.LogicBuilderInterface
{
static protocolId = protocolId;
static readonly supportedChainIds = supportedChainIds;

async getTokenList() {
const service = new Service(this.chainId, this.provider);
const tokens = await service.getAssets();

const tokenList: BorrowLogicTokenList = [];
for (const token of tokens) {
if (token.isWrapped) {
tokenList.push(token.unwrapped);
}
tokenList.push(token);
}

return tokenList;
}

async build(fields: BorrowLogicFields, options: BorrowLogicOptions) {
const { output, interestRateMode, referralCode = 0 } = fields;
const { account } = options;

const tokenOut = output.token.wrapped;

const service = new Service(this.chainId, this.provider);
const to = await service.getLendingPoolAddress();
const data = LendingPool__factory.createInterface().encodeFunctionData('borrow', [
tokenOut.address,
output.amountWei,
interestRateMode,
referralCode,
account,
]);
const wrapMode = output.token.isNative ? core.WrapMode.unwrapAfter : core.WrapMode.none;

return core.newLogic({ to, data, wrapMode });
constructor(chainId: number, provider?: providers.Provider) {
super({ chainId, provider, service: new Service(chainId, provider) });
}
}
69 changes: 14 additions & 55 deletions src/logics/aave-v2/logic.deposit.ts
Original file line number Diff line number Diff line change
@@ -1,68 +1,27 @@
import { LendingPool__factory } from './contracts';
import { Service } from './service';
import * as common from '@protocolink/common';
import * as core from '@protocolink/core';
import { supportedChainIds } from './configs';
import * as aavev2 from 'src/modules/aavev2';
import { protocolId, supportedChainIds } from './configs';
import { providers } from 'ethers';

export type DepositLogicTokenList = [common.Token, common.Token][];
export type DepositLogicTokenList = aavev2.DepositLogicTokenList;

export type DepositLogicParams = core.TokenToTokenExactInParams;
export type DepositLogicParams = aavev2.DepositLogicParams;

export type DepositLogicFields = core.TokenToTokenExactInFields<{ referralCode?: number }>;
export type DepositLogicFields = aavev2.DepositLogicFields;

export type DepositLogicOptions = Pick<core.GlobalOptions, 'account'>;
export type DepositLogicOptions = aavev2.DepositLogicOptions;

export class DepositLogic
extends core.Logic
implements core.LogicTokenListInterface, core.LogicOracleInterface, core.LogicBuilderInterface
{
static id = 'deposit';
static protocolId = 'aave-v2';
export class DepositLogic extends aavev2.DepositLogics {
static protocolId = protocolId;
static readonly supportedChainIds = supportedChainIds;

async getTokenList() {
const service = new Service(this.chainId, this.provider);
const reserveTokens = await service.getReserveTokens();

const tokenList: DepositLogicTokenList = [];
for (const reserveToken of reserveTokens) {
if (reserveToken.asset.isWrapped) {
tokenList.push([reserveToken.asset.unwrapped, reserveToken.aToken]);
}
tokenList.push([reserveToken.asset, reserveToken.aToken]);
}

return tokenList;
constructor(chainId: number, provider?: providers.Provider) {
super({ chainId, provider, service: new Service(chainId, provider) });
}

async quote(params: DepositLogicParams) {
const { input, tokenOut } = params;
const output = new common.TokenAmount(tokenOut, input.amount);

return { input, output };
}

async build(fields: DepositLogicFields, options: DepositLogicOptions) {
const { input, balanceBps, referralCode = 0 } = fields;
const { account } = options;

const tokenIn = input.token.wrapped;
const agent = await this.calcAgent(account);

const service = new Service(this.chainId, this.provider);
const to = await service.getLendingPoolAddress();
const data = LendingPool__factory.createInterface().encodeFunctionData('deposit', [
tokenIn.address,
input.amountWei,
agent,
referralCode,
]);
const amountOffset = balanceBps ? common.getParamOffset(1) : undefined;
const inputs = [
core.newLogicInput({ input: new common.TokenAmount(tokenIn, input.amount), balanceBps, amountOffset }),
];
const wrapMode = input.token.isNative ? core.WrapMode.wrapBefore : core.WrapMode.none;
async getTokenList() {
const reserveTokens = await this.service.getSupplyTokens();

return core.newLogic({ to, data, inputs, wrapMode });
return aavev2.createDepositTokenList(reserveTokens, 'aToken');
}
}
70 changes: 10 additions & 60 deletions src/logics/aave-v2/logic.repay.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,23 @@
import { InterestRateMode } from './types';
import { LendingPool__factory } from './contracts';
import { Service } from './service';
import * as common from '@protocolink/common';
import * as aavev2 from 'src/modules/aavev2';
import * as core from '@protocolink/core';
import { supportedChainIds } from './configs';
import { protocolId, supportedChainIds } from './configs';
import { providers } from 'ethers';

export type RepayLogicTokenList = common.Token[];
export type RepayLogicTokenList = aavev2.RepayLogicTokenList;

export type RepayLogicParams = core.RepayParams<{ interestRateMode: InterestRateMode }>;
export type RepayLogicParams = aavev2.RepayLogicParams;

export type RepayLogicFields = core.RepayFields<{ interestRateMode: InterestRateMode }>;
export type RepayLogicFields = aavev2.RepayLogicFields;

export class RepayLogic
extends core.Logic
extends aavev2.RepayLogic
implements core.LogicTokenListInterface, core.LogicOracleInterface, core.LogicBuilderInterface
{
static id = 'repay';
static protocolId = 'aave-v2';
static protocolId = protocolId;
static readonly supportedChainIds = supportedChainIds;

async getTokenList() {
const service = new Service(this.chainId, this.provider);
const tokens = await service.getAssets();

const tokenList: RepayLogicTokenList = [];
for (const token of tokens) {
if (token.isWrapped) {
tokenList.push(token.unwrapped);
}
tokenList.push(token);
}

return tokenList;
}

async quote(params: RepayLogicParams) {
const { borrower, tokenIn, interestRateMode } = params;

const service = new Service(this.chainId, this.provider);
const { currentStableDebt, currentVariableDebt } = await service.protocolDataProvider.getUserReserveData(
tokenIn.wrapped.address,
borrower
);
const currentDebt = interestRateMode === InterestRateMode.variable ? currentVariableDebt : currentStableDebt;
const amountWei = common.calcSlippage(currentDebt, -1); // slightly higher than the current borrowed amount
const input = new common.TokenAmount(tokenIn).setWei(amountWei);

return { borrower, interestRateMode, input };
}

async build(fields: RepayLogicFields) {
const { input, interestRateMode, borrower, balanceBps } = fields;

const tokenIn = input.token.wrapped;

const service = new Service(this.chainId, this.provider);
const to = await service.getLendingPoolAddress();
const data = LendingPool__factory.createInterface().encodeFunctionData('repay', [
tokenIn.address,
input.amountWei,
interestRateMode,
borrower,
]);
const amountOffset = balanceBps ? common.getParamOffset(1) : undefined;
const inputs = [
core.newLogicInput({ input: new common.TokenAmount(tokenIn, input.amount), balanceBps, amountOffset }),
];
const wrapMode = input.token.isNative ? core.WrapMode.wrapBefore : core.WrapMode.none;

return core.newLogic({ to, data, inputs, wrapMode });
constructor(chainId: number, provider?: providers.Provider) {
super({ chainId, provider, service: new Service(chainId, provider) });
}
}
62 changes: 14 additions & 48 deletions src/logics/aave-v2/logic.withdraw.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,31 @@
import { LendingPool__factory } from './contracts';
import { Service } from './service';
import * as common from '@protocolink/common';
import * as aavev2 from 'src/modules/aavev2';
import * as core from '@protocolink/core';
import { supportedChainIds } from './configs';
import { protocolId, supportedChainIds } from './configs';
import { providers } from 'ethers';

export type WithdrawLogicTokenList = [common.Token, common.Token][];
export type WithdrawLogicTokenList = aavev2.WithdrawLogicTokenList;

export type WithdrawLogicParams = core.TokenToTokenExactInParams;
export type WithdrawLogicParams = aavev2.WithdrawLogicParams;

export type WithdrawLogicFields = core.TokenToTokenExactInFields;
export type WithdrawLogicFields = aavev2.WithdrawLogicFields;

export type WithdrawLogicOptions = Pick<core.GlobalOptions, 'account'>;
export type WithdrawLogicOptions = aavev2.WithdrawLogicOptions;

export class WithdrawLogic
extends core.Logic
extends aavev2.WithdrawLogic
implements core.LogicTokenListInterface, core.LogicOracleInterface, core.LogicBuilderInterface
{
static id = 'withdraw';
static protocolId = 'aave-v2';
static protocolId = protocolId;
static readonly supportedChainIds = supportedChainIds;

async getTokenList() {
const service = new Service(this.chainId, this.provider);
const reserveTokens = await service.getReserveTokens();

const tokenList: WithdrawLogicTokenList = [];
for (const reserveToken of reserveTokens) {
if (reserveToken.asset.isWrapped) {
tokenList.push([reserveToken.aToken, reserveToken.asset.unwrapped]);
}
tokenList.push([reserveToken.aToken, reserveToken.asset]);
}

return tokenList;
constructor(chainId: number, provider?: providers.Provider) {
super({ chainId, provider, service: new Service(chainId, provider) });
}

async quote(params: WithdrawLogicParams) {
const { input, tokenOut } = params;
const output = new common.TokenAmount(tokenOut, input.amount);

return { input, output };
}

async build(fields: WithdrawLogicFields, options: WithdrawLogicOptions) {
const { input, output, balanceBps } = fields;
const { account } = options;

const tokenOut = output.token.wrapped;
const agent = await this.calcAgent(account);

const service = new Service(this.chainId, this.provider);
const to = await service.getLendingPoolAddress();
const data = LendingPool__factory.createInterface().encodeFunctionData('withdraw', [
tokenOut.address,
input.amountWei,
agent,
]);
const amountOffset = balanceBps ? common.getParamOffset(1) : undefined;
const inputs = [core.newLogicInput({ input, balanceBps, amountOffset })];
const wrapMode = output.token.isNative ? core.WrapMode.unwrapAfter : core.WrapMode.none;
async getTokenList() {
const reserveTokens = await this.service.getSupplyTokens();

return core.newLogic({ to, data, inputs, wrapMode });
return aavev2.createWithdrawTokenList(reserveTokens, 'aToken');
}
}
26 changes: 0 additions & 26 deletions src/logics/aave-v2/scripts/refresh-tokens-data.ts

This file was deleted.

Loading

0 comments on commit 2e2c829

Please sign in to comment.