Skip to content

Commit c450792

Browse files
authored
Merge pull request #57 from VenusProtocol/cache-candidate-pools
feat: cache candidate pools for 15 minutes
2 parents dface15 + a507079 commit c450792

File tree

2 files changed

+47
-12
lines changed

2 files changed

+47
-12
lines changed

packages/keeper-bots/src/__mocks__/@pancakeswap/smart-router/evm/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const SmartRouter = {
3636
getV2PoolSubgraph: jest.fn(),
3737
getV2PoolsOnChain: jest.fn(),
3838
getV2PoolsWithTvlByCommonTokenPrices: jest.fn(),
39-
getV3CandidatePools: jest.fn(),
39+
getV3CandidatePools: jest.fn(() => [{}]),
4040
getV3PoolSubgraph: jest.fn(),
4141
getV3PoolsWithTvlFromOnChain: jest.fn(),
4242
getV3PoolsWithTvlFromOnChainFallback: jest.fn(),

packages/keeper-bots/src/providers/pancake-swap.ts

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ class PancakeSwapProvider extends SwapProvider {
1818
private v3PancakeSubgraphClient: UrqlClient | undefined;
1919
private tokens: Map<Address, Token>;
2020
private quoteProvider: QuoteProvider;
21+
private _candidatePools: {
22+
expirationTimestamp: Date;
23+
data: ReturnType<typeof SmartRouter.getV3CandidatePools>;
24+
};
2125

2226
constructor({ subscriber }: { subscriber?: (msg: ConverterBotMessage) => void }) {
2327
super({ subscriber });
@@ -32,6 +36,10 @@ class PancakeSwapProvider extends SwapProvider {
3236
this.tokens = new Map();
3337
this.chainName = config.network.name;
3438
this.liquidityProviderId = 1;
39+
this._candidatePools = {
40+
expirationTimestamp: new Date(),
41+
data: [],
42+
};
3543
}
3644

3745
/**
@@ -67,6 +75,31 @@ class PancakeSwapProvider extends SwapProvider {
6775
throw new Error(`Unable to fetch token details for ${address}`);
6876
}
6977

78+
/**
79+
* Querying candidate pools can be a heavy operation so we cache it for 15 minutes
80+
* @param swapFromToken
81+
* @param swapToToken
82+
*/
83+
getCandidatePools = async (swapFromToken: Token, swapToToken: Token) => {
84+
const now = new Date();
85+
if (!this._candidatePools.data.length || this._candidatePools.expirationTimestamp < now) {
86+
const candidatePools = await SmartRouter.getV3CandidatePools({
87+
onChainProvider: () => this.publicClient,
88+
subgraphProvider: () => this.v3PancakeSubgraphClient,
89+
currencyA: swapFromToken,
90+
currencyB: swapToToken,
91+
});
92+
93+
now.setMinutes(15 + new Date().getMinutes());
94+
this._candidatePools.data = candidatePools;
95+
this._candidatePools.expirationTimestamp = now;
96+
97+
return candidatePools;
98+
}
99+
100+
return this._candidatePools.data;
101+
};
102+
70103
async getBestTrade(
71104
tokenConverter: Address,
72105
swapFrom: Address,
@@ -76,6 +109,10 @@ class PancakeSwapProvider extends SwapProvider {
76109
const swapFromToken = await this.getToken(swapFrom);
77110
const swapToToken = await this.getToken(swapTo);
78111

112+
let trade;
113+
let error;
114+
let priceImpact;
115+
79116
// [amount transferred out of converter, amount transferred in]
80117
const { result: updatedAmountIn } = await this.publicClient.simulateContract({
81118
address: tokenConverter,
@@ -84,17 +121,9 @@ class PancakeSwapProvider extends SwapProvider {
84121
args: [amount, swapTo, swapFrom],
85122
});
86123

87-
const candidatePools = await SmartRouter.getV3CandidatePools({
88-
onChainProvider: () => this.publicClient,
89-
subgraphProvider: () => this.v3PancakeSubgraphClient,
90-
currencyA: swapFromToken,
91-
currencyB: swapToToken,
92-
});
93-
let trade;
94-
let error;
95-
let priceImpact;
96-
97124
try {
125+
const candidatePools = await this.getCandidatePools(swapFromToken, swapToToken);
126+
98127
const response = await SmartRouter.getBestTrade(
99128
CurrencyAmount.fromRawAmount(swapToToken, updatedAmountIn[1]),
100129
swapFromToken,
@@ -124,7 +153,13 @@ class PancakeSwapProvider extends SwapProvider {
124153
}
125154
priceImpact = SmartRouter.getPriceImpact(response);
126155
} catch (e) {
127-
error = `Error getting best trade - ${(e as Error).message}`;
156+
const message = (e as Error).message;
157+
error = `Error getting best trade - ${message}`;
158+
// If we can't find a valid swap invalidate pool cache
159+
if (message === "Cannot find a valid swap route") {
160+
this._candidatePools.data = [];
161+
this._candidatePools.expirationTimestamp = new Date();
162+
}
128163
throw new Error(error);
129164
}
130165

0 commit comments

Comments
 (0)