@@ -42,9 +42,17 @@ import {IPyth} from "@pythnetwork/IPyth.sol";
4242import {MockPyth} from "@pythnetwork/MockPyth.sol " ;
4343import {MockERC20} from "./mocks/MockERC20.sol " ;
4444import {RolloverVault} from "../src/RolloverVault.sol " ;
45+ import {FulfillmentVault} from "../src/FulfillmentVault.sol " ;
46+ import {CoreSimulatorLib} from "@hyper-evm-lib/test/simulation/CoreSimulatorLib.sol " ;
47+ import {PrecompileLib} from "@hyper-evm-lib/src/PrecompileLib.sol " ;
48+ import {HyperCore} from "@hyper-evm-lib/test/simulation/HyperCore.sol " ;
49+ import {TokenRegistry} from "@hyper-evm-lib/src/registry/TokenRegistry.sol " ;
50+ import {HLConversions} from "@hyper-evm-lib/src/common/HLConversions.sol " ;
51+ import {HLConstants} from "@hyper-evm-lib/src/common/HLConstants.sol " ;
4552
4653contract BaseTest is Test {
4754 using OPoolConfigIdLibrary for OPoolConfigId;
55+ using PrecompileLib for address ;
4856
4957 // Actors
5058 address public admin = makeAddr ("admin " );
@@ -112,6 +120,27 @@ contract BaseTest is Test {
112120 uint8 ROLLLOVER_VAULT_DECIMALS = 24 ; // Make this 6 + usdx decimals
113121 uint8 ROLLLOVER_VAULT_DECIMALS_OFFSET = 6 ;
114122 RolloverVault public rolloverVault;
123+ // Hyper-EVM-Lib Values
124+ HyperCore public hyperCore;
125+ TokenRegistry public tokenRegistry;
126+ address public HYPER_CORE_ADDRESS = 0x9999999999999999999999999999999999999999 ;
127+ address TOKEN_INFO_PRECOMPILE_ADDRESS = 0x000000000000000000000000000000000000080C ;
128+ address SPOT_INFO_PRECOMPILE_ADDRESS = 0x000000000000000000000000000000000000080b ;
129+ address SPOT_PX_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000808 ;
130+ address public TOKEN_REGISTRY_ADDRESS = 0x0b51d1A9098cf8a72C325003F44C194D41d7A85B ;
131+ address public UBTC_SYSTEM_ADDRESS = 0x20000000000000000000000000000000000000c5 ;
132+ uint32 public HYPE_TOKEN_INDEX = uint32 (HLConstants.hypeTokenIndex ());
133+ uint32 public USDC_TOKEN_INDEX = 0 ;
134+ uint32 public USDT_TOKEN_INDEX = 268 ;
135+ uint32 public USDH_TOKEN_INDEX = 360 ;
136+ uint32 public UBTC_TOKEN_INDEX = 197 ;
137+ // FulfillmentVault Args
138+ FulfillmentVault public fulfillmentVault;
139+ string FULFILLMENT_VAULT_NAME = "Test Fulfillment Vault " ;
140+ string FULFILLMENT_VAULT_SYMBOL = "tFT " ;
141+ uint8 FULFILLMENT_VAULT_DECIMALS = 24 ;
142+ uint8 FULFILLMENT_VAULT_DECIMALS_OFFSET = 6 ;
143+ // Vault Priming Amount
115144 uint256 public PRIME_AMOUNT = 1e18 ; // The initial amount of depositableAsset to prime the liquidityVault with (in depositableAsset decimals)
116145
117146 function _deployWHype () internal {
@@ -428,5 +457,154 @@ contract BaseTest is Test {
428457 vm.stopPrank ();
429458 }
430459
460+ function mockTokenInfo (
461+ uint32 tokenIndex ,
462+ address evmContract ,
463+ string memory name ,
464+ uint8 szDecimals ,
465+ uint8 weiDecimals ,
466+ int8 evmExtraWeiDecimals
467+ ) internal {
468+ PrecompileLib.TokenInfo memory info = PrecompileLib.TokenInfo ({
469+ name: name,
470+ spots: new uint64 [](0 ),
471+ deployerTradingFeeShare: 0 ,
472+ deployer: address (0 ),
473+ evmContract: evmContract,
474+ szDecimals: szDecimals,
475+ weiDecimals: weiDecimals,
476+ evmExtraWeiDecimals: evmExtraWeiDecimals
477+ });
478+
479+ vm.mockCall (TOKEN_INFO_PRECOMPILE_ADDRESS, abi.encode (tokenIndex), abi.encode (info));
480+ if (tokenIndex != HYPE_TOKEN_INDEX && tokenIndex != USDC_TOKEN_INDEX) {
481+ tokenRegistry.setTokenInfo (tokenIndex);
482+ }
483+ }
484+
485+ function mockSpotInfo (uint32 spotIndex , string memory name , uint64 [2 ] memory tokens ) internal {
486+ PrecompileLib.SpotInfo memory info = PrecompileLib.SpotInfo ({name: name, tokens: tokens});
487+ vm.mockCall (SPOT_INFO_PRECOMPILE_ADDRESS, abi.encode (spotIndex), abi.encode (info));
488+ }
489+
490+ function mockSpotPx (uint32 spotIndex , uint64 px ) internal {
491+ vm.mockCall (SPOT_PX_PRECOMPILE_ADDRESS, abi.encode (spotIndex), abi.encode (px));
492+ }
493+
494+ function setupHyperCore () internal {
495+ hyperCore = new HyperCore ();
496+ vm.etch (HYPER_CORE_ADDRESS, address (hyperCore).code);
497+ vm.label (HYPER_CORE_ADDRESS, "HyperCore " );
498+ hyperCore = CoreSimulatorLib.init ();
499+ hyperCore.setUseRealL1Read (false );
500+ }
501+
502+ function setupTokenRegistry () internal {
503+ tokenRegistry = new TokenRegistry ();
504+ vm.etch (TOKEN_REGISTRY_ADDRESS, address (tokenRegistry).code);
505+ vm.label (TOKEN_REGISTRY_ADDRESS, "TokenRegistry " );
506+ tokenRegistry = TokenRegistry (TOKEN_REGISTRY_ADDRESS);
507+ mockTokenInfo (USDT_TOKEN_INDEX, address (usdt), "USDT " , 2 , 8 , - 2 );
508+ mockTokenInfo (USDH_TOKEN_INDEX, address (usdh), "USDH " , 2 , 8 , - 2 );
509+ mockTokenInfo (HYPE_TOKEN_INDEX, address (0 ), "HYPE " , 2 , 8 , 0 );
510+ mockTokenInfo (USDC_TOKEN_INDEX, address (0 ), "USDC " , 8 , 8 , 0 );
511+ mockTokenInfo (UBTC_TOKEN_INDEX, address (ubtc), "UBTC " , 5 , 10 , - 2 );
512+ }
513+
514+ function setupSpotInfo () internal {
515+ uint64 [2 ] memory tokens = [uint64 (USDT_TOKEN_INDEX), uint64 (USDC_TOKEN_INDEX)];
516+ mockSpotInfo (USDT_TOKEN_INDEX, "@166 " , tokens);
517+ tokens = [uint64 (USDH_TOKEN_INDEX), uint64 (USDC_TOKEN_INDEX)];
518+ mockSpotInfo (USDH_TOKEN_INDEX, "@230 " , tokens);
519+ tokens = [uint64 (HYPE_TOKEN_INDEX), uint64 (USDC_TOKEN_INDEX)];
520+ mockSpotInfo (HYPE_TOKEN_INDEX, "@107 " , tokens);
521+ tokens = [uint64 (UBTC_TOKEN_INDEX), uint64 (USDC_TOKEN_INDEX)];
522+ mockSpotInfo (UBTC_TOKEN_INDEX, "@142 " , tokens);
523+ }
524+
525+ function primeFulfillmentVault () public {
526+ // Mint 0.5 PRIME_AMOUNT of usdt0 and usdh to the admin
527+ vm.startPrank (admin);
528+ uint256 usdtAmount = usdx.convertUnderlying (address (usdt), PRIME_AMOUNT / 2 );
529+ uint256 usdhAmount = usdx.convertUnderlying (address (usdh), PRIME_AMOUNT / 2 );
530+ deal (address (usdt), admin, usdtAmount);
531+ deal (address (usdh), admin, usdhAmount);
532+ vm.stopPrank ();
533+
534+ // Admin primes the fulfillmentVault with PRIME_AMOUNT of usdx
535+ vm.startPrank (admin);
536+ usdt.approve (address (usdx), usdtAmount);
537+ usdh.approve (address (usdx), usdhAmount);
538+ usdx.deposit (address (usdt), usdtAmount);
539+ usdx.deposit (address (usdh), usdhAmount);
540+ usdx.approve (address (fulfillmentVault), PRIME_AMOUNT);
541+ fulfillmentVault.deposit (address (usdx), PRIME_AMOUNT);
542+ vm.stopPrank ();
543+
544+ // Transfer the fulfillmentVault balance to the fulfillmentVault itself
545+ vm.startPrank (admin);
546+ fulfillmentVault.transfer (address (fulfillmentVault), fulfillmentVault.balanceOf (admin));
547+ vm.stopPrank ();
548+ }
549+
550+ function setUpFulfillmentVault () public {
551+ // Initialize the HyperCore simulator
552+ // vm.createSelectFork(vm.rpcUrl("hyperliquid"), 17133085);
553+ setupHyperCore ();
554+
555+ // Setup core
556+ setUpCore ();
557+
558+ // Setup the mock token registry
559+ setupTokenRegistry ();
560+
561+ // Setup the mock spot info
562+ setupSpotInfo ();
563+
564+ // Deploy the fulfillmentVault
565+ FulfillmentVault fulfillmentVaultImplementation = new FulfillmentVault ();
566+ bytes memory initializerData = abi.encodeWithSelector (
567+ FulfillmentVault.initialize.selector ,
568+ FULFILLMENT_VAULT_NAME,
569+ FULFILLMENT_VAULT_SYMBOL,
570+ FULFILLMENT_VAULT_DECIMALS,
571+ FULFILLMENT_VAULT_DECIMALS_OFFSET,
572+ address (whype),
573+ address (generalManager),
574+ address (admin)
575+ );
576+ ERC1967Proxy proxy = new ERC1967Proxy (address (fulfillmentVaultImplementation), initializerData);
577+ fulfillmentVault = FulfillmentVault (payable (address (proxy)));
578+
579+ // Prime the fulfillmentVault
580+ primeFulfillmentVault ();
581+
582+ // Grant the keeper the KEEPER_ROLE
583+ vm.startPrank (admin);
584+ fulfillmentVault.grantRole (fulfillmentVault.KEEPER_ROLE (), keeper);
585+ vm.stopPrank ();
586+
587+ // Force the fulfillmentVault to be activated on hypercore
588+ vm.mockCall (
589+ HLConstants.CORE_USER_EXISTS_PRECOMPILE_ADDRESS, abi.encode (address (fulfillmentVault)), abi.encode (true )
590+ );
591+ CoreSimulatorLib.forceAccountActivation (address (fulfillmentVault));
592+
593+ // Force activate the HYPE system address so bridging works
594+ vm.mockCall (
595+ HLConstants.CORE_USER_EXISTS_PRECOMPILE_ADDRESS, abi.encode (HLConstants.HYPE_SYSTEM_ADDRESS), abi.encode (true )
596+ );
597+ CoreSimulatorLib.forceAccountActivation (HLConstants.HYPE_SYSTEM_ADDRESS);
598+
599+ // Force activate the UBTC system address so bridging works
600+ vm.mockCall (HLConstants.CORE_USER_EXISTS_PRECOMPILE_ADDRESS, abi.encode (UBTC_SYSTEM_ADDRESS), abi.encode (true ));
601+ CoreSimulatorLib.forceAccountActivation (UBTC_SYSTEM_ADDRESS);
602+
603+ // Grant the fulfillmentVault the orderPool's FULFILLMENT_VAULT_ROLE
604+ vm.startPrank (admin);
605+ IAccessControl (address (orderPool)).grantRole (Roles.FULFILLMENT_ROLE, address (fulfillmentVault));
606+ vm.stopPrank ();
607+ }
608+
431609 function test_constructor () public view virtual {}
432610}
0 commit comments