Skip to content

Commit

Permalink
fix Recently added FluidDex pools are not discovered
Browse files Browse the repository at this point in the history
  • Loading branch information
aburkut committed Dec 16, 2024
1 parent 738c886 commit 18031e9
Show file tree
Hide file tree
Showing 8 changed files with 441 additions and 72 deletions.
1 change: 1 addition & 0 deletions src/dex/fluid-dex/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const MIN_SWAP_LIQUIDITY = 10n ** 4n;
17 changes: 17 additions & 0 deletions src/dex/fluid-dex/fluid-dex-e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,23 @@ describe('FluidDex E2E', () => {
describe('Mainnet', () => {
const network = Network.MAINNET;

describe('ETH -> INST', () => {
const tokenASymbol: string = 'ETH';
const tokenBSymbol: string = 'INST';

const tokenAAmount: string = '100000000000000';
const tokenBAmount: string = '100000000000000';

testForNetwork(
network,
dexKey,
tokenASymbol,
tokenBSymbol,
tokenAAmount,
tokenBAmount,
);
});

describe('ETH -> wstETH', () => {
const tokenASymbol: string = 'wstETH';
const tokenBSymbol: string = 'ETH';
Expand Down
12 changes: 12 additions & 0 deletions src/dex/fluid-dex/fluid-dex-events.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { FluidDexLiquidityProxyState } from './types';
import { FluidDexConfig } from './config';
import { FluidDexLiquidityProxy } from './fluid-dex-liquidity-proxy';
import { FluidDexFactory } from './fluid-dex-factory';
import { FluidDexEventPool } from './fluid-dex-pool';

jest.setTimeout(50 * 1000);

Expand Down Expand Up @@ -126,4 +127,15 @@ describe('FluidDex EventPool Mainnet', function () {
},
);
});

describe('Pool events', () => {
let dexPool: FluidDexEventPool;

const eventsToTest: Record<Address, EventMappings> = {
'0x8710039D5de6840EdE452A85672B32270a709aE2': {
LogPauseSwapAndArbitrage: [21337128],
LogUnpauseSwapAndArbitrage: [],
},
};
});
});
42 changes: 39 additions & 3 deletions src/dex/fluid-dex/fluid-dex-liquidity-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { bigIntify, catchParseLogError } from '../../utils';
import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
import { IDexHelper } from '../../dex-helper/idex-helper';
import ResolverABI from '../../abi/fluid-dex/resolver.abi.json';
import FluidDexPoolABI from '../../abi/fluid-dex/fluid-dex.abi.json';
import LiquidityABI from '../../abi/fluid-dex/liquidityUserModule.abi.json';
import {
CommonAddresses,
Expand All @@ -13,7 +14,13 @@ import {
PoolReserveResponse,
} from './types';
import { Address } from '../../types';
import { Contract } from 'ethers';
import { Contract, ethers } from 'ethers';
import { uint256ToBigInt } from '../../lib/decoders';
import { DecodedStateMultiCallResultWithRelativeBitmaps } from '../uniswap-v3/types';

const {
utils: { hexlify, hexZeroPad },
} = ethers;

export class FluidDexLiquidityProxy extends StatefulEventSubscriber<FluidDexLiquidityProxyState> {
handlers: {
Expand All @@ -28,7 +35,9 @@ export class FluidDexLiquidityProxy extends StatefulEventSubscriber<FluidDexLiqu

addressesSubscribed: Address[];

protected liquidityIface = new Interface(LiquidityABI);
readonly liquidityIface = new Interface(LiquidityABI);

readonly poolIface = new Interface(FluidDexPoolABI);

readonly resolverIface = new Interface(ResolverABI);

Expand Down Expand Up @@ -123,7 +132,34 @@ export class FluidDexLiquidityProxy extends StatefulEventSubscriber<FluidDexLiqu
});

const convertedResult = this.convertToFluidDexPoolState(rawResult);

//
// const multicallData = convertedResult.poolsReserves.map(pool => ({
// target: pool.pool,
// callData: this.poolIface.encodeFunctionData('readFromStorage', [
// hexZeroPad(hexlify(1), 32),
// ]),
// decodeFunction: uint256ToBigInt,
// }));
//
// const storageResults = await this.dexHelper.multiWrapper.tryAggregate<
// bigint | DecodedStateMultiCallResultWithRelativeBitmaps
// >(
// false,
// multicallData,
// blockNumber,
// this.dexHelper.multiWrapper.defaultBatchSize,
// false,
// );
//
// const poolsReserves = convertedResult.poolsReserves.map(
// (poolReserve, index) => {
// const isSwapAndArbitragePaused =
// BigInt(storageResults[index].returnData.toString()) >> BigInt(255) ===
// BigInt(1);
// return { ...poolReserve, isSwapAndArbitragePaused };
// },
// );
//
this.logger.info(`${this.parentName}: ${this.name}: generating state...`);

return convertedResult;
Expand Down
138 changes: 138 additions & 0 deletions src/dex/fluid-dex/fluid-dex-pool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
import { DeepReadonly } from 'ts-essentials';
import { Address, Log, Logger } from '../../types';
import { IDexHelper } from '../../dex-helper';
import { Interface } from '@ethersproject/abi';
import FluidDexPoolABI from '../../abi/fluid-dex/fluid-dex.abi.json';
import { catchParseLogError } from '../../utils';
import { ethers } from 'ethers';
import { uint256ToBigInt } from '../../lib/decoders';
import { DecodedStateMultiCallResultWithRelativeBitmaps } from '../uniswap-v3/types';

const {
utils: { hexlify, hexZeroPad },
} = ethers;

type PoolState = {
isSwapAndArbitragePaused: boolean;
};

export class FluidDexEventPool extends StatefulEventSubscriber<PoolState> {
handlers: {
[event: string]: (
event: any,
state: DeepReadonly<PoolState>,
log: Readonly<Log>,
) => DeepReadonly<PoolState> | null;
} = {};

logDecoder: (log: Log) => any;
addressesSubscribed: Address[];
protected poolIface = new Interface(FluidDexPoolABI);

constructor(
readonly parentName: string,
readonly poolAddress: string,
protected network: number,
protected dexHelper: IDexHelper,
logger: Logger,
) {
super(parentName, 'pool', dexHelper, logger);

this.logDecoder = (log: Log) => this.poolIface.parseLog(log);
this.addressesSubscribed = [poolAddress];

// Add handlers
this.handlers['LogPauseSwapAndArbitrage'] =
this.handleLogPauseSwapAndArbitrage.bind(this);
this.handlers['LogUnpauseSwapAndArbitrage'] =
this.handleLogUnpauseSwapAndArbitrage.bind(this);
}

/**
* The function is called every time any of the subscribed
* addresses release log. The function accepts the current
* state, updates the state according to the log, and returns
* the updated state.
* @param state - Current state of event subscriber
* @param log - Log released by one of the subscribed addresses
* @returns Updates state of the event subscriber after the log
*/
async processLog(
state: DeepReadonly<PoolState>,
log: Readonly<Log>,
): Promise<DeepReadonly<PoolState> | null> {
try {
let event;
try {
event = this.logDecoder(log);
} catch (e) {
return null;
}
if (event.name in this.handlers) {
return this.handlers[event.name](event, state, log);
}
} catch (e) {
catchParseLogError(e, this.logger);
}

return null;
}

handleLogPauseSwapAndArbitrage() {
return { isSwapAndArbitragePaused: true };
}

handleLogUnpauseSwapAndArbitrage() {
return { isSwapAndArbitragePaused: false };
}

async getStateOrGenerate(
blockNumber: number,
readonly: boolean = false,
): Promise<DeepReadonly<PoolState>> {
let state = this.getState(blockNumber);
if (!state) {
state = await this.generateState(blockNumber);
if (!readonly) this.setState(state, blockNumber);
}
return state;
}

/**
* The function generates state using on-chain calls. This
* function is called to regenerate state if the event based
* system fails to fetch events and the local state is no
* more correct.
* @param blockNumber - Blocknumber for which the state should
* should be generated
* @returns state of the event subscriber at blocknumber
*/
async generateState(blockNumber: number): Promise<DeepReadonly<PoolState>> {
const multicallData = [
{
target: this.addressesSubscribed[0],
callData: this.poolIface.encodeFunctionData('readFromStorage', [
hexZeroPad(hexlify(1), 32),
]),
decodeFunction: uint256ToBigInt,
},
];

const storageResults = await this.dexHelper.multiWrapper.tryAggregate<
bigint | DecodedStateMultiCallResultWithRelativeBitmaps
>(
false,
multicallData,
blockNumber,
this.dexHelper.multiWrapper.defaultBatchSize,
false,
);

const isSwapAndArbitragePaused =
BigInt(storageResults[0].returnData.toString()) >> BigInt(255) ===
BigInt(1);

return { isSwapAndArbitragePaused };
}
}
Loading

0 comments on commit 18031e9

Please sign in to comment.