Skip to content

Commit

Permalink
fix: fix for pr comments
Browse files Browse the repository at this point in the history
  • Loading branch information
chouandy committed Aug 3, 2023
1 parent 195b3a8 commit 2bcb71e
Show file tree
Hide file tree
Showing 15 changed files with 176 additions and 25 deletions.
4 changes: 2 additions & 2 deletions src/logics/aave-v2/logic.flash-loan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ export class FlashLoanLogic extends core.Logic implements core.LogicTokenListInt
const fees = new common.TokenAmounts();
for (let i = 0; i < loans.length; i++) {
const loan = loans.at(i);
const { isActive, avaliableToBorrow } = assetInfos[i];
const { isActive, availableToBorrow } = assetInfos[i];
invariant(isActive, `asset is not active: ${loan.token.address}`);
invariant(avaliableToBorrow.gte(loan), `insufficient borrowing capacity for the asset: ${loan.token.address}`);
invariant(availableToBorrow.gte(loan), `insufficient borrowing capacity for the asset: ${loan.token.address}`);

const feeAmountWei = common.calcFee(loan.amountWei, feeBps);
const fee = new common.TokenAmount(loan.token).setWei(feeAmountWei);
Expand Down
2 changes: 1 addition & 1 deletion src/logics/aave-v2/service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ describe('AaveV2 Service', function () {
expect(flashLoanConfiguration).to.have.keys('feeBps', 'assetInfos');
expect(flashLoanConfiguration.assetInfos).to.have.lengthOf.above(0);
for (const assetInfo of flashLoanConfiguration.assetInfos) {
expect(assetInfo).to.have.keys('isActive', 'avaliableToBorrow');
expect(assetInfo).to.have.keys('isActive', 'availableToBorrow');
}
});
});
Expand Down
4 changes: 2 additions & 2 deletions src/logics/aave-v2/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,10 @@ export class Service extends common.Web3Toolkit {
j++;

const [balance] = this.erc20Iface.decodeFunctionResult('balanceOf', returnData[j]);
const avaliableToBorrow = new common.TokenAmount(assets[i]).setWei(balance);
const availableToBorrow = new common.TokenAmount(assets[i]).setWei(balance);
j++;

assetInfos.push({ isActive, avaliableToBorrow });
assetInfos.push({ isActive, availableToBorrow });
}

