Skip to content

Commit 10af41e

Browse files
committed
chore: add custom errors to abis
1 parent 2394f80 commit 10af41e

File tree

6 files changed

+79
-14
lines changed

6 files changed

+79
-14
lines changed

src/core/abis/fpmm.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,33 @@ export const FPMM_ABI = parseAbi([
1515
'function rebalanceThresholdBelow() view returns (uint256)',
1616
'function liquidityStrategy(address) view returns (bool)',
1717
'function getRebalancingState() view returns (uint256, uint256, uint256, uint256, bool, uint16, uint256)',
18+
19+
// Custom errors
20+
'error ReferenceRateNotSet()',
21+
'error ReservesEmpty()',
22+
'error InvalidToken()',
23+
'error ZeroAddress()',
24+
'error ProtocolFeeRecipientRequired()',
25+
'error NotFeeSetter()',
26+
'error FeeTooHigh()',
27+
'error InsufficientLiquidityMinted()',
28+
'error InsufficientLiquidityBurned()',
29+
'error InsufficientOutputAmount()',
30+
'error InsufficientLiquidity()',
31+
'error InvalidToAddress()',
32+
'error InsufficientInputAmount()',
33+
'error NotLiquidityStrategy()',
34+
'error OneOutputAmountRequired()',
35+
'error PriceDifferenceTooSmall()',
36+
'error PriceDifferenceNotImproved()',
37+
'error PriceDifferenceMovedInWrongDirection()',
38+
'error PriceDifferenceMovedTooFarFromThresholds()',
39+
'error InsufficientAmount0In()',
40+
'error InsufficientAmount1In()',
41+
'error ReserveValueDecreased()',
42+
'error RebalanceIncentiveTooHigh()',
43+
'error RebalanceThresholdTooHigh()',
44+
'error RebalanceDirectionInvalid()',
45+
'error LimitDoesNotFitInInt120()',
46+
'error InvalidTokenDecimals()',
1847
])

src/core/abis/fpmmFactory.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,22 @@ import { parseAbi } from 'viem'
33
export const FPMM_FACTORY_ABI = parseAbi([
44
'function deployedFPMMAddresses() view returns (address[])',
55
'function isPool(address pool) view returns (bool)',
6+
7+
// Custom errors
8+
'error CreateXBytecodeHashMismatch()',
9+
'error ZeroAddress()',
10+
'error IdenticalTokenAddresses()',
11+
'error SortTokensZeroAddress()',
12+
'error InvalidOracleAdapter()',
13+
'error InvalidProxyAdmin()',
14+
'error InvalidOwner()',
15+
'error InvalidReferenceRateFeedID()',
16+
'error PairAlreadyExists()',
17+
'error ImplementationNotRegistered()',
18+
'error ImplementationAlreadyRegistered()',
19+
'error IndexOutOfBounds()',
20+
'error ImplementationIndexMismatch()',
21+
'error FeeTooHigh()',
22+
'error RebalanceIncentiveTooHigh()',
23+
'error RebalanceThresholdTooHigh()',
624
])

