-
Probably a noob question but I'm trying to understand and learn. Uncovered for src/Raffle.sol:
- Branch (branch: 3, path: 0) (location: source ID 44, line 124, chars 5107-5163, hits: 0)
- Line (location: source ID 44, line 125, chars 5121-5152, hits: 0)
- Statement (location: source ID 44, line 125, chars 5121-5152, hits: 0) which leads me to this conditional: (bool success,) = recentWinner.call{value: address(this).balance}("");
if (!success) {
revert Raffle__TransferFailed();
} Is there a way to check if Raffle__TransferFailed is indeed the error triggered? this is what I tried so far contract RevertOnReceive {
receive() external payable {
revert("Forced failure");
}
}
function testFulfillRandomWordsTransferFailureBranch() public skipFork {
// Arrange
RevertOnReceive player = new RevertOnReceive();
hoax(address(player), 1 ether);
raffle.enterRaffle{value: 1 ether}();
vm.warp(block.timestamp + interval + 1);
vm.roll(block.number + 1);
// Perform upkeep to emit a requestId
vm.recordLogs();
raffle.performUpkeep("");
Vm.Log[] memory entries = vm.getRecordedLogs();
bytes32 requestId = entries[1].topics[1];
vm.expectRevert(Raffle__TransferFailed.selector);
// Act
VRFCoordinatorV2_5Mock(vrfCoordinator).fulfillRandomWords(uint256(requestId), address(raffle));
// Assert: The player's balance should remain unchanged
assertEq(address(player).balance, 0 ether);
} this fails: [352418] RaffleTest::testFulfillRandomWordsTransferFailureBranch()
├─ [25675] → new RevertOnReceive@0x2e234DAe75C793f67A35089C9d99245E1C58470b
│ └─ ← [Return] 128 bytes of code
├─ [0] VM::deal(RevertOnReceive: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], 1000000000000000000 [1e18])
│ └─ ← [Return]
├─ [0] VM::prank(RevertOnReceive: [0x2e234DAe75C793f67A35089C9d99245E1C58470b])
│ └─ ← [Return]
├─ [47827] Raffle::enterRaffle{value: 1000000000000000000}()
│ ├─ emit RaffleEntered(player: RevertOnReceive: [0x2e234DAe75C793f67A35089C9d99245E1C58470b])
│ └─ ← [Stop]
├─ [0] VM::warp(32)
│ └─ ← [Return]
├─ [0] VM::roll(2)
│ └─ ← [Return]
├─ [0] VM::recordLogs()
│ └─ ← [Return]
├─ [146059] Raffle::performUpkeep(0x)
│ ├─ [115645] VRFCoordinatorV2_5Mock::requestRandomWords(RandomWordsRequest({ keyHash: 0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae, subId: 7570848181127581986339189052072122886913734678723205985508750752041200654908 [7.57e75], requestConfirmations: 3, callbackGasLimit: 500000 [5e5], numWords: 1, extraArgs: 0x92fd13380000000000000000000000000000000000000000000000000000000000000000 }))
│ │ ├─ emit RandomWordsRequested(keyHash: 0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae, requestId: 1, preSeed: 100, subId: 7570848181127581986339189052072122886913734678723205985508750752041200654908 [7.57e75], minimumRequestConfirmations: 3, callbackGasLimit: 500000 [5e5], numWords: 1, extraArgs: 0x92fd13380000000000000000000000000000000000000000000000000000000000000000, sender: Raffle: [0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76])
│ │ └─ ← [Return] 1
│ ├─ emit RequestedRaffleWinner(requestId: 1)
│ └─ ← [Stop]
├─ [0] VM::getRecordedLogs()
│ └─ ← [Return] [([0xeb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e, 0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae, 0x10bcf2be64c261e434a6014656bea8260621c8940cfe977cd11416455f3a1a3c, 0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76], 0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000002492fd1338000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 0x34A1D3fff3958843C43aD80F30b94c510645C316), ([0xcd6e45c8998311cab7e9d4385596cac867e20a0587194b954fa3a731c93ce78b, 0x0000000000000000000000000000000000000000000000000000000000000001], 0x, 0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76)]
├─ [0] VM::expectRevert(custom error 0xf4844814)
│ └─ ← [Return]
├─ [73764] VRFCoordinatorV2_5Mock::fulfillRandomWords(1, Raffle: [0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76])
│ ├─ [16561] Raffle::rawFulfillRandomWords(1, [78541660797044910968829902406342334108369226379826116161446442989268089806461 [7.854e76]])
│ │ ├─ emit WinnerPicked(winner: RevertOnReceive: [0x2e234DAe75C793f67A35089C9d99245E1C58470b])
│ │ ├─ [144] RevertOnReceive::receive{value: 1000000000000000000}()
│ │ │ └─ ← [Revert] revert: Forced failure
│ │ ├─ [0] console::log("Transfer failed", false) [staticcall]
│ │ │ └─ ← [Stop]
│ │ └─ ← [Revert] Raffle__TransferFailed()
│ ├─ emit RandomWordsFulfilled(requestId: 1, outputSeed: 1, subId: 7570848181127581986339189052072122886913734678723205985508750752041200654908 [7.57e75], payment: 62510145000000000000 [6.251e19], nativePayment: false, success: false, onlyPremium: false)
│ └─ ← [Stop]
└─ ← [Revert] next call did not revert as expected
Suite result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 2.32ms (187.60µs CPU time)
Ran 1 test suite in 912.37ms (2.32ms CPU time): 0 tests passed, 1 failed, 0 skipped (1 total tests)
Failing tests:
Encountered 1 failing test in test/unit/RaffleTest.t.sol:RaffleTest
[FAIL: next call did not revert as expected] testFulfillRandomWordsTransferFailureBranch() (gas: 352418) If I don't expectRevert it obviously pass and shows that indeed the error reverts and that the player balance did not change. contract RevertOnReceive {
receive() external payable {
revert("Forced failure");
}
}
function testFulfillRandomWordsTransferFailureBranch() public skipFork {
// Arrange
RevertOnReceive player = new RevertOnReceive();
hoax(address(player), 1 ether);
raffle.enterRaffle{value: 1 ether}();
vm.warp(block.timestamp + interval + 1);
vm.roll(block.number + 1);
// Perform upkeep to emit a requestId
vm.recordLogs();
raffle.performUpkeep("");
Vm.Log[] memory entries = vm.getRecordedLogs();
bytes32 requestId = entries[1].topics[1];
// Act
VRFCoordinatorV2_5Mock(vrfCoordinator).fulfillRandomWords(uint256(requestId), address(raffle));
// Assert: The player's balance should remain unchanged
assertEq(address(player).balance, 0 ether);
} [352585] RaffleTest::testFulfillRandomWordsTransferFailureBranch()
├─ [25675] → new RevertOnReceive@0x2e234DAe75C793f67A35089C9d99245E1C58470b
│ └─ ← [Return] 128 bytes of code
├─ [0] VM::deal(RevertOnReceive: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], 1000000000000000000 [1e18])
│ └─ ← [Return]
├─ [0] VM::prank(RevertOnReceive: [0x2e234DAe75C793f67A35089C9d99245E1C58470b])
│ └─ ← [Return]
├─ [47827] Raffle::enterRaffle{value: 1000000000000000000}()
│ ├─ emit RaffleEntered(player: RevertOnReceive: [0x2e234DAe75C793f67A35089C9d99245E1C58470b])
│ └─ ← [Stop]
├─ [0] VM::warp(32)
│ └─ ← [Return]
├─ [0] VM::roll(2)
│ └─ ← [Return]
├─ [0] VM::recordLogs()
│ └─ ← [Return]
├─ [146059] Raffle::performUpkeep(0x)
│ ├─ [115645] VRFCoordinatorV2_5Mock::requestRandomWords(RandomWordsRequest({ keyHash: 0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae, subId: 7570848181127581986339189052072122886913734678723205985508750752041200654908 [7.57e75], requestConfirmations: 3, callbackGasLimit: 500000 [5e5], numWords: 1, extraArgs: 0x92fd13380000000000000000000000000000000000000000000000000000000000000000 }))
│ │ ├─ emit RandomWordsRequested(keyHash: 0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae, requestId: 1, preSeed: 100, subId: 7570848181127581986339189052072122886913734678723205985508750752041200654908 [7.57e75], minimumRequestConfirmations: 3, callbackGasLimit: 500000 [5e5], numWords: 1, extraArgs: 0x92fd13380000000000000000000000000000000000000000000000000000000000000000, sender: Raffle: [0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76])
│ │ └─ ← [Return] 1
│ ├─ emit RequestedRaffleWinner(requestId: 1)
│ └─ ← [Stop]
├─ [0] VM::getRecordedLogs()
│ └─ ← [Return] [([0xeb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e, 0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae, 0x10bcf2be64c261e434a6014656bea8260621c8940cfe977cd11416455f3a1a3c, 0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76], 0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000002492fd1338000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 0x34A1D3fff3958843C43aD80F30b94c510645C316), ([0xcd6e45c8998311cab7e9d4385596cac867e20a0587194b954fa3a731c93ce78b, 0x0000000000000000000000000000000000000000000000000000000000000001], 0x, 0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76)]
├─ [73764] VRFCoordinatorV2_5Mock::fulfillRandomWords(1, Raffle: [0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76])
│ ├─ [16561] Raffle::rawFulfillRandomWords(1, [78541660797044910968829902406342334108369226379826116161446442989268089806461 [7.854e76]])
│ │ ├─ emit WinnerPicked(winner: RevertOnReceive: [0x2e234DAe75C793f67A35089C9d99245E1C58470b])
│ │ ├─ [144] RevertOnReceive::receive{value: 1000000000000000000}()
│ │ │ └─ ← [Revert] revert: Forced failure
│ │ ├─ [0] console::log("Transfer failed", false) [staticcall]
│ │ │ └─ ← [Stop]
│ │ └─ ← [Revert] Raffle__TransferFailed()
│ ├─ emit RandomWordsFulfilled(requestId: 1, outputSeed: 1, subId: 7570848181127581986339189052072122886913734678723205985508750752041200654908 [7.57e75], payment: 62510145000000000000 [6.251e19], nativePayment: false, success: false, onlyPremium: false)
│ └─ ← [Stop]
├─ [0] VM::assertEq(0, 0) [staticcall]
│ └─ ← [Return]
└─ ← [Stop]
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 7.35ms (513.57µs CPU time) To me it looks strange that after the Raffle__TransferFailed() reverts, RandomWordsFullfilled gets emitted. Is this happening because |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
The test is failing because the vm.expectRevert() is placed on the call to VRFCoordinatorV2_5Mock::fulfillRandomWords, which does not revert even though the inner Raffle function does. The mock coordinator catches the revert from the Raffle contract and emits an event indicating failure, but does not propagate the revert. Thus, the outer call doesn't revert, causing the test's revert expectation to fail. |
Beta Was this translation helpful? Give feedback.
The test is failing because the vm.expectRevert() is placed on the call to VRFCoordinatorV2_5Mock::fulfillRandomWords, which does not revert even though the inner Raffle function does. The mock coordinator catches the revert from the Raffle contract and emits an event indicating failure, but does not propagate the revert. Thus, the outer call doesn't revert, causing the test's revert expectation to fail.