return { feeBps: feeBps, assetInfos };
Expand Down
2 changes: 1 addition & 1 deletion src/logics/aave-v2/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export enum InterestRateMode {

export interface FlashLoanAssetInfo {
isActive: boolean;
avaliableToBorrow: common.TokenAmount;
availableToBorrow: common.TokenAmount;
}

export interface FlashLoanConfiguration {
Expand Down
4 changes: 2 additions & 2 deletions src/logics/aave-v3/logic.flash-loan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ export class FlashLoanLogic
const fees = new common.TokenAmounts();
for (let i = 0; i < loans.length; i++) {
const loan = loans.at(i);
const { isActive, isPaused, isFlashLoanEnabled, avaliableToBorrow } = assetInfos[i];
const { isActive, isPaused, isFlashLoanEnabled, availableToBorrow } = assetInfos[i];
invariant(isActive, `asset is not active: ${loan.token.address}`);
invariant(!isPaused, `asset is paused: ${loan.token.address}`);
invariant(isFlashLoanEnabled, `asset can not be used in flash loan: ${loan.token.address}`);
invariant(avaliableToBorrow.gte(loan), `insufficient borrowing capacity for the asset: ${loan.token.address}`);
invariant(availableToBorrow.gte(loan), `insufficient borrowing capacity for the asset: ${loan.token.address}`);

const feeAmountWei = common.calcFee(loan.amountWei, feeBps);
const fee = new common.TokenAmount(loan.token).setWei(feeAmountWei);
Expand Down
2 changes: 1 addition & 1 deletion src/logics/aave-v3/service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ describe('AaveV3 Service', function () {
expect(flashLoanConfiguration).to.have.keys('feeBps', 'assetInfos');
expect(flashLoanConfiguration.assetInfos).to.have.lengthOf.above(0);
for (const assetInfo of flashLoanConfiguration.assetInfos) {
expect(assetInfo).to.have.keys('isPaused', 'isActive', 'isFlashLoanEnabled', 'avaliableToBorrow');
expect(assetInfo).to.have.keys('isPaused', 'isActive', 'isFlashLoanEnabled', 'availableToBorrow');
}
});
});
Expand Down
4 changes: 2 additions & 2 deletions src/logics/aave-v3/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,10 +296,10 @@ export class Service extends common.Web3Toolkit {
j++;

const [balance] = this.erc20Iface.decodeFunctionResult('balanceOf', returnData[j]);
const avaliableToBorrow = new common.TokenAmount(assets[i]).setWei(balance);
const availableToBorrow = new common.TokenAmount(assets[i]).setWei(balance);
j++;

assetInfos.push({ isPaused, isActive, isFlashLoanEnabled, avaliableToBorrow });
assetInfos.push({ isPaused, isActive, isFlashLoanEnabled, availableToBorrow });
}

return { feeBps: feeBps, assetInfos };
Expand Down
2 changes: 1 addition & 1 deletion src/logics/aave-v3/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export interface FlashLoanAssetInfo {
isPaused: boolean;
isActive: boolean;
isFlashLoanEnabled: boolean;
avaliableToBorrow: common.TokenAmount;
availableToBorrow: common.TokenAmount;
}

export interface FlashLoanConfiguration {
Expand Down
15 changes: 15 additions & 0 deletions src/logics/balancer-v2/abis/ProtocolFeesCollector.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[
{
"inputs": [],
"name": "getFlashLoanFeePercentage",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
}
]
14 changes: 13 additions & 1 deletion src/logics/balancer-v2/configs.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as common from '@protocolink/common';

type ContractNames = 'Vault' | 'BalancerV2FlashLoanCallback';
type ContractNames = 'Vault' | 'BalancerV2FlashLoanCallback' | 'ProtocolFeesCollector';

export interface Config {
chainId: number;
Expand All @@ -13,27 +13,39 @@ export const configs: Config[] = [
contract: {
Vault: '0xBA12222222228d8Ba445958a75a0704d566BF2C8',
BalancerV2FlashLoanCallback: '0x03EdE4da71B8c404f7a2d61b8Ad367edEFc90Af8',
ProtocolFeesCollector: '0xce88686553686DA562CE7Cea497CE749DA109f9F',
},
},
{
chainId: common.ChainId.polygon,
contract: {
Vault: '0xBA12222222228d8Ba445958a75a0704d566BF2C8',
BalancerV2FlashLoanCallback: '0x03EdE4da71B8c404f7a2d61b8Ad367edEFc90Af8',
ProtocolFeesCollector: '0xce88686553686DA562CE7Cea497CE749DA109f9F',
},
},
{
chainId: common.ChainId.arbitrum,
contract: {
Vault: '0xBA12222222228d8Ba445958a75a0704d566BF2C8',
BalancerV2FlashLoanCallback: '0x03EdE4da71B8c404f7a2d61b8Ad367edEFc90Af8',
ProtocolFeesCollector: '0xce88686553686DA562CE7Cea497CE749DA109f9F',
},
},
{
chainId: common.ChainId.optimism,
contract: {
Vault: '0xBA12222222228d8Ba445958a75a0704d566BF2C8',
BalancerV2FlashLoanCallback: '0x03EdE4da71B8c404f7a2d61b8Ad367edEFc90Af8',
ProtocolFeesCollector: '0xce88686553686DA562CE7Cea497CE749DA109f9F',
},
},
{
chainId: common.ChainId.avalanche,
contract: {
Vault: '0xBA12222222228d8Ba445958a75a0704d566BF2C8',
BalancerV2FlashLoanCallback: '0x03EdE4da71B8c404f7a2d61b8Ad367edEFc90Af8',
ProtocolFeesCollector: '0xce88686553686DA562CE7Cea497CE749DA109f9F',
},
},
];
Expand Down
64 changes: 64 additions & 0 deletions src/logics/balancer-v2/contracts/ProtocolFeesCollector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type { BaseContract, BigNumber, BytesLike, CallOverrides, PopulatedTransaction, Signer, utils } from 'ethers';
import type { FunctionFragment, Result } from '@ethersproject/abi';
import type { Listener, Provider } from '@ethersproject/providers';
import type { TypedEventFilter, TypedEvent, TypedListener, OnEvent } from './common';

export interface ProtocolFeesCollectorInterface extends utils.Interface {
functions: {
'getFlashLoanFeePercentage()': FunctionFragment;
};

getFunction(nameOrSignatureOrTopic: 'getFlashLoanFeePercentage'): FunctionFragment;

encodeFunctionData(functionFragment: 'getFlashLoanFeePercentage', values?: undefined): string;

decodeFunctionResult(functionFragment: 'getFlashLoanFeePercentage', data: BytesLike): Result;

events: {};
}

export interface ProtocolFeesCollector extends BaseContract {
connect(signerOrProvider: Signer | Provider | string): this;
attach(addressOrName: string): this;
deployed(): Promise<this>;

interface: ProtocolFeesCollectorInterface;

queryFilter<TEvent extends TypedEvent>(
event: TypedEventFilter<TEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TEvent>>;

listeners<TEvent extends TypedEvent>(eventFilter?: TypedEventFilter<TEvent>): Array<TypedListener<TEvent>>;
listeners(eventName?: string): Array<Listener>;
removeAllListeners<TEvent extends TypedEvent>(eventFilter: TypedEventFilter<TEvent>): this;
removeAllListeners(eventName?: string): this;
off: OnEvent<this>;
on: OnEvent<this>;
once: OnEvent<this>;
removeListener: OnEvent<this>;

functions: {
getFlashLoanFeePercentage(overrides?: CallOverrides): Promise<[BigNumber]>;
};

getFlashLoanFeePercentage(overrides?: CallOverrides): Promise<BigNumber>;

callStatic: {
getFlashLoanFeePercentage(overrides?: CallOverrides): Promise<BigNumber>;
};

filters: {};

estimateGas: {
getFlashLoanFeePercentage(overrides?: CallOverrides): Promise<BigNumber>;
};

populateTransaction: {
getFlashLoanFeePercentage(overrides?: CallOverrides): Promise<PopulatedTransaction>;
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */

import { Contract, Signer, utils } from 'ethers';
import type { Provider } from '@ethersproject/providers';
import type { ProtocolFeesCollector, ProtocolFeesCollectorInterface } from '../ProtocolFeesCollector';

const _abi = [
{
inputs: [],
name: 'getFlashLoanFeePercentage',
outputs: [
{
internalType: 'uint256',
name: '',
type: 'uint256',
},
],
stateMutability: 'view',
type: 'function',
},
] as const;

export class ProtocolFeesCollector__factory {
static readonly abi = _abi;
static createInterface(): ProtocolFeesCollectorInterface {
return new utils.Interface(_abi) as ProtocolFeesCollectorInterface;
}
static connect(address: string, signerOrProvider: Signer | Provider): ProtocolFeesCollector {
return new Contract(address, _abi, signerOrProvider) as ProtocolFeesCollector;
}
}
1 change: 1 addition & 0 deletions src/logics/balancer-v2/contracts/factories/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
/* tslint:disable */
/* eslint-disable */
export { BalancerV2FlashLoanCallback__factory } from './BalancerV2FlashLoanCallback__factory';
export { ProtocolFeesCollector__factory } from './ProtocolFeesCollector__factory';
export { Vault__factory } from './Vault__factory';
2 changes: 2 additions & 0 deletions src/logics/balancer-v2/contracts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
/* tslint:disable */
/* eslint-disable */
export type { BalancerV2FlashLoanCallback } from './BalancerV2FlashLoanCallback';
export type { ProtocolFeesCollector } from './ProtocolFeesCollector';
export type { Vault } from './Vault';
export * as factories from './factories';
export { BalancerV2FlashLoanCallback__factory } from './factories/BalancerV2FlashLoanCallback__factory';
export { ProtocolFeesCollector__factory } from './factories/ProtocolFeesCollector__factory';
export { Vault__factory } from './factories/Vault__factory';
48 changes: 36 additions & 12 deletions src/logics/balancer-v2/logic.flash-loan.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BigNumberish } from 'ethers';
import { ProtocolFeesCollector__factory, Vault__factory } from './contracts';
import { TokenList } from '@uniswap/token-lists';
import { Vault__factory } from './contracts';
import { axios } from 'src/utils';
import * as common from '@protocolink/common';
import * as core from '@protocolink/core';
Expand Down Expand Up @@ -30,7 +30,7 @@ export class FlashLoanLogic extends core.Logic implements core.LogicTokenListInt

async getTokenList() {
const { data } = await axios.get<TokenList>(
'https://raw.githubusercontent.com/balancer/tokenlists/main/generated/listed-old.tokenlist.json'
'https://raw.githubusercontent.com/balancer/tokenlists/main/generated/balancer.tokenlist.json'
);

const tmp: Record<string, boolean> = {};
Expand All @@ -46,26 +46,50 @@ export class FlashLoanLogic extends core.Logic implements core.LogicTokenListInt

async quote(params: FlashLoanLogicParams) {
const { outputs: loans } = params;
invariant(new Set(loans.map(({ token }) => token.address)).size === loans.length, 'loans have duplicate tokens');

const vaultAddress = getContractAddress(this.chainId, 'Vault');
const calls: common.Multicall2.CallStruct[] = loans.map((loan) => ({
target: loan.token.address,
callData: this.erc20Iface.encodeFunctionData('balanceOf', [vaultAddress]),
}));
const protocolFeesCollectorIface = ProtocolFeesCollector__factory.createInterface();

const calls: common.Multicall2.CallStruct[] = [
{
target: getContractAddress(this.chainId, 'ProtocolFeesCollector'),
callData: protocolFeesCollectorIface.encodeFunctionData('getFlashLoanFeePercentage'),
},
];
loans.forEach(({ token }) => {
calls.push({
target: token.address,
callData: this.erc20Iface.encodeFunctionData('balanceOf', [vaultAddress]),
});
});
const { returnData } = await this.multicall2.callStatic.aggregate(calls);

let j = 0;
const [flashLoanFeePercentage] = protocolFeesCollectorIface.decodeFunctionResult(
'getFlashLoanFeePercentage',
returnData[j]
);
const feeBps = flashLoanFeePercentage.toNumber();
j++;

const repays = new common.TokenAmounts();
const fees = new common.TokenAmounts();
for (let i = 0; i < loans.length; i++) {
const loan = loans.at(i);
const [balance] = this.erc20Iface.decodeFunctionResult('balanceOf', returnData[i]);
const avaliableToBorrow = new common.TokenAmount(loan.token).setWei(balance);
invariant(avaliableToBorrow.gte(loan), `insufficient borrowing capacity for the asset: ${loan.token.address}`);
const [balance] = this.erc20Iface.decodeFunctionResult('balanceOf', returnData[j]);
const availableToBorrow = new common.TokenAmount(loan.token).setWei(balance);
invariant(availableToBorrow.gte(loan), `insufficient borrowing capacity for the asset: ${loan.token.address}`);
j++;

const feeAmountWei = common.calcFee(loan.amountWei, feeBps);
const fee = new common.TokenAmount(loan.token).setWei(feeAmountWei);
fees.add(fee);

repays.add(loan.token, loan.amount);
fees.add(loan.token, '0');
const repay = loan.clone().add(fee);
repays.add(repay);
}
const quotation: FlashLoanLogicQuotation = { loans, repays, fees, feeBps: 0 };
const quotation: FlashLoanLogicQuotation = { loans, repays, fees, feeBps };

return quotation;
}
Expand Down

0 comments on commit 2bcb71e

Please sign in to comment.