src/core/abis/router.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export const ROUTER_ABI = parseAbi([
2121
'struct Route { address from; address to; address factory; }',
2222
'struct Zap { address tokenA; address tokenB; address factory; uint256 amountOutMinA; uint256 amountOutMinB; uint256 amountAMin; uint256 amountBMin; }',
2323

24-
// Custom errors
24+
// Custom errors (Router)
2525
'error ETHTransferFailed()',
2626
'error Expired()',
2727
'error InsufficientAmount()',
@@ -42,4 +42,5 @@ export const ROUTER_ABI = parseAbi([
4242
'error PoolFactoryDoesNotExist()',
4343
'error SameAddresses()',
4444
'error ZeroAddress()',
45+
'error FXMarketClosed()',
4546
])

src/core/abis/virtualPoolFactory.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,12 @@ export const VIRTUAL_POOL_FACTORY_ABI = parseAbi([
44
'function getOrPrecomputeProxyAddress(address token0, address token1) view returns (address)',
55
'function isPool(address pool) view returns (bool)',
66
'function getAllPools() view returns (address[])',
7+
8+
// Custom errors
9+
'error InvalidExchangeProvider()',
10+
'error InvalidExchangeId()',
11+
'error VirtualPoolAlreadyExistsForThisPair()',
12+
'error InvalidCreateXBytecode()',
13+
'error PoolNotFound()',
14+
'error PoolAlreadyDeprecated()',
715
])

src/services/quotes/QuoteService.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Address, PublicClient } from 'viem'
1+
import { Address, PublicClient, BaseError, ContractFunctionRevertedError } from 'viem'
22
import { RouteService } from '../routes'
33
import { Route } from '../../core/types'
44
import { ROUTER_ABI } from '../../core/abis'
@@ -7,8 +7,6 @@ import { FXMarketClosedError } from '../../core/errors'
77
import { encodeRoutePath, ReadonlyRouterRoutes } from '../../utils/pathEncoder'
88
import { validateAddress } from '../../utils/validation'
99

10-
const FX_MARKET_CLOSED_SIG = '0xa407143a'
11-
1210
/**
1311
* Service for getting swap quotes from the Mento protocol.
1412
* Calculates expected output amounts for trades without executing them.
@@ -79,9 +77,14 @@ export class QuoteService {
7977

8078
return amounts[amounts.length - 1]
8179
} catch (error: unknown) {
82-
const errorString = String(error)
83-
if (errorString.includes(FX_MARKET_CLOSED_SIG)) {
84-
throw new FXMarketClosedError()
80+
if (error instanceof BaseError) {
81+
const revertError = error.walk((e) => e instanceof ContractFunctionRevertedError)
82+
if (
83+
revertError instanceof ContractFunctionRevertedError &&
84+
revertError.data?.errorName === 'FXMarketClosed'
85+
) {
86+
throw new FXMarketClosedError()
87+
}
8588
}
8689
throw error
8790
}

tests/unit/services/QuoteService.test.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import { RouteService } from '../../../src/services/routes'
33
import { FXMarketClosedError } from '../../../src/core/errors'
44
import { PoolType } from '../../../src/core/types'
55
import type { PublicClient } from 'viem'
6+
import { ContractFunctionRevertedError } from 'viem'
67
import { ChainId } from '../../../src/core/constants'
8+
import { ROUTER_ABI } from '../../../src/core/abis'
79

810
describe('QuoteService', () => {
911
let mockPublicClient: jest.Mocked<PublicClient>
@@ -45,20 +47,24 @@ describe('QuoteService', () => {
4547
})
4648

4749
describe('FXMarketClosed handling', () => {
48-
it('should throw FXMarketClosedError when router reverts with 0xa407143a', async () => {
49-
mockPublicClient.readContract.mockRejectedValue(
50-
new Error('execution reverted: error 0xa407143a')
51-
)
50+
function createFXMarketClosedError() {
51+
return new ContractFunctionRevertedError({
52+
abi: ROUTER_ABI as any,
53+
data: '0xa407143a',
54+
functionName: 'getAmountsOut',
55+
})
56+
}
57+
58+
it('should throw FXMarketClosedError when router reverts with FXMarketClosed', async () => {
59+
mockPublicClient.readContract.mockRejectedValue(createFXMarketClosedError())
5260

5361
await expect(
5462
service.getAmountOut(tokenIn, tokenOut, 1000000000000000000n, mockRoute)
5563
).rejects.toThrow(FXMarketClosedError)
5664
})
5765

5866
it('should throw FXMarketClosedError with descriptive message', async () => {
59-
mockPublicClient.readContract.mockRejectedValue(
60-
new Error('ContractFunctionExecutionError: 0xa407143a')
61-
)
67+
mockPublicClient.readContract.mockRejectedValue(createFXMarketClosedError())
6268

6369
await expect(
6470
service.getAmountOut(tokenIn, tokenOut, 1000000000000000000n, mockRoute)

0 commit comments

Comments
 (0)