@@ -81,6 +81,7 @@ const WALLET_ADDRESS = "0x18a390bD45bCc92652b9A91AD51Aed7f1c1358f5".toLowerCase(
8181
8282const ERC20_OHM = "0x64aa3364F17a4D01c6f1751Fd97C2BD3D7e7f1D5" . toLowerCase ( ) ;
8383const ERC20_WETH = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" . toLowerCase ( ) ;
84+ const ERC20_USDC = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" . toLowerCase ( ) ;
8485
8586const OHM_WETH_POOL = "0x88051b0eea095007d3bef21ab287be961f3d8598" . toLowerCase ( ) ;
8687const OHM_WETH_SQRTPRICEX96 = BigInt . fromString ( "198259033222864761237442349019430" ) ;
@@ -90,6 +91,14 @@ const OHM_WETH_POSITION_TICK_LOWER: i32 = -887220;
9091const OHM_WETH_POSITION_TICK_UPPER : i32 = 887220 ;
9192const OHM_WETH_POSITION_LIQUIDITY = BigInt . fromString ( "346355586036686019" ) ;
9293
94+ const OHM_USDC_POOL = "0x183ea22691c54806FE96555436dd312b6BeFAc2F" . toLowerCase ( ) ;
95+ const OHM_USDC_SQRTPRICEX96 = BigInt . fromString ( "11823183971744406029263508776" ) ;
96+ const OHM_USDC_TICK : i32 = - 38048 ;
97+ const OHM_USDC_POSITION_ID = BigInt . fromString ( "1872809" ) ;
98+ const OHM_USDC_POSITION_TICK_LOWER : i32 = - 44200 ;
99+ const OHM_USDC_POSITION_TICK_UPPER : i32 = 887220 ;
100+ const OHM_USDC_POSITION_LIQUIDITY = BigInt . fromString ( "11264485942092" ) ;
101+
93102export const mockFpisFraxPair = ( ) : void => {
94103 mockRateUniswapV3 (
95104 LP_UNISWAP_V3_FPIS_FRAX ,
@@ -118,6 +127,20 @@ export const mockOhmWethPair = (): void => {
118127 ) ;
119128} ;
120129
130+ export const mockOhmUsdcPair = ( ) : void => {
131+ mockRateUniswapV3 (
132+ OHM_USDC_POOL ,
133+ OHM_USDC_SQRTPRICEX96 ,
134+ OHM_USDC_TICK ,
135+ ERC20_OHM ,
136+ ERC20_USDC ,
137+ 9 ,
138+ 6 ,
139+ toBigInt ( BigDecimal . fromString ( "75504.35396532" ) ) ,
140+ toBigInt ( BigDecimal . fromString ( "445506.63314" ) ) ,
141+ ) ;
142+ } ;
143+
121144export const mockOhmWethPosition = ( ) : void => {
122145 // positionManager.balanceOf()
123146 createMockedFunction (
@@ -160,6 +183,48 @@ export const mockOhmWethPosition = (): void => {
160183 ] ) ;
161184} ;
162185
186+ export const mockOhmUsdcPosition = ( ) : void => {
187+ // positionManager.balanceOf()
188+ createMockedFunction (
189+ Address . fromString ( UNISWAP_V3_POSITION_MANAGER ) ,
190+ "balanceOf" ,
191+ "balanceOf(address):(uint256)" ,
192+ )
193+ . withArgs ( [ ethereum . Value . fromAddress ( Address . fromString ( WALLET_ADDRESS ) ) ] )
194+ . returns ( [ ethereum . Value . fromUnsignedBigInt ( BigInt . fromI32 ( 1 ) ) ] ) ;
195+
196+ // positionManager.tokenOfOwnerByIndex()
197+ createMockedFunction (
198+ Address . fromString ( UNISWAP_V3_POSITION_MANAGER ) ,
199+ "tokenOfOwnerByIndex" ,
200+ "tokenOfOwnerByIndex(address,uint256):(uint256)" ,
201+ )
202+ . withArgs ( [ ethereum . Value . fromAddress ( Address . fromString ( WALLET_ADDRESS ) ) , ethereum . Value . fromUnsignedBigInt ( BigInt . fromI32 ( 0 ) ) ] )
203+ . returns ( [ ethereum . Value . fromUnsignedBigInt ( OHM_USDC_POSITION_ID ) ] ) ;
204+
205+ // positionManager.positions()
206+ createMockedFunction (
207+ Address . fromString ( UNISWAP_V3_POSITION_MANAGER ) ,
208+ "positions" ,
209+ "positions(uint256):(uint96,address,address,address,uint24,int24,int24,uint128,uint256,uint256,uint128,uint128)" ,
210+ )
211+ . withArgs ( [ ethereum . Value . fromUnsignedBigInt ( OHM_USDC_POSITION_ID ) ] )
212+ . returns ( [
213+ ethereum . Value . fromUnsignedBigInt ( BigInt . fromI32 ( 0 ) ) , // nonce
214+ ethereum . Value . fromAddress ( Address . zero ( ) ) , // operator
215+ ethereum . Value . fromAddress ( Address . fromString ( ERC20_OHM ) ) , // token0
216+ ethereum . Value . fromAddress ( Address . fromString ( ERC20_USDC ) ) , // token1
217+ ethereum . Value . fromUnsignedBigInt ( BigInt . fromI32 ( 10000 ) ) , // fee
218+ ethereum . Value . fromI32 ( OHM_USDC_POSITION_TICK_LOWER ) , // tickLower
219+ ethereum . Value . fromI32 ( OHM_USDC_POSITION_TICK_UPPER ) , // tickUpper
220+ ethereum . Value . fromUnsignedBigInt ( OHM_USDC_POSITION_LIQUIDITY ) , // liquidity
221+ ethereum . Value . fromUnsignedBigInt ( BigInt . fromI32 ( 0 ) ) , // feeGrowthInside0X128
222+ ethereum . Value . fromUnsignedBigInt ( BigInt . fromI32 ( 0 ) ) , // feeGrowthInside1X128
223+ ethereum . Value . fromUnsignedBigInt ( BigInt . fromI32 ( 0 ) ) , // tokensOwed0
224+ ethereum . Value . fromUnsignedBigInt ( BigInt . fromI32 ( 0 ) ) , // tokensOwed1
225+ ] ) ;
226+ } ;
227+
163228const FPIS_RATE = BigDecimal . fromString ( "1.13357594386" ) ;
164229
165230describe ( "getPrice" , ( ) => {
@@ -348,7 +413,28 @@ describe("getUnderlyingTokenBalance", () => {
348413 const ohmBalance = handler . getUnderlyingTokenBalance ( WALLET_ADDRESS , ERC20_OHM , BLOCK ) ;
349414 const wethBalance = handler . getUnderlyingTokenBalance ( WALLET_ADDRESS , ERC20_WETH , BLOCK ) ;
350415
351- assert . stringEquals ( "138431.489223295" , ohmBalance . toString ( ) ) ;
352- assert . stringEquals ( "866.581676263788419538" , wethBalance . toString ( ) ) ;
416+ assert . stringEquals ( "138410.423" , ohmBalance . truncate ( 4 ) . toString ( ) ) ;
417+ assert . stringEquals ( "866.7135" , wethBalance . truncate ( 4 ) . toString ( ) ) ;
418+ } ) ;
419+
420+ test ( "OHM-USDC balances are correct" , ( ) => {
421+ const contractLookup : ContractNameLookup = ( tokenAddress : string ) : string => {
422+ if ( addressesEqual ( tokenAddress , ERC20_USDC ) ) {
423+ return "USDC" ;
424+ }
425+
426+ return "OHM" ;
427+ } ;
428+
429+ mockOhmUsdcPair ( ) ;
430+ mockOhmUsdcPosition ( ) ;
431+
432+ const handler = new PriceHandlerUniswapV3 ( [ ERC20_OHM , ERC20_USDC ] , OHM_USDC_POOL , UNISWAP_V3_POSITION_MANAGER , contractLookup ) ;
433+
434+ const ohmBalance = handler . getUnderlyingTokenBalance ( WALLET_ADDRESS , ERC20_OHM , BLOCK ) ;
435+ const usdcBalance = handler . getUnderlyingTokenBalance ( WALLET_ADDRESS , ERC20_USDC , BLOCK ) ;
436+
437+ assert . stringEquals ( "75484.2794" , ohmBalance . truncate ( 4 ) . toString ( ) ) ;
438+ assert . stringEquals ( "445136.3419" , usdcBalance . truncate ( 4 ) . toString ( ) ) ;
353439 } ) ;
354440} ) ;
0 commit comments