Commit dae569e1 authored by smartcontracts's avatar smartcontracts Committed by Adrian Sutton

fix: no squeezing unfinalized proposals (#257)

* fix: no squeezing unfinalized proposals

Updates the PreimageOracle to correctly revert if a proposal has
not actually been finalized. This fixes a bug because the timestamp
is not set until after a proposal is finalized but all other
conditions in the squeeze function are met even before addLeaves
is called with the finalize boolean set.

* fix: ci checks

* fix: semver lock

---------
Co-authored-by: default avatarrefcell <abigger87@gmail.com>
parent 705c5a14
...@@ -148,8 +148,8 @@ ...@@ -148,8 +148,8 @@
"sourceCodeHash": "0x115bd6a4c4d77ed210dfd468675b409fdae9f79b932063c138f0765ba9063462" "sourceCodeHash": "0x115bd6a4c4d77ed210dfd468675b409fdae9f79b932063c138f0765ba9063462"
}, },
"src/cannon/PreimageOracle.sol": { "src/cannon/PreimageOracle.sol": {
"initCodeHash": "0x274a82a7df1bfe30b23bdd9ece61ae8ef0429ea346bd4e462e233a3d4953bce5", "initCodeHash": "0x3b89440c73c7da079257f38a9da237fef199755c0e31578889ebd55e3f963aef",
"sourceCodeHash": "0x566e557b64d2df3425373514e112d0813326013b35b387e08c027cc052636ee1" "sourceCodeHash": "0x6889891526f82ec0c68561ac0803da0ee995f737844ad2b7acfdac0b41ff789e"
}, },
"src/dispute/AnchorStateRegistry.sol": { "src/dispute/AnchorStateRegistry.sol": {
"initCodeHash": "0x0305c21e50829b9e07d43358d8c2c82f1449534c90d4391400d46e76d0503a49", "initCodeHash": "0x0305c21e50829b9e07d43358d8c2c82f1449534c90d4391400d46e76d0503a49",
......
...@@ -508,7 +508,7 @@ contract PreimageOracle is IPreimageOracle, ISemver { ...@@ -508,7 +508,7 @@ contract PreimageOracle is IPreimageOracle, ISemver {
let inputPtr := add(input, 0x20) let inputPtr := add(input, 0x20)
// The input length must be a multiple of 136 bytes // The input length must be a multiple of 136 bytes
// The input lenth / 136 must be equal to the number of state commitments. // The input length / 136 must be equal to the number of state commitments.
if or(mod(inputLen, 136), iszero(eq(_stateCommitments.length, div(inputLen, 136)))) { if or(mod(inputLen, 136), iszero(eq(_stateCommitments.length, div(inputLen, 136)))) {
// Store "InvalidInputSize()" error selector // Store "InvalidInputSize()" error selector
mstore(0x00, 0x7b1daf1) mstore(0x00, 0x7b1daf1)
...@@ -677,6 +677,9 @@ contract PreimageOracle is IPreimageOracle, ISemver { ...@@ -677,6 +677,9 @@ contract PreimageOracle is IPreimageOracle, ISemver {
// Check if the proposal was countered. // Check if the proposal was countered.
if (metaData.countered()) revert BadProposal(); if (metaData.countered()) revert BadProposal();
// Check if the proposal has been finalized at all.
if (metaData.timestamp() == 0) revert ActiveProposal();
// Check if the challenge period has passed since the proposal was finalized. // Check if the challenge period has passed since the proposal was finalized.
if (block.timestamp - metaData.timestamp() <= CHALLENGE_PERIOD) revert ActiveProposal(); if (block.timestamp - metaData.timestamp() <= CHALLENGE_PERIOD) revert ActiveProposal();
......
...@@ -640,6 +640,63 @@ contract PreimageOracle_LargePreimageProposals_Test is Test { ...@@ -640,6 +640,63 @@ contract PreimageOracle_LargePreimageProposals_Test is Test {
}); });
} }
/// @notice Tests that a proposal cannot be squeezed if the proposal has not been finalized.
function test_squeeze_notFinalized_reverts() public {
// Allocate the preimage data.
bytes memory data = new bytes(136);
for (uint256 i; i < data.length; i++) {
data[i] = 0xFF;
}
// Initialize the proposal.
oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length));
// Generate the padded input data.
// Since the data is 136 bytes, which is exactly one keccak block, we will add one extra
// keccak block of empty padding to the input data. We need to do this here because the
// addLeavesLPP function will normally perform this padding internally when _finalize is
// set to true but we're explicitly testing the case where _finalize is not true.
bytes memory paddedData = new bytes(136 * 2);
for (uint256 i; i < data.length; i++) {
paddedData[i] = data[i];
}
// Add the leaves to the tree (2 keccak blocks.)
LibKeccak.StateMatrix memory stateMatrix;
bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data);
oracle.addLeavesLPP(TEST_UUID, 0, paddedData, stateCommitments, false);
// Construct the leaf preimage data for the blocks added.
LibKeccak.StateMatrix memory matrix;
PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrix, data);
// Create a proof array with 16 elements.
bytes32[] memory preProof = new bytes32[](16);
preProof[0] = _hashLeaf(leaves[1]);
bytes32[] memory postProof = new bytes32[](16);
postProof[0] = _hashLeaf(leaves[0]);
for (uint256 i = 1; i < preProof.length; i++) {
bytes32 zeroHash = oracle.zeroHashes(i);
preProof[i] = zeroHash;
postProof[i] = zeroHash;
}
// Warp past the challenge period.
vm.warp(block.timestamp + oracle.challengePeriod() + 1 seconds);
// Finalize the proposal.
vm.expectRevert(ActiveProposal.selector);
oracle.squeezeLPP({
_claimant: address(this),
_uuid: TEST_UUID,
_stateMatrix: _stateMatrixAtBlockIndex(data, 1),
_preState: leaves[0],
_preStateProof: preProof,
_postState: leaves[1],
_postStateProof: postProof
});
}
/// @notice Tests that a proposal cannot be finalized until it has passed the challenge period. /// @notice Tests that a proposal cannot be finalized until it has passed the challenge period.
function test_squeeze_challengePeriodActive_reverts() public { function test_squeeze_challengePeriodActive_reverts() public {
// Allocate the preimage data. // Allocate the preimage data.
...@@ -795,7 +852,7 @@ contract PreimageOracle_LargePreimageProposals_Test is Test { ...@@ -795,7 +852,7 @@ contract PreimageOracle_LargePreimageProposals_Test is Test {
/// @notice Tests that squeezing a large preimage proposal after the challenge period has passed always succeeds and /// @notice Tests that squeezing a large preimage proposal after the challenge period has passed always succeeds and
/// persists the correct data. /// persists the correct data.
function testFuzz_squeeze_succeeds(uint256 _numBlocks, uint32 _partOffset) public { function testFuzz_squeezeLPP_succeeds(uint256 _numBlocks, uint32 _partOffset) public {
_numBlocks = bound(_numBlocks, 1, 2 ** 8); _numBlocks = bound(_numBlocks, 1, 2 ** 8);
_partOffset = uint32(bound(_partOffset, 0, _numBlocks * LibKeccak.BLOCK_SIZE_BYTES + 8 - 1)); _partOffset = uint32(bound(_partOffset, 0, _numBlocks * LibKeccak.BLOCK_SIZE_BYTES + 8 - 1));
......
...@@ -27,7 +27,7 @@ contract DeploymentSummary is DeploymentSummaryCode { ...@@ -27,7 +27,7 @@ contract DeploymentSummary is DeploymentSummaryCode {
address internal constant l1StandardBridgeProxyAddress = 0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D; address internal constant l1StandardBridgeProxyAddress = 0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D;
address internal constant l2OutputOracleAddress = 0x19652082F846171168Daf378C4fD3ee85a0D4A60; address internal constant l2OutputOracleAddress = 0x19652082F846171168Daf378C4fD3ee85a0D4A60;
address internal constant l2OutputOracleProxyAddress = 0x39Af23E00F1e662025aA01b0cEdA19542B78DF99; address internal constant l2OutputOracleProxyAddress = 0x39Af23E00F1e662025aA01b0cEdA19542B78DF99;
address internal constant mipsAddress = 0x2d3ec143CD85E6A74ce9110d607519dBd1D41b5E; address internal constant mipsAddress = 0xfc0E48bB2bDa4158Bc6F0809ac65F8C17750a57C;
address internal constant optimismMintableERC20FactoryAddress = 0x39Aea2Dd53f2d01c15877aCc2791af6BDD7aD567; address internal constant optimismMintableERC20FactoryAddress = 0x39Aea2Dd53f2d01c15877aCc2791af6BDD7aD567;
address internal constant optimismMintableERC20FactoryProxyAddress = 0xc7B87b2b892EA5C3CfF47168881FE168C00377FB; address internal constant optimismMintableERC20FactoryProxyAddress = 0xc7B87b2b892EA5C3CfF47168881FE168C00377FB;
address internal constant optimismPortalAddress = 0xbdD90485FCbcac869D5b5752179815a3103d8131; address internal constant optimismPortalAddress = 0xbdD90485FCbcac869D5b5752179815a3103d8131;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -27,13 +27,13 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { ...@@ -27,13 +27,13 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode {
address internal constant l1StandardBridgeProxyAddress = 0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D; address internal constant l1StandardBridgeProxyAddress = 0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D;
address internal constant l2OutputOracleAddress = 0x19652082F846171168Daf378C4fD3ee85a0D4A60; address internal constant l2OutputOracleAddress = 0x19652082F846171168Daf378C4fD3ee85a0D4A60;
address internal constant l2OutputOracleProxyAddress = 0x39Af23E00F1e662025aA01b0cEdA19542B78DF99; address internal constant l2OutputOracleProxyAddress = 0x39Af23E00F1e662025aA01b0cEdA19542B78DF99;
address internal constant mipsAddress = 0x2d3ec143CD85E6A74ce9110d607519dBd1D41b5E; address internal constant mipsAddress = 0xfc0E48bB2bDa4158Bc6F0809ac65F8C17750a57C;
address internal constant optimismMintableERC20FactoryAddress = 0x39Aea2Dd53f2d01c15877aCc2791af6BDD7aD567; address internal constant optimismMintableERC20FactoryAddress = 0x39Aea2Dd53f2d01c15877aCc2791af6BDD7aD567;
address internal constant optimismMintableERC20FactoryProxyAddress = 0xc7B87b2b892EA5C3CfF47168881FE168C00377FB; address internal constant optimismMintableERC20FactoryProxyAddress = 0xc7B87b2b892EA5C3CfF47168881FE168C00377FB;
address internal constant optimismPortalAddress = 0xbdD90485FCbcac869D5b5752179815a3103d8131; address internal constant optimismPortalAddress = 0xbdD90485FCbcac869D5b5752179815a3103d8131;
address internal constant optimismPortal2Address = 0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b; address internal constant optimismPortal2Address = 0xae5DadFc48928543f706a9E6Ce25c682aaD2b63b;
address internal constant optimismPortalProxyAddress = 0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4; address internal constant optimismPortalProxyAddress = 0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4;
address internal constant preimageOracleAddress = 0x5dF69aDD67a34e9b1e29dB9097f17ECe07DBC440; address internal constant preimageOracleAddress = 0xbc8Fd6DC3e97736bBdcdB65E92378FBc0a2dD484;
address internal constant protocolVersionsAddress = 0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F; address internal constant protocolVersionsAddress = 0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F;
address internal constant protocolVersionsProxyAddress = 0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1; address internal constant protocolVersionsProxyAddress = 0x4C52a6277b1B84121b3072C0c92b6Be0b7CC10F1;
address internal constant proxyAdminAddress = 0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1; address internal constant proxyAdminAddress = 0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD7D1;
......
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