diff --git a/packages/contracts-rfq/contracts/FastBridgeV2.sol b/packages/contracts-rfq/contracts/FastBridgeV2.sol index 9f54c87f42..9666ba35a3 100644 --- a/packages/contracts-rfq/contracts/FastBridgeV2.sol +++ b/packages/contracts-rfq/contracts/FastBridgeV2.sol @@ -177,7 +177,12 @@ contract FastBridgeV2 is Admin, IFastBridgeV2, IFastBridgeV2Errors { /// @inheritdoc IFastBridgeV2 function bridge(BridgeParams memory params, BridgeParamsV2 memory paramsV2) public payable { - int256 exclusivityEndTime = int256(block.timestamp) + paramsV2.quoteExclusivitySeconds; + int256 exclusivityEndTime = 0; + // if relayer exclusivity is not intended for this bridge, set exclusivityEndTime to static zero + // otherwise, set exclusivity to expire at the current block ts offset by quoteExclusivitySeconds + if (paramsV2.quoteRelayer != address(0)) { + exclusivityEndTime = int256(block.timestamp) + paramsV2.quoteExclusivitySeconds; + } _validateBridgeParams(params, paramsV2, exclusivityEndTime); // transfer tokens to bridge contract @@ -206,7 +211,7 @@ contract FastBridgeV2 is Admin, IFastBridgeV2, IFastBridgeV2Errors { deadline: params.deadline, nonce: senderNonces[params.sender]++, // increment nonce on every bridge exclusivityRelayer: paramsV2.quoteRelayer, - // We checked exclusivityEndTime to be in range (0 .. params.deadline] above, so can safely cast + // We checked exclusivityEndTime to be in range [0 .. params.deadline] above, so can safely cast exclusivityEndTime: uint256(exclusivityEndTime), callValue: paramsV2.callValue, callParams: paramsV2.callParams @@ -443,8 +448,8 @@ contract FastBridgeV2 is Admin, IFastBridgeV2, IFastBridgeV2Errors { if (paramsV2.callValue != 0 && params.destToken == UniversalTokenLib.ETH_ADDRESS) { revert NativeTokenCallValueNotSupported(); } - // exclusivityEndTime must be in range (0 .. params.deadline] - if (exclusivityEndTime <= 0 || exclusivityEndTime > int256(params.deadline)) { + // exclusivityEndTime must be in range [0 .. params.deadline] + if (exclusivityEndTime < 0 || exclusivityEndTime > int256(params.deadline)) { revert ExclusivityParamsIncorrect(); } } diff --git a/packages/contracts-rfq/test/FastBridgeV2.GasBench.Src.t.sol b/packages/contracts-rfq/test/FastBridgeV2.GasBench.Src.t.sol index 940eae3aa1..0ffa7d8d5e 100644 --- a/packages/contracts-rfq/test/FastBridgeV2.GasBench.Src.t.sol +++ b/packages/contracts-rfq/test/FastBridgeV2.GasBench.Src.t.sol @@ -48,17 +48,6 @@ contract FastBridgeV2GasBenchmarkSrcTest is FastBridgeV2SrcBaseTest { ethTx.nonce = 5; } - function createFixturesV2() public virtual override { - super.createFixturesV2(); - bridgedTokenTx.exclusivityEndTime = block.timestamp; - provenTokenTx.exclusivityEndTime = block.timestamp; - bridgedEthTx.exclusivityEndTime = block.timestamp; - provenEthTx.exclusivityEndTime = block.timestamp; - // Actual tx will be submitted one block later - tokenTx.exclusivityEndTime = block.timestamp + BLOCK_TIME; - ethTx.exclusivityEndTime = block.timestamp + BLOCK_TIME; - } - function mintTokens() public virtual override { super.mintTokens(); srcToken.mint(relayerA, INITIAL_RELAYER_BALANCE); diff --git a/packages/contracts-rfq/test/FastBridgeV2.Src.Exclusivity.Negative.t.sol b/packages/contracts-rfq/test/FastBridgeV2.Src.Exclusivity.Negative.t.sol index 4eeacb2f88..05db1713e3 100644 --- a/packages/contracts-rfq/test/FastBridgeV2.Src.Exclusivity.Negative.t.sol +++ b/packages/contracts-rfq/test/FastBridgeV2.Src.Exclusivity.Negative.t.sol @@ -23,9 +23,8 @@ contract FastBridgeV2SrcExclusivityNegativeTest is FastBridgeV2SrcTest { bridge(caller, msgValue, params, paramsV2); } - function test_bridge_revert_exclusivityEndTimeZero() public { + function test_bridge_exclusivityEndTimeZero() public { tokenParamsV2.quoteExclusivitySeconds = -int256(block.timestamp); - vm.expectRevert(ExclusivityParamsIncorrect.selector); bridge({caller: userA, msgValue: 0, params: tokenParams, paramsV2: tokenParamsV2}); } @@ -35,9 +34,8 @@ contract FastBridgeV2SrcExclusivityNegativeTest is FastBridgeV2SrcTest { bridge({caller: userA, msgValue: 0, params: tokenParams, paramsV2: tokenParamsV2}); } - function test_bridge_eth_revert_exclusivityEndTimeZero() public { + function test_bridge_eth_exclusivityEndTimeZero() public { ethParamsV2.quoteExclusivitySeconds = -int256(block.timestamp); - vm.expectRevert(ExclusivityParamsIncorrect.selector); bridge({caller: userA, msgValue: ethParams.originAmount, params: ethParams, paramsV2: ethParamsV2}); } diff --git a/packages/contracts-rfq/test/FastBridgeV2.t.sol b/packages/contracts-rfq/test/FastBridgeV2.t.sol index 7c3581e6ee..99a73655ce 100644 --- a/packages/contracts-rfq/test/FastBridgeV2.t.sol +++ b/packages/contracts-rfq/test/FastBridgeV2.t.sol @@ -173,9 +173,9 @@ abstract contract FastBridgeV2Test is Test, IFastBridgeV2Errors { }); tokenTx.exclusivityRelayer = address(0); - tokenTx.exclusivityEndTime = block.timestamp; + tokenTx.exclusivityEndTime = 0; ethTx.exclusivityRelayer = address(0); - ethTx.exclusivityEndTime = block.timestamp; + ethTx.exclusivityEndTime = 0; } function setStorageBridgeTxV2(