Skip to content

Commit

Permalink
Forkaware structure (#74)
Browse files Browse the repository at this point in the history
On L2, I think many contracts need to wait after a fork for the first message that will come from the bridge. E.g. our adjudication framework would have to wait for a message which court is removed before it starts to forward any new information of the oracles/courts. Then I think the following contract will be quite helpful.
  • Loading branch information
josojo authored Sep 28, 2023
1 parent 80f5235 commit 0a140b3
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .solhint.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"plugins": ["prettier"],
"rules": {
"compiler-version": "off",
"max-states-count": "off"
"max-states-count": "off",
"no-empty-blocks": "off",
"func-visibility": ["warn",{"ignoreConstructors":true}]
}
}
23 changes: 23 additions & 0 deletions development/contracts/mixin/InitializeChain.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pragma solidity ^0.8.20;

/** This contract can be inherited form any other contrac that needs to be aware of Forks.
This contract uses the fact that after a fork the chainId changes and thereby detects forks*/

contract InitializeChain {
uint256 public chainId;

modifier onlyChainUninitialized() {
require(chainId != block.chainid, "Not on new fork");
_;
chainId = block.chainid;
}

modifier onlyChainInitialized() {
require(chainId == block.chainid, "On new fork");
_;
}

constructor() {
chainId = block.chainid;
}
}
64 changes: 64 additions & 0 deletions test/InitializeChain.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.17;

import {Test} from "forge-std/Test.sol";
import {InitializeChainWrapper} from "./testcontract/InitializeChainWrapper.sol";

contract InitializeChainWrapperTest is Test {
InitializeChainWrapper public wrapper;

function setUp() public {
wrapper = new InitializeChainWrapper();
}

function testSetChainId() public {
assertEq(wrapper.chainId(), block.chainid);
}

function testonlyChainUninitialized() public {
// Simulate a chain fork by setting block.chainid to a new value
vm.chainId(2);
wrapper.onlyChainUninitializedWrapper(); // This should pass since it's the first TX after fork

// Subsequent calls should fail
try wrapper.onlyChainUninitializedWrapper() {
fail(
"Should have reverted because it's not the first TX after fork."
);
} catch Error(string memory reason) {
assertEq(reason, "Not on new fork");
}
}

function testonlyChainInitialized() public {
// On the original chain, this call should succeed
wrapper.onlyChainInitializedWrapper();

// Simulate a chain fork by setting block.chainid to a new value
vm.chainId(2);

// This call should fail since it's the first TX after fork
try wrapper.onlyChainInitializedWrapper() {
fail("Should have reverted because it's the first TX after fork.");
} catch Error(string memory reason) {
assertEq(reason, "On new fork");
}

// Call a function with onlyChainUninitialized to update chainId
wrapper.onlyChainUninitializedWrapper();

// Now, this call should succeed
wrapper.onlyChainInitializedWrapper();
}

function testUpdateChainId() public {
// Initially, chainId is 1
assertFalse(wrapper.chainId() == 1);

// Simulate a chain fork by setting block.chainid to a new value
vm.chainId(2);
wrapper.onlyChainUninitializedWrapper(); // This should update the chainId

assertEq(wrapper.chainId(), 2);
}
}
15 changes: 15 additions & 0 deletions test/testcontract/InitializeChainWrapper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.17;

import {InitializeChain} from "../../development/contracts/mixin/InitializeChain.sol";

contract InitializeChainWrapper is InitializeChain {
constructor() InitializeChain() {}

function onlyChainUninitializedWrapper() public onlyChainUninitialized {}

function onlyChainInitializedWrapper()
public
onlyChainInitialized
{}
}

0 comments on commit 0a140b3

Please sign in to comment.