Commit 8a728cf7 authored by Michael Amadi's avatar Michael Amadi Committed by GitHub

Sc/improve optimismportal test cov (#12962)

* improve optimismportal(2) test coverage

* improve optimismportal(2) test coverage

* more tests, fixes
parent 39c3b5b6
...@@ -1006,7 +1006,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is CommonTest { ...@@ -1006,7 +1006,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is CommonTest {
) )
); );
uint256 bobBalanceBefore = address(bob).balance; // Fund the portal so that we can withdraw ETH.
vm.store(address(optimismPortal), bytes32(uint256(61)), bytes32(uint256(0xFFFFFFFF)));
vm.deal(address(optimismPortal), 0xFFFFFFFF);
uint256 bobBalanceBefore = bob.balance;
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash_noData, alice, bob); emit WithdrawalProven(_withdrawalHash_noData, alice, bob);
...@@ -1019,7 +1022,69 @@ contract OptimismPortal_FinalizeWithdrawal_Test is CommonTest { ...@@ -1019,7 +1022,69 @@ contract OptimismPortal_FinalizeWithdrawal_Test is CommonTest {
emit WithdrawalFinalized(_withdrawalHash_noData, true); emit WithdrawalFinalized(_withdrawalHash_noData, true);
optimismPortal.finalizeWithdrawalTransaction(_defaultTx_noData); optimismPortal.finalizeWithdrawalTransaction(_defaultTx_noData);
assertEq(address(bob).balance, bobBalanceBefore + 100); assertEq(bob.balance, bobBalanceBefore + 100);
}
/// @dev Tests that `finalizeWithdrawalTransaction` succeeds when _tx.data is empty and with a custom gas token.
function test_finalizeWithdrawalTransaction_noTxDataNonEtherGasToken_succeeds() external {
Types.WithdrawalTransaction memory _defaultTx_noData = Types.WithdrawalTransaction({
nonce: 0,
sender: alice,
target: bob,
value: 100,
gasLimit: 100_000,
data: hex""
});
// Get withdrawal proof data we can use for testing.
(
bytes32 _stateRoot_noData,
bytes32 _storageRoot_noData,
bytes32 _outputRoot_noData,
bytes32 _withdrawalHash_noData,
bytes[] memory _withdrawalProof_noData
) = ffi.getProveWithdrawalTransactionInputs(_defaultTx_noData);
// Setup a dummy output root proof for reuse.
Types.OutputRootProof memory _outputRootProof_noData = Types.OutputRootProof({
version: bytes32(uint256(0)),
stateRoot: _stateRoot_noData,
messagePasserStorageRoot: _storageRoot_noData,
latestBlockhash: bytes32(uint256(0))
});
// Configure the oracle to return the output root we've prepared.
vm.mockCall(
address(l2OutputOracle),
abi.encodePacked(IL2OutputOracle.getL2Output.selector),
abi.encode(
Types.OutputProposal(
_outputRoot_noData,
l2OutputOracle.getL2Output(_proposedOutputIndex).timestamp,
uint128(_proposedBlockNumber)
)
)
);
// Fund the portal so that we can withdraw ETH.
vm.store(address(optimismPortal), bytes32(uint256(61)), bytes32(uint256(0xFFFFFFFF)));
deal(address(L1Token), address(optimismPortal), 0xFFFFFFFF);
// modify the gas token to be non ether
vm.mockCall(
address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(L1Token), 18)
);
uint256 bobBalanceBefore = L1Token.balanceOf(bob);
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash_noData, alice, bob);
optimismPortal.proveWithdrawalTransaction(
_defaultTx_noData, _proposedOutputIndex, _outputRootProof_noData, _withdrawalProof_noData
);
vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectEmit(true, true, false, true);
emit WithdrawalFinalized(_withdrawalHash_noData, true);
optimismPortal.finalizeWithdrawalTransaction(_defaultTx_noData);
assertEq(L1Token.balanceOf(bob), bobBalanceBefore + 100);
} }
/// @dev Tests that `finalizeWithdrawalTransaction` reverts if the finalization period /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the finalization period
......
...@@ -802,6 +802,169 @@ contract OptimismPortal2_FinalizeWithdrawal_Test is CommonTest { ...@@ -802,6 +802,169 @@ contract OptimismPortal2_FinalizeWithdrawal_Test is CommonTest {
assert(address(bob).balance == bobBalanceBefore + 100); assert(address(bob).balance == bobBalanceBefore + 100);
} }
/// @dev Tests that `finalizeWithdrawalTransaction` reverts if the target reverts and caller is the
/// ESTIMATION_ADDRESS.
function test_finalizeWithdrawalTransaction_targetFailsAndCallerIsEstimationAddress_reverts() external {
vm.etch(bob, hex"fe"); // Contract with just the invalid opcode.
vm.prank(alice);
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
optimismPortal2.proveWithdrawalTransaction(_defaultTx, _proposedGameIndex, _outputRootProof, _withdrawalProof);
// Warp and resolve the dispute game.
game.resolveClaim(0, 0);
game.resolve();
vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1 seconds);
vm.startPrank(alice, Constants.ESTIMATION_ADDRESS);
vm.expectRevert(GasEstimation.selector);
optimismPortal2.finalizeWithdrawalTransaction(_defaultTx);
}
/// @dev Tests that `finalizeWithdrawalTransaction` succeeds when _tx.data is empty.
function test_finalizeWithdrawalTransaction_noTxData_succeeds() external {
Types.WithdrawalTransaction memory _defaultTx_noData = Types.WithdrawalTransaction({
nonce: 0,
sender: alice,
target: bob,
value: 100,
gasLimit: 100_000,
data: hex""
});
// Get withdrawal proof data we can use for testing.
(
bytes32 _stateRoot_noData,
bytes32 _storageRoot_noData,
bytes32 _outputRoot_noData,
bytes32 _withdrawalHash_noData,
bytes[] memory _withdrawalProof_noData
) = ffi.getProveWithdrawalTransactionInputs(_defaultTx_noData);
// Setup a dummy output root proof for reuse.
Types.OutputRootProof memory _outputRootProof_noData = Types.OutputRootProof({
version: bytes32(uint256(0)),
stateRoot: _stateRoot_noData,
messagePasserStorageRoot: _storageRoot_noData,
latestBlockhash: bytes32(uint256(0))
});
uint256 _proposedBlockNumber_noData = 0xFF;
IFaultDisputeGame game_noData = IFaultDisputeGame(
payable(
address(
disputeGameFactory.create(
optimismPortal2.respectedGameType(),
Claim.wrap(_outputRoot_noData),
abi.encode(_proposedBlockNumber_noData)
)
)
)
);
uint256 _proposedGameIndex_noData = disputeGameFactory.gameCount() - 1;
// Warp beyond the chess clocks and finalize the game.
vm.warp(block.timestamp + game_noData.maxClockDuration().raw() + 1 seconds);
// Fund the portal so that we can withdraw ETH.
vm.store(address(optimismPortal2), bytes32(uint256(61)), bytes32(uint256(0xFFFFFFFF)));
vm.deal(address(optimismPortal2), 0xFFFFFFFF);
uint256 bobBalanceBefore = bob.balance;
vm.expectEmit(address(optimismPortal2));
emit WithdrawalProven(_withdrawalHash_noData, alice, bob);
vm.expectEmit(address(optimismPortal2));
emit WithdrawalProvenExtension1(_withdrawalHash_noData, address(this));
optimismPortal2.proveWithdrawalTransaction({
_tx: _defaultTx_noData,
_disputeGameIndex: _proposedGameIndex_noData,
_outputRootProof: _outputRootProof_noData,
_withdrawalProof: _withdrawalProof_noData
});
// Warp and resolve the dispute game.
game_noData.resolveClaim(0, 0);
game_noData.resolve();
vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1 seconds);
vm.expectEmit(true, true, false, true);
emit WithdrawalFinalized(_withdrawalHash_noData, true);
optimismPortal2.finalizeWithdrawalTransaction(_defaultTx_noData);
assert(bob.balance == bobBalanceBefore + 100);
}
/// @dev Tests that `finalizeWithdrawalTransaction` succeeds when _tx.data is empty and with a custom gas token.
function test_finalizeWithdrawalTransaction_noTxDataNonEtherGasToken_succeeds() external {
Types.WithdrawalTransaction memory _defaultTx_noData = Types.WithdrawalTransaction({
nonce: 0,
sender: alice,
target: bob,
value: 100,
gasLimit: 100_000,
data: hex""
});
// Get withdrawal proof data we can use for testing.
(
bytes32 _stateRoot_noData,
bytes32 _storageRoot_noData,
bytes32 _outputRoot_noData,
bytes32 _withdrawalHash_noData,
bytes[] memory _withdrawalProof_noData
) = ffi.getProveWithdrawalTransactionInputs(_defaultTx_noData);
// Setup a dummy output root proof for reuse.
Types.OutputRootProof memory _outputRootProof_noData = Types.OutputRootProof({
version: bytes32(uint256(0)),
stateRoot: _stateRoot_noData,
messagePasserStorageRoot: _storageRoot_noData,
latestBlockhash: bytes32(uint256(0))
});
uint256 _proposedBlockNumber_noData = 0xFF;
IFaultDisputeGame game_noData = IFaultDisputeGame(
payable(
address(
disputeGameFactory.create(
optimismPortal2.respectedGameType(),
Claim.wrap(_outputRoot_noData),
abi.encode(_proposedBlockNumber_noData)
)
)
)
);
uint256 _proposedGameIndex_noData = disputeGameFactory.gameCount() - 1;
// Warp beyond the chess clocks and finalize the game.
vm.warp(block.timestamp + game_noData.maxClockDuration().raw() + 1 seconds);
// Fund the portal so that we can withdraw ETH.
vm.store(address(optimismPortal2), bytes32(uint256(61)), bytes32(uint256(0xFFFFFFFF)));
deal(address(L1Token), address(optimismPortal2), 0xFFFFFFFF);
// modify the gas token to be non ether
vm.mockCall(
address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(L1Token), 18)
);
uint256 bobBalanceBefore = L1Token.balanceOf(bob);
vm.expectEmit(address(optimismPortal2));
emit WithdrawalProven(_withdrawalHash_noData, alice, bob);
vm.expectEmit(address(optimismPortal2));
emit WithdrawalProvenExtension1(_withdrawalHash_noData, address(this));
optimismPortal2.proveWithdrawalTransaction({
_tx: _defaultTx_noData,
_disputeGameIndex: _proposedGameIndex_noData,
_outputRootProof: _outputRootProof_noData,
_withdrawalProof: _withdrawalProof_noData
});
// Warp and resolve the dispute game.
game_noData.resolveClaim(0, 0);
game_noData.resolve();
vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1 seconds);
vm.expectEmit(true, true, false, true);
emit WithdrawalFinalized(_withdrawalHash_noData, true);
optimismPortal2.finalizeWithdrawalTransaction(_defaultTx_noData);
assert(L1Token.balanceOf(bob) == bobBalanceBefore + 100);
}
/// @dev Tests that `finalizeWithdrawalTransaction` succeeds. /// @dev Tests that `finalizeWithdrawalTransaction` succeeds.
function test_finalizeWithdrawalTransaction_provenWithdrawalHashEther_succeeds() external { function test_finalizeWithdrawalTransaction_provenWithdrawalHashEther_succeeds() external {
uint256 bobBalanceBefore = address(bob).balance; uint256 bobBalanceBefore = address(bob).balance;
...@@ -1575,7 +1738,7 @@ contract OptimismPortal2WithMockERC20_Test is OptimismPortal2_FinalizeWithdrawal ...@@ -1575,7 +1738,7 @@ contract OptimismPortal2WithMockERC20_Test is OptimismPortal2_FinalizeWithdrawal
); );
// Deposit the token into the portal // Deposit the token into the portal
optimismPortal.depositERC20Transaction(_to, _mint, _value, _gasLimit, _isCreation, _data); optimismPortal2.depositERC20Transaction(_to, _mint, _value, _gasLimit, _isCreation, _data);
// Assert final balance equals the deposited amount // Assert final balance equals the deposited amount
assertEq(token.balanceOf(address(optimismPortal2)), _mint); assertEq(token.balanceOf(address(optimismPortal2)), _mint);
...@@ -1657,7 +1820,7 @@ contract OptimismPortal2WithMockERC20_Test is OptimismPortal2_FinalizeWithdrawal ...@@ -1657,7 +1820,7 @@ contract OptimismPortal2WithMockERC20_Test is OptimismPortal2_FinalizeWithdrawal
); );
// Mock the token balance // Mock the token balance
vm.mockCall(address(token), abi.encodeCall(token.balanceOf, (address(optimismPortal))), abi.encode(0)); vm.mockCall(address(token), abi.encodeCall(token.balanceOf, (address(optimismPortal2))), abi.encode(0));
// Call minimumGasLimit(0) before vm.expectRevert to ensure vm.expectRevert is for depositERC20Transaction // Call minimumGasLimit(0) before vm.expectRevert to ensure vm.expectRevert is for depositERC20Transaction
uint64 gasLimit = optimismPortal2.minimumGasLimit(0); uint64 gasLimit = optimismPortal2.minimumGasLimit(0);
...@@ -1723,7 +1886,7 @@ contract OptimismPortal2WithMockERC20_Test is OptimismPortal2_FinalizeWithdrawal ...@@ -1723,7 +1886,7 @@ contract OptimismPortal2WithMockERC20_Test is OptimismPortal2_FinalizeWithdrawal
); );
// Deposit the token into the portal // Deposit the token into the portal
optimismPortal2.depositERC20Transaction(address(0), _amount, 0, optimismPortal.minimumGasLimit(0), false, ""); optimismPortal2.depositERC20Transaction(address(0), _amount, 0, optimismPortal2.minimumGasLimit(0), false, "");
// Check that the balance has been correctly updated // Check that the balance has been correctly updated
assertEq(optimismPortal2.balance(), _amount); assertEq(optimismPortal2.balance(), _amount);
...@@ -1742,7 +1905,7 @@ contract OptimismPortal2WithMockERC20_Test is OptimismPortal2_FinalizeWithdrawal ...@@ -1742,7 +1905,7 @@ contract OptimismPortal2WithMockERC20_Test is OptimismPortal2_FinalizeWithdrawal
// Deposit the token into the portal // Deposit the token into the portal
optimismPortal2.depositERC20Transaction( optimismPortal2.depositERC20Transaction(
address(bob), _defaultTx.value, 0, optimismPortal.minimumGasLimit(0), false, "" address(bob), _defaultTx.value, 0, optimismPortal2.minimumGasLimit(0), false, ""
); );
assertEq(optimismPortal2.balance(), _defaultTx.value); assertEq(optimismPortal2.balance(), _defaultTx.value);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment