diff --git a/evm/env/testing.env b/evm/env/testing.env index b371d1e0..c2983018 100644 --- a/evm/env/testing.env +++ b/evm/env/testing.env @@ -1,5 +1,5 @@ export AVALANCHE_RPC=https://api.avax.network/ext/bc/C/rpc -export ETHEREUM_RPC=https://rpc.ankr.com/eth +export ETHEREUM_RPC=https://eth.llamarpc.com export AVAX_USDC_ADDRESS=0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E diff --git a/evm/forge/tests/MatchingEngine.t.sol b/evm/forge/tests/MatchingEngine.t.sol index 40df9220..22dd789b 100644 --- a/evm/forge/tests/MatchingEngine.t.sol +++ b/evm/forge/tests/MatchingEngine.t.sol @@ -55,6 +55,8 @@ contract MatchingEngineTest is Test { uint32 constant ARB_DOMAIN = 3; uint32 constant ETH_DOMAIN = 0; uint32 constant AVAX_DOMAIN = 1; + uint256 constant WORMHOLE_MESSAGE_FEE = 1; + uint256 constant WORMHOLE_MESSAGE_FEE_STORAGE_SLOT = 7; // Environment variables. uint256 immutable TESTING_SIGNER = uint256(vm.envBytes32("TESTING_DEVNET_GUARDIAN")); @@ -128,6 +130,8 @@ contract MatchingEngineTest is Test { } function setUp() public { + // Set core bridge messageFee > 0 + vm.store(address(wormhole), bytes32(uint256(WORMHOLE_MESSAGE_FEE_STORAGE_SLOT)), bytes32(uint256(WORMHOLE_MESSAGE_FEE))); vm.startPrank(makeAddr("owner")); engine = deployProxy(USDC_ADDRESS, address(wormhole), CIRCLE_BRIDGE.fromUniversalAddress()); @@ -1794,9 +1798,10 @@ contract MatchingEngineTest is Test { // Record logs for placeMarketOrder. vm.recordLogs(); + vm.deal(caller, WORMHOLE_MESSAGE_FEE); // Place the order. vm.prank(caller); - engine.executeFastOrder(fastMessage); + engine.executeFastOrder{value: WORMHOLE_MESSAGE_FEE}(fastMessage); // Fetch the logs for Wormhole message. There should be two messages. Vm.Log[] memory logs = vm.getRecordedLogs(); @@ -1816,9 +1821,10 @@ contract MatchingEngineTest is Test { // Record logs for placeMarketOrder. vm.recordLogs(); + vm.deal(caller, WORMHOLE_MESSAGE_FEE); // Place the order. vm.prank(caller); - engine.executeFastOrder(fastMessage); + engine.executeFastOrder{value: WORMHOLE_MESSAGE_FEE}(fastMessage); // Fetch the logs for Wormhole message. There should be two messages. Vm.Log[] memory logs = vm.getRecordedLogs(); @@ -1837,8 +1843,10 @@ contract MatchingEngineTest is Test { // Record logs for placeMarketOrder. vm.recordLogs(); + vm.deal(caller, WORMHOLE_MESSAGE_FEE); + vm.prank(caller); - engine.executeSlowOrderAndRedeem(fastTransferVaa, params); + engine.executeSlowOrderAndRedeem{value: WORMHOLE_MESSAGE_FEE}(fastTransferVaa, params); // Fetch the logs for Wormhole message. There should be two messages. Vm.Log[] memory logs = vm.getRecordedLogs(); diff --git a/evm/forge/tests/TokenRouter.t.sol b/evm/forge/tests/TokenRouter.t.sol index 02c54a60..4c547f45 100644 --- a/evm/forge/tests/TokenRouter.t.sol +++ b/evm/forge/tests/TokenRouter.t.sol @@ -76,6 +76,10 @@ contract TokenRouterTest is Test, ITokenRouterEvents { ITokenRouter router; SigningWormholeSimulator wormholeSimulator; CircleSimulator circleSimulator; + + // Core bridge. + uint256 immutable WORMHOLE_MESSAGE_FEE_STORAGE_SLOT = 7; + uint256 immutable WORMHOLE_MESSAGE_FEE = 1; function deployProxy(address _token, address _wormhole, address _tokenMessenger) internal @@ -128,6 +132,9 @@ contract TokenRouterTest is Test, ITokenRouterEvents { circleSimulator = new CircleSimulator(TESTING_SIGNER, MESSAGE_TRANSMITTER); circleSimulator.setupCircleAttester(); + + // Set core bridge messageFee > 0 + vm.store(address(wormhole), bytes32(uint256(WORMHOLE_MESSAGE_FEE_STORAGE_SLOT)), bytes32(uint256(WORMHOLE_MESSAGE_FEE))); } /** @@ -1607,7 +1614,9 @@ contract TokenRouterTest is Test, ITokenRouterEvents { vm.recordLogs(); // Place the order. - _router.placeMarketOrder( + _router.placeMarketOrder{ + value: WORMHOLE_MESSAGE_FEE + }( amountIn, minAmountOut, targetChain, redeemer, redeemerMessage, refundAddress ); @@ -1637,7 +1646,7 @@ contract TokenRouterTest is Test, ITokenRouterEvents { vm.recordLogs(); // Place the order. - _router.placeMarketOrder(amountIn, targetChain, redeemer, redeemerMessage); + _router.placeMarketOrder{value: WORMHOLE_MESSAGE_FEE}(amountIn, targetChain, redeemer, redeemerMessage); // Fetch the logs for Wormhole message. Vm.Log[] memory logs = vm.getRecordedLogs(); @@ -1663,7 +1672,9 @@ contract TokenRouterTest is Test, ITokenRouterEvents { vm.recordLogs(); // Place the order. - _router.placeFastMarketOrder( + _router.placeFastMarketOrder{ + value: WORMHOLE_MESSAGE_FEE * 2 + }( expectedOrder.amountIn, expectedOrder.minAmountOut, expectedOrder.targetChain, @@ -1708,7 +1719,9 @@ contract TokenRouterTest is Test, ITokenRouterEvents { vm.recordLogs(); // Place the order. - _router.placeFastMarketOrder( + _router.placeFastMarketOrder{ + value: WORMHOLE_MESSAGE_FEE * 2 + }( amountIn, targetChain, redeemer, redeemerMessage, maxFee, deadline ); diff --git a/evm/ts/src/TokenRouter/evm.ts b/evm/ts/src/TokenRouter/evm.ts index 7ab4f8b1..3dfcdf59 100644 --- a/evm/ts/src/TokenRouter/evm.ts +++ b/evm/ts/src/TokenRouter/evm.ts @@ -42,6 +42,7 @@ export class EvmTokenRouter implements TokenRouter { redeemerMessage: Buffer | Uint8Array, minAmountOut?: bigint, refundAddress?: string, + transactionValue?: bigint, ) { if (minAmountOut !== undefined && refundAddress !== undefined) { return this.contract["placeMarketOrder(uint64,uint64,uint16,bytes32,bytes,address)"]( @@ -51,6 +52,9 @@ export class EvmTokenRouter implements TokenRouter { redeemer, redeemerMessage, refundAddress, + { + value: transactionValue, + } ); } else { return this.contract["placeMarketOrder(uint64,uint16,bytes32,bytes)"]( @@ -58,6 +62,9 @@ export class EvmTokenRouter implements TokenRouter { targetChain, redeemer, redeemerMessage, + { + value: transactionValue, + } ); } } @@ -71,6 +78,7 @@ export class EvmTokenRouter implements TokenRouter { deadline: number, minAmountOut?: bigint, refundAddress?: string, + transactionValue?: bigint, ) { if (minAmountOut !== undefined && refundAddress !== undefined) { return this.contract[ @@ -84,6 +92,9 @@ export class EvmTokenRouter implements TokenRouter { refundAddress, maxFee, deadline, + { + value: transactionValue, + } ); } else { return this.contract["placeFastMarketOrder(uint64,uint16,bytes32,bytes,uint64,uint32)"]( @@ -93,6 +104,9 @@ export class EvmTokenRouter implements TokenRouter { redeemerMessage, maxFee, deadline, + { + value: transactionValue, + } ); } } diff --git a/evm/ts/src/testing/consts.ts b/evm/ts/src/testing/consts.ts index 711bdd64..31cc29bd 100644 --- a/evm/ts/src/testing/consts.ts +++ b/evm/ts/src/testing/consts.ts @@ -19,7 +19,7 @@ export const USDC_DECIMALS: NetworkVars = { Base: 6, }; -export const WORMHOLE_MESSAGE_FEE = 0; +export const WORMHOLE_MESSAGE_FEE = 100000000000000n; export const WORMHOLE_GUARDIAN_SET_INDEX = 4; export const GUARDIAN_PRIVATE_KEY = "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"; diff --git a/evm/ts/tests/00__environment.ts b/evm/ts/tests/00__environment.ts index fec10610..9e42f1c2 100644 --- a/evm/ts/tests/00__environment.ts +++ b/evm/ts/tests/00__environment.ts @@ -59,6 +59,15 @@ describe("Environment", () => { const actualChainId = await coreBridge.chainId(); expect(actualChainId).to.equal(chainId); + { + // set message fee + const messageFeeSlot = 7; + await provider.send("anvil_setStorageAt", [ + coreBridge.address, + messageFeeSlot, + ethers.utils.hexZeroPad(`0x${WORMHOLE_MESSAGE_FEE.toString(16)}`, 32), + ]); + } // fetch current coreBridge protocol fee const messageFee = await coreBridge.messageFee(); expect(messageFee.eq(WORMHOLE_MESSAGE_FEE)).to.be.true; @@ -243,7 +252,7 @@ describe("Environment", () => { const scripts = `${__dirname}/../../sh`; const cmd = `bash ${scripts}/deploy_matching_engine.sh ` + - `-n localnet -c ${chainName} -u ${localhost} -k ${owner.privateKey} ` + + `-n localnet -c ${chainName} -u ${localhost} -k ${owner.privateKey}` + `> /dev/null 2>&1`; const out = execSync(cmd, { encoding: "utf8" }); diff --git a/evm/ts/tests/03__marketOrder.ts b/evm/ts/tests/03__marketOrder.ts index dbaad999..4005fc1a 100644 --- a/evm/ts/tests/03__marketOrder.ts +++ b/evm/ts/tests/03__marketOrder.ts @@ -14,6 +14,7 @@ import { ChainType, parseLiquidityLayerEnvFile, tryNativeToUint8Array, + WORMHOLE_MESSAGE_FEE, } from "../src/testing"; import { toChainId } from "@wormhole-foundation/sdk-base"; @@ -113,6 +114,7 @@ describe("Market Order Business Logic -- CCTP to CCTP", () => { Buffer.from("All your base are belong to us."), minAmountOut, fromWallet.address, + WORMHOLE_MESSAGE_FEE, ) .then((tx) => mineWait(fromProvider, tx)) .catch((err) => {