diff --git a/tests/CrossChainReceiver.t.sol b/tests/CrossChainReceiver.t.sol index 003113dc..a7edc817 100644 --- a/tests/CrossChainReceiver.t.sol +++ b/tests/CrossChainReceiver.t.sol @@ -370,271 +370,271 @@ contract CrossChainReceiverTest is BaseTest { assertEq(crossChainReceiver.isReceiverBridgeAdapterAllowed(BRIDGE_ADAPTER, 137), true); } - // // TEST RECEIVE MESSAGES - // function testReceiveCrossChainMessage(uint256 txNonce, uint256 envelopeNonce) public { - // ExtendedTransaction memory txExtended = _generateExtendedTransaction( - // TestParams({ - // origin: GOVERNANCE_CORE, - // destination: VOTING_MACHINE, - // originChainId: DEFAULT_ORIGIN_CHAIN_ID, - // destinationChainId: block.chainid, - // envelopeNonce: envelopeNonce, - // transactionNonce: txNonce - // }) - // ); - - // hoax(BRIDGE_ADAPTER); - // vm.mockCall( - // txExtended.envelope.destination, - // abi.encodeWithSelector(IBaseReceiverPortal.receiveCrossChainMessage.selector), - // abi.encode() - // ); - // vm.expectCall( - // txExtended.envelope.destination, - // abi.encodeWithSelector( - // IBaseReceiverPortal.receiveCrossChainMessage.selector, - // txExtended.envelope.origin, - // txExtended.envelope.originChainId, - // txExtended.envelope.message - // ) - // ); - // vm.expectEmit(true, true, true, true); - // emit TransactionReceived( - // txExtended.transactionId, - // txExtended.envelopeId, - // txExtended.envelope.originChainId, - // txExtended.transaction, - // BRIDGE_ADAPTER, - // 1 - // ); - // vm.expectEmit(true, true, true, true); - // emit EnvelopeDeliveryAttempted(txExtended.envelopeId, txExtended.envelope, true); - // crossChainReceiver.receiveCrossChainMessage( - // txExtended.transactionEncoded, - // txExtended.envelope.originChainId - // ); - - // // check internal transaction - // assertEq( - // crossChainReceiver.isTransactionReceivedByAdapter(txExtended.transactionId, BRIDGE_ADAPTER), - // true - // ); - // ICrossChainReceiver.TransactionStateWithoutAdapters - // memory internalTransactionState = crossChainReceiver.getTransactionState( - // txExtended.transactionId - // ); - // ICrossChainReceiver.EnvelopeState internalEnvelopeState = crossChainReceiver.getEnvelopeState( - // txExtended.envelopeId - // ); - - // assertEq(internalTransactionState.confirmations, 1); - // assertEq(internalTransactionState.firstBridgedAt, block.timestamp); - // assertTrue(internalEnvelopeState == ICrossChainReceiver.EnvelopeState.Delivered); - // } - - // function testReceiveCrossChainMessageAfterConfirmation( - // uint256 txNonce, - // uint256 envelopeNonce - // ) public { - // ExtendedTransaction memory txExtended = _generateExtendedTransaction( - // TestParams({ - // origin: GOVERNANCE_CORE, - // destination: VOTING_MACHINE, - // originChainId: DEFAULT_ORIGIN_CHAIN_ID, - // destinationChainId: block.chainid, - // envelopeNonce: envelopeNonce, - // transactionNonce: txNonce - // }) - // ); - - // hoax(BRIDGE_ADAPTER); - // vm.mockCall( - // txExtended.envelope.destination, - // abi.encodeWithSelector(IBaseReceiverPortal.receiveCrossChainMessage.selector), - // abi.encode() - // ); - // vm.expectCall( - // txExtended.envelope.destination, - // abi.encodeWithSelector( - // IBaseReceiverPortal.receiveCrossChainMessage.selector, - // txExtended.envelope.origin, - // txExtended.envelope.originChainId, - // txExtended.envelope.message - // ) - // ); - // vm.expectEmit(true, true, true, true); - // emit TransactionReceived( - // txExtended.transactionId, - // txExtended.envelopeId, - // txExtended.envelope.originChainId, - // txExtended.transaction, - // BRIDGE_ADAPTER, - // 1 - // ); - // vm.expectEmit(true, true, true, true); - // emit EnvelopeDeliveryAttempted(txExtended.envelopeId, txExtended.envelope, true); - // crossChainReceiver.receiveCrossChainMessage( - // txExtended.transactionEncoded, - // txExtended.envelope.originChainId - // ); - - // // check internal transaction - // assertEq( - // crossChainReceiver.isTransactionReceivedByAdapter(txExtended.transactionId, BRIDGE_ADAPTER), - // true - // ); - // ICrossChainReceiver.TransactionStateWithoutAdapters - // memory internalTransactionState = crossChainReceiver.getTransactionState( - // txExtended.transactionId - // ); - // ICrossChainReceiver.EnvelopeState internalEnvelopeState = crossChainReceiver.getEnvelopeState( - // txExtended.envelopeId - // ); - - // assertEq(internalTransactionState.confirmations, 1); - // assertEq(internalTransactionState.firstBridgedAt, block.timestamp); - // assertTrue(internalEnvelopeState == ICrossChainReceiver.EnvelopeState.Delivered); - - // // receive 2nd cross chain message after its already confirmed - // hoax(BRIDGE_ADAPTER_2); - // vm.expectEmit(true, true, true, true); - // emit TransactionReceived( - // txExtended.transactionId, - // txExtended.envelopeId, - // txExtended.envelope.originChainId, - // txExtended.transaction, - // BRIDGE_ADAPTER_2, - // 2 - // ); - // crossChainReceiver.receiveCrossChainMessage( - // txExtended.transactionEncoded, - // txExtended.envelope.originChainId - // ); - - // // check internal transaction - // assertEq( - // crossChainReceiver.isTransactionReceivedByAdapter(txExtended.transactionId, BRIDGE_ADAPTER_2), - // true - // ); - // internalTransactionState = crossChainReceiver.getTransactionState(txExtended.transactionId); - // internalEnvelopeState = crossChainReceiver.getEnvelopeState(txExtended.envelopeId); - - // assertEq(internalTransactionState.confirmations, 2); - // assertEq(internalTransactionState.firstBridgedAt, block.timestamp); - // assertTrue(internalEnvelopeState == ICrossChainReceiver.EnvelopeState.Delivered); - // } - - // function testReceiveCrossChainMessageAfterConfirmationsLowered() public { - // // set initial needed confirmation to 2 - // ICrossChainReceiver.ConfirmationInput memory confirmation = ICrossChainReceiver - // .ConfirmationInput({chainId: 1, requiredConfirmations: 2}); - // ICrossChainReceiver.ConfirmationInput[] - // memory requiredConfirmations = new ICrossChainReceiver.ConfirmationInput[](1); - // requiredConfirmations[0] = confirmation; - - // vm.prank(OWNER); - // crossChainReceiver.updateConfirmations(requiredConfirmations); - - // ExtendedTransaction memory txExtended = _generateExtendedTransaction( - // TestParams({ - // origin: GOVERNANCE_CORE, - // destination: VOTING_MACHINE, - // originChainId: DEFAULT_ORIGIN_CHAIN_ID, - // destinationChainId: block.chainid, - // envelopeNonce: 0, - // transactionNonce: 0 - // }) - // ); - - // // receive first confirmation message - // hoax(BRIDGE_ADAPTER); - // vm.mockCall( - // txExtended.envelope.destination, - // abi.encodeWithSelector(IBaseReceiverPortal.receiveCrossChainMessage.selector), - // abi.encode() - // ); - // vm.expectEmit(true, true, true, true); - // emit TransactionReceived( - // txExtended.transactionId, - // txExtended.envelopeId, - // txExtended.envelope.originChainId, - // txExtended.transaction, - // BRIDGE_ADAPTER, - // 1 - // ); - // crossChainReceiver.receiveCrossChainMessage( - // txExtended.transactionEncoded, - // txExtended.envelope.originChainId - // ); - - // // lower required confirmations to 1 - // requiredConfirmations[0] = ICrossChainReceiver.ConfirmationInput({ - // chainId: txExtended.envelope.originChainId, - // requiredConfirmations: 1 - // }); - - // vm.prank(OWNER); - // crossChainReceiver.updateConfirmations(requiredConfirmations); - - // // receive second confirmation message - // hoax(BRIDGE_ADAPTER_2); - // vm.mockCall( - // txExtended.envelope.destination, - // abi.encodeWithSelector(IBaseReceiverPortal.receiveCrossChainMessage.selector), - // abi.encode() - // ); - // vm.expectCall( - // txExtended.envelope.destination, - // abi.encodeWithSelector( - // IBaseReceiverPortal.receiveCrossChainMessage.selector, - // txExtended.envelope.origin, - // txExtended.envelope.originChainId, - // txExtended.envelope.message - // ) - // ); - // vm.expectEmit(true, true, true, true); - // emit TransactionReceived( - // txExtended.transactionId, - // txExtended.envelopeId, - // txExtended.envelope.originChainId, - // txExtended.transaction, - // BRIDGE_ADAPTER_2, - // 2 - // ); - - // vm.expectEmit(true, true, false, true); - // emit EnvelopeDeliveryAttempted(txExtended.envelopeId, txExtended.envelope, true); - // crossChainReceiver.receiveCrossChainMessage( - // txExtended.transactionEncoded, - // txExtended.envelope.originChainId - // ); - - // // check internal message - // assertEq( - // crossChainReceiver.isTransactionReceivedByAdapter(txExtended.transactionId, BRIDGE_ADAPTER), - // true - // ); - // assertEq( - // crossChainReceiver.isTransactionReceivedByAdapter(txExtended.transactionId, BRIDGE_ADAPTER_2), - // true - // ); - // ICrossChainReceiver.TransactionStateWithoutAdapters - // memory internalTransactionState = crossChainReceiver.getTransactionState( - // txExtended.transactionId - // ); - // ICrossChainReceiver.EnvelopeState internalEnvelopeState = crossChainReceiver.getEnvelopeState( - // txExtended.envelopeId - // ); - - // // Confirmation of the message is GREATER compared to the required confirmations - // assertGt( - // internalTransactionState.confirmations, - // crossChainReceiver.getConfigurationByChain(DEFAULT_ORIGIN_CHAIN_ID).requiredConfirmation - // ); - // assertEq(internalTransactionState.confirmations, 2); - // assertEq(internalTransactionState.firstBridgedAt, block.timestamp); - // assertTrue(internalEnvelopeState == ICrossChainReceiver.EnvelopeState.Delivered); - // } + // TEST RECEIVE MESSAGES + function testReceiveCrossChainMessage(uint256 txNonce, uint256 envelopeNonce) public { + ExtendedTransaction memory txExtended = _generateExtendedTransaction( + TestParams({ + origin: GOVERNANCE_CORE, + destination: VOTING_MACHINE, + originChainId: DEFAULT_ORIGIN_CHAIN_ID, + destinationChainId: block.chainid, + envelopeNonce: envelopeNonce, + transactionNonce: txNonce + }) + ); + + hoax(BRIDGE_ADAPTER); + vm.mockCall( + txExtended.envelope.destination, + abi.encodeWithSelector(IBaseReceiverPortal.receiveCrossChainMessage.selector), + abi.encode() + ); + vm.expectCall( + txExtended.envelope.destination, + abi.encodeWithSelector( + IBaseReceiverPortal.receiveCrossChainMessage.selector, + txExtended.envelope.origin, + txExtended.envelope.originChainId, + txExtended.envelope.message + ) + ); + vm.expectEmit(true, true, true, true); + emit TransactionReceived( + txExtended.transactionId, + txExtended.envelopeId, + txExtended.envelope.originChainId, + txExtended.transaction, + BRIDGE_ADAPTER, + 1 + ); + vm.expectEmit(true, true, true, true); + emit EnvelopeDeliveryAttempted(txExtended.envelopeId, txExtended.envelope, true); + crossChainReceiver.receiveCrossChainMessage( + txExtended.transactionEncoded, + txExtended.envelope.originChainId + ); + + // check internal transaction + assertEq( + crossChainReceiver.isTransactionReceivedByAdapter(txExtended.transactionId, BRIDGE_ADAPTER), + true + ); + ICrossChainReceiver.TransactionStateWithoutAdapters + memory internalTransactionState = crossChainReceiver.getTransactionState( + txExtended.transactionId + ); + ICrossChainReceiver.EnvelopeState internalEnvelopeState = crossChainReceiver.getEnvelopeState( + txExtended.envelopeId + ); + + assertEq(internalTransactionState.confirmations, 1); + assertEq(internalTransactionState.firstBridgedAt, block.timestamp); + assertTrue(internalEnvelopeState == ICrossChainReceiver.EnvelopeState.Delivered); + } + + function testReceiveCrossChainMessageAfterConfirmation( + uint256 txNonce, + uint256 envelopeNonce + ) public { + ExtendedTransaction memory txExtended = _generateExtendedTransaction( + TestParams({ + origin: GOVERNANCE_CORE, + destination: VOTING_MACHINE, + originChainId: DEFAULT_ORIGIN_CHAIN_ID, + destinationChainId: block.chainid, + envelopeNonce: envelopeNonce, + transactionNonce: txNonce + }) + ); + + hoax(BRIDGE_ADAPTER); + vm.mockCall( + txExtended.envelope.destination, + abi.encodeWithSelector(IBaseReceiverPortal.receiveCrossChainMessage.selector), + abi.encode() + ); + vm.expectCall( + txExtended.envelope.destination, + abi.encodeWithSelector( + IBaseReceiverPortal.receiveCrossChainMessage.selector, + txExtended.envelope.origin, + txExtended.envelope.originChainId, + txExtended.envelope.message + ) + ); + vm.expectEmit(true, true, true, true); + emit TransactionReceived( + txExtended.transactionId, + txExtended.envelopeId, + txExtended.envelope.originChainId, + txExtended.transaction, + BRIDGE_ADAPTER, + 1 + ); + vm.expectEmit(true, true, true, true); + emit EnvelopeDeliveryAttempted(txExtended.envelopeId, txExtended.envelope, true); + crossChainReceiver.receiveCrossChainMessage( + txExtended.transactionEncoded, + txExtended.envelope.originChainId + ); + + // check internal transaction + assertEq( + crossChainReceiver.isTransactionReceivedByAdapter(txExtended.transactionId, BRIDGE_ADAPTER), + true + ); + ICrossChainReceiver.TransactionStateWithoutAdapters + memory internalTransactionState = crossChainReceiver.getTransactionState( + txExtended.transactionId + ); + ICrossChainReceiver.EnvelopeState internalEnvelopeState = crossChainReceiver.getEnvelopeState( + txExtended.envelopeId + ); + + assertEq(internalTransactionState.confirmations, 1); + assertEq(internalTransactionState.firstBridgedAt, block.timestamp); + assertTrue(internalEnvelopeState == ICrossChainReceiver.EnvelopeState.Delivered); + + // receive 2nd cross chain message after its already confirmed + hoax(BRIDGE_ADAPTER_2); + vm.expectEmit(true, true, true, true); + emit TransactionReceived( + txExtended.transactionId, + txExtended.envelopeId, + txExtended.envelope.originChainId, + txExtended.transaction, + BRIDGE_ADAPTER_2, + 2 + ); + crossChainReceiver.receiveCrossChainMessage( + txExtended.transactionEncoded, + txExtended.envelope.originChainId + ); + + // check internal transaction + assertEq( + crossChainReceiver.isTransactionReceivedByAdapter(txExtended.transactionId, BRIDGE_ADAPTER_2), + true + ); + internalTransactionState = crossChainReceiver.getTransactionState(txExtended.transactionId); + internalEnvelopeState = crossChainReceiver.getEnvelopeState(txExtended.envelopeId); + + assertEq(internalTransactionState.confirmations, 2); + assertEq(internalTransactionState.firstBridgedAt, block.timestamp); + assertTrue(internalEnvelopeState == ICrossChainReceiver.EnvelopeState.Delivered); + } + + function testReceiveCrossChainMessageAfterConfirmationsLowered() public { + // set initial needed confirmation to 2 + ICrossChainReceiver.ConfirmationInput memory confirmation = ICrossChainReceiver + .ConfirmationInput({chainId: 1, requiredConfirmations: 2}); + ICrossChainReceiver.ConfirmationInput[] + memory requiredConfirmations = new ICrossChainReceiver.ConfirmationInput[](1); + requiredConfirmations[0] = confirmation; + + vm.prank(OWNER); + crossChainReceiver.updateConfirmations(requiredConfirmations); + + ExtendedTransaction memory txExtended = _generateExtendedTransaction( + TestParams({ + origin: GOVERNANCE_CORE, + destination: VOTING_MACHINE, + originChainId: DEFAULT_ORIGIN_CHAIN_ID, + destinationChainId: block.chainid, + envelopeNonce: 0, + transactionNonce: 0 + }) + ); + + // receive first confirmation message + hoax(BRIDGE_ADAPTER); + vm.mockCall( + txExtended.envelope.destination, + abi.encodeWithSelector(IBaseReceiverPortal.receiveCrossChainMessage.selector), + abi.encode() + ); + vm.expectEmit(true, true, true, true); + emit TransactionReceived( + txExtended.transactionId, + txExtended.envelopeId, + txExtended.envelope.originChainId, + txExtended.transaction, + BRIDGE_ADAPTER, + 1 + ); + crossChainReceiver.receiveCrossChainMessage( + txExtended.transactionEncoded, + txExtended.envelope.originChainId + ); + + // lower required confirmations to 1 + requiredConfirmations[0] = ICrossChainReceiver.ConfirmationInput({ + chainId: txExtended.envelope.originChainId, + requiredConfirmations: 1 + }); + + vm.prank(OWNER); + crossChainReceiver.updateConfirmations(requiredConfirmations); + + // receive second confirmation message + hoax(BRIDGE_ADAPTER_2); + vm.mockCall( + txExtended.envelope.destination, + abi.encodeWithSelector(IBaseReceiverPortal.receiveCrossChainMessage.selector), + abi.encode() + ); + vm.expectCall( + txExtended.envelope.destination, + abi.encodeWithSelector( + IBaseReceiverPortal.receiveCrossChainMessage.selector, + txExtended.envelope.origin, + txExtended.envelope.originChainId, + txExtended.envelope.message + ) + ); + vm.expectEmit(true, true, true, true); + emit TransactionReceived( + txExtended.transactionId, + txExtended.envelopeId, + txExtended.envelope.originChainId, + txExtended.transaction, + BRIDGE_ADAPTER_2, + 2 + ); + + vm.expectEmit(true, true, false, true); + emit EnvelopeDeliveryAttempted(txExtended.envelopeId, txExtended.envelope, true); + crossChainReceiver.receiveCrossChainMessage( + txExtended.transactionEncoded, + txExtended.envelope.originChainId + ); + + // check internal message + assertEq( + crossChainReceiver.isTransactionReceivedByAdapter(txExtended.transactionId, BRIDGE_ADAPTER), + true + ); + assertEq( + crossChainReceiver.isTransactionReceivedByAdapter(txExtended.transactionId, BRIDGE_ADAPTER_2), + true + ); + ICrossChainReceiver.TransactionStateWithoutAdapters + memory internalTransactionState = crossChainReceiver.getTransactionState( + txExtended.transactionId + ); + ICrossChainReceiver.EnvelopeState internalEnvelopeState = crossChainReceiver.getEnvelopeState( + txExtended.envelopeId + ); + + // Confirmation of the message is GREATER compared to the required confirmations + assertGt( + internalTransactionState.confirmations, + crossChainReceiver.getConfigurationByChain(DEFAULT_ORIGIN_CHAIN_ID).requiredConfirmation + ); + assertEq(internalTransactionState.confirmations, 2); + assertEq(internalTransactionState.firstBridgedAt, block.timestamp); + assertTrue(internalEnvelopeState == ICrossChainReceiver.EnvelopeState.Delivered); + } function testReceiveCrossChainMessageWhenCallerNotBridge() public { ExtendedTransaction memory txExtended = _generateExtendedTransaction( @@ -655,124 +655,124 @@ contract CrossChainReceiverTest is BaseTest { ); } - // function testReceiveMessageButNotConfirmation() public { - // // set new adapter - // uint256[] memory chainIds = new uint256[](2); - // chainIds[0] = DEFAULT_ORIGIN_CHAIN_ID; - - // ICrossChainReceiver.ConfirmationInput[] - // memory requiredConfirmations = new ICrossChainReceiver.ConfirmationInput[](1); - - // // set initial needed confirmation to 2 - // ICrossChainReceiver.ConfirmationInput memory confirmation = ICrossChainReceiver - // .ConfirmationInput({chainId: DEFAULT_ORIGIN_CHAIN_ID, requiredConfirmations: 2}); - // requiredConfirmations[0] = confirmation; - - // ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] - // memory bridgeAdaptersToAllow = new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[](1); - // address newAdapter = address(101); - - // bridgeAdaptersToAllow[0] = ICrossChainReceiver.ReceiverBridgeAdapterConfigInput({ - // bridgeAdapter: newAdapter, - // chainIds: chainIds - // }); - - // vm.startPrank(OWNER); - // crossChainReceiver.allowReceiverBridgeAdapters(bridgeAdaptersToAllow); - // crossChainReceiver.updateConfirmations(requiredConfirmations); - // vm.stopPrank(); - - // ExtendedTransaction memory txExtended = _generateExtendedTransaction( - // TestParams({ - // origin: GOVERNANCE_CORE, - // destination: VOTING_MACHINE, - // originChainId: DEFAULT_ORIGIN_CHAIN_ID, - // destinationChainId: block.chainid, - // envelopeNonce: 0, - // transactionNonce: 0 - // }) - // ); - - // hoax(BRIDGE_ADAPTER); - // vm.expectEmit(true, true, true, true); - // emit TransactionReceived( - // txExtended.transactionId, - // txExtended.envelopeId, - // txExtended.envelope.originChainId, - // txExtended.transaction, - // BRIDGE_ADAPTER, - // 1 - // ); - // crossChainReceiver.receiveCrossChainMessage( - // txExtended.transactionEncoded, - // txExtended.envelope.originChainId - // ); - - // // check internal message - // assertEq( - // crossChainReceiver.isTransactionReceivedByAdapter(txExtended.transactionId, BRIDGE_ADAPTER), - // true - // ); - // ICrossChainReceiver.TransactionStateWithoutAdapters - // memory internalTransactionState = crossChainReceiver.getTransactionState( - // txExtended.transactionId - // ); - // ICrossChainReceiver.EnvelopeState internalEnvelopeState = crossChainReceiver.getEnvelopeState( - // txExtended.envelopeId - // ); - - // assertEq(internalTransactionState.confirmations, 1); - // assertEq(internalTransactionState.firstBridgedAt, block.timestamp); - // assertTrue(internalEnvelopeState == ICrossChainReceiver.EnvelopeState.None); - - // hoax(newAdapter); - // vm.mockCall( - // txExtended.envelope.destination, - // abi.encodeWithSelector(IBaseReceiverPortal.receiveCrossChainMessage.selector), - // abi.encode() - // ); - // vm.expectCall( - // txExtended.envelope.destination, - // abi.encodeWithSelector( - // IBaseReceiverPortal.receiveCrossChainMessage.selector, - // txExtended.envelope.origin, - // txExtended.envelope.originChainId, - // txExtended.envelope.message - // ) - // ); - // vm.expectEmit(true, true, true, true); - // emit TransactionReceived( - // txExtended.transactionId, - // txExtended.envelopeId, - // txExtended.envelope.originChainId, - // txExtended.transaction, - // newAdapter, - // 2 - // ); - // vm.expectEmit(true, true, true, true); - // emit EnvelopeDeliveryAttempted(txExtended.envelopeId, txExtended.envelope, true); - // crossChainReceiver.receiveCrossChainMessage( - // txExtended.transactionEncoded, - // txExtended.envelope.originChainId - // ); - - // // check internal message - // assertEq( - // crossChainReceiver.isTransactionReceivedByAdapter(txExtended.transactionId, newAdapter), - // true - // ); - // ICrossChainReceiver.TransactionStateWithoutAdapters - // memory internalTransactionState2 = crossChainReceiver.getTransactionState( - // txExtended.transactionId - // ); - // ICrossChainReceiver.EnvelopeState internalEnvelopeState2 = crossChainReceiver.getEnvelopeState( - // txExtended.envelopeId - // ); - - // assertEq(internalTransactionState2.confirmations, 2); - // assertEq(internalTransactionState2.firstBridgedAt, block.timestamp); - // assertTrue(internalEnvelopeState2 == ICrossChainReceiver.EnvelopeState.Delivered); - // } + function testReceiveMessageButNotConfirmation() public { + // set new adapter + uint256[] memory chainIds = new uint256[](2); + chainIds[0] = DEFAULT_ORIGIN_CHAIN_ID; + + ICrossChainReceiver.ConfirmationInput[] + memory requiredConfirmations = new ICrossChainReceiver.ConfirmationInput[](1); + + // set initial needed confirmation to 2 + ICrossChainReceiver.ConfirmationInput memory confirmation = ICrossChainReceiver + .ConfirmationInput({chainId: DEFAULT_ORIGIN_CHAIN_ID, requiredConfirmations: 2}); + requiredConfirmations[0] = confirmation; + + ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] + memory bridgeAdaptersToAllow = new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[](1); + address newAdapter = address(101); + + bridgeAdaptersToAllow[0] = ICrossChainReceiver.ReceiverBridgeAdapterConfigInput({ + bridgeAdapter: newAdapter, + chainIds: chainIds + }); + + vm.startPrank(OWNER); + crossChainReceiver.allowReceiverBridgeAdapters(bridgeAdaptersToAllow); + crossChainReceiver.updateConfirmations(requiredConfirmations); + vm.stopPrank(); + + ExtendedTransaction memory txExtended = _generateExtendedTransaction( + TestParams({ + origin: GOVERNANCE_CORE, + destination: VOTING_MACHINE, + originChainId: DEFAULT_ORIGIN_CHAIN_ID, + destinationChainId: block.chainid, + envelopeNonce: 0, + transactionNonce: 0 + }) + ); + + hoax(BRIDGE_ADAPTER); + vm.expectEmit(true, true, true, true); + emit TransactionReceived( + txExtended.transactionId, + txExtended.envelopeId, + txExtended.envelope.originChainId, + txExtended.transaction, + BRIDGE_ADAPTER, + 1 + ); + crossChainReceiver.receiveCrossChainMessage( + txExtended.transactionEncoded, + txExtended.envelope.originChainId + ); + + // check internal message + assertEq( + crossChainReceiver.isTransactionReceivedByAdapter(txExtended.transactionId, BRIDGE_ADAPTER), + true + ); + ICrossChainReceiver.TransactionStateWithoutAdapters + memory internalTransactionState = crossChainReceiver.getTransactionState( + txExtended.transactionId + ); + ICrossChainReceiver.EnvelopeState internalEnvelopeState = crossChainReceiver.getEnvelopeState( + txExtended.envelopeId + ); + + assertEq(internalTransactionState.confirmations, 1); + assertEq(internalTransactionState.firstBridgedAt, block.timestamp); + assertTrue(internalEnvelopeState == ICrossChainReceiver.EnvelopeState.None); + + hoax(newAdapter); + vm.mockCall( + txExtended.envelope.destination, + abi.encodeWithSelector(IBaseReceiverPortal.receiveCrossChainMessage.selector), + abi.encode() + ); + vm.expectCall( + txExtended.envelope.destination, + abi.encodeWithSelector( + IBaseReceiverPortal.receiveCrossChainMessage.selector, + txExtended.envelope.origin, + txExtended.envelope.originChainId, + txExtended.envelope.message + ) + ); + vm.expectEmit(true, true, true, true); + emit TransactionReceived( + txExtended.transactionId, + txExtended.envelopeId, + txExtended.envelope.originChainId, + txExtended.transaction, + newAdapter, + 2 + ); + vm.expectEmit(true, true, true, true); + emit EnvelopeDeliveryAttempted(txExtended.envelopeId, txExtended.envelope, true); + crossChainReceiver.receiveCrossChainMessage( + txExtended.transactionEncoded, + txExtended.envelope.originChainId + ); + + // check internal message + assertEq( + crossChainReceiver.isTransactionReceivedByAdapter(txExtended.transactionId, newAdapter), + true + ); + ICrossChainReceiver.TransactionStateWithoutAdapters + memory internalTransactionState2 = crossChainReceiver.getTransactionState( + txExtended.transactionId + ); + ICrossChainReceiver.EnvelopeState internalEnvelopeState2 = crossChainReceiver.getEnvelopeState( + txExtended.envelopeId + ); + + assertEq(internalTransactionState2.confirmations, 2); + assertEq(internalTransactionState2.firstBridgedAt, block.timestamp); + assertTrue(internalEnvelopeState2 == ICrossChainReceiver.EnvelopeState.Delivered); + } // TEST INVALIDATIONS function testInvalidatePreviousMessages() public {