This repository has been archived by the owner on Jan 11, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add skeleton for GatewayActor invariants (#413)
This PR establishes a skeleton for future invariant tests for GatewayActor. The main idea is to define all basic properties of the gatewayActor and be able to apply them to many different Gateway instances with different configurations.
- Loading branch information
Showing
7 changed files
with
230 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// SPDX-License-Identifier: MIT OR Apache-2.0 | ||
pragma solidity 0.8.19; | ||
|
||
import {SubnetID, Subnet, IPCAddress, Validator} from "../src/structs/Subnet.sol"; | ||
import {DiamondCutFacet} from "../src/diamond/DiamondCutFacet.sol"; | ||
import {DiamondLoupeFacet} from "../src/diamond/DiamondLoupeFacet.sol"; | ||
import {GatewayDiamond} from "../src/GatewayDiamond.sol"; | ||
import {GatewayGetterFacet} from "../src/gateway/GatewayGetterFacet.sol"; | ||
import {GatewayManagerFacet} from "../src/gateway/GatewayManagerFacet.sol"; | ||
import {GatewayMessengerFacet} from "../src/gateway/GatewayMessengerFacet.sol"; | ||
import {XnetMessagingFacet} from "../src/gateway/router/XnetMessagingFacet.sol"; | ||
import {IntegrationTestBase} from "./IntegrationTestBase.sol"; | ||
|
||
contract L1GatewayActorDiamond is IntegrationTestBase { | ||
function setUp() public virtual override { | ||
GatewayDiamond.ConstructorParams memory gwConstructorParams = defaultGatewayParams(); | ||
gatewayDiamond = createGatewayDiamond(gwConstructorParams); | ||
|
||
gwGetter = GatewayGetterFacet(address(gatewayDiamond)); | ||
gwManager = GatewayManagerFacet(address(gatewayDiamond)); | ||
gwXnetMessagingFacet = XnetMessagingFacet(address(gatewayDiamond)); | ||
gwMessenger = GatewayMessengerFacet(address(gatewayDiamond)); | ||
gwLouper = DiamondLoupeFacet(address(gatewayDiamond)); | ||
gwCutter = DiamondCutFacet(address(gatewayDiamond)); | ||
} | ||
|
||
function defaultGatewayParams() internal pure override returns (GatewayDiamond.ConstructorParams memory) { | ||
address[] memory path = new address[](1); | ||
path[0] = CHILD_NETWORK_ADDRESS; | ||
|
||
GatewayDiamond.ConstructorParams memory params = GatewayDiamond.ConstructorParams({ | ||
networkName: SubnetID({root: ROOTNET_CHAINID, route: path}), | ||
bottomUpCheckPeriod: DEFAULT_CHECKPOINT_PERIOD, | ||
msgFee: DEFAULT_CROSS_MSG_FEE, | ||
majorityPercentage: DEFAULT_MAJORITY_PERCENTAGE, | ||
genesisValidators: new Validator[](0), | ||
activeValidatorsLimit: DEFAULT_ACTIVE_VALIDATORS_LIMIT | ||
}); | ||
|
||
return params; | ||
} | ||
} | ||
|
||
contract L2GatewayActorDiamond is IntegrationTestBase { | ||
function setUp() public virtual override { | ||
GatewayDiamond.ConstructorParams memory gwConstructorParams = defaultGatewayParams(); | ||
gatewayDiamond = createGatewayDiamond(gwConstructorParams); | ||
|
||
gwGetter = GatewayGetterFacet(address(gatewayDiamond)); | ||
gwManager = GatewayManagerFacet(address(gatewayDiamond)); | ||
gwXnetMessagingFacet = XnetMessagingFacet(address(gatewayDiamond)); | ||
gwMessenger = GatewayMessengerFacet(address(gatewayDiamond)); | ||
gwLouper = DiamondLoupeFacet(address(gatewayDiamond)); | ||
gwCutter = DiamondCutFacet(address(gatewayDiamond)); | ||
} | ||
|
||
function defaultGatewayParams() internal pure override returns (GatewayDiamond.ConstructorParams memory) { | ||
address[] memory path = new address[](2); | ||
path[0] = CHILD_NETWORK_ADDRESS; | ||
path[1] = CHILD_NETWORK_ADDRESS_2; | ||
|
||
GatewayDiamond.ConstructorParams memory params = GatewayDiamond.ConstructorParams({ | ||
networkName: SubnetID({root: ROOTNET_CHAINID, route: path}), | ||
bottomUpCheckPeriod: DEFAULT_CHECKPOINT_PERIOD, | ||
msgFee: DEFAULT_CROSS_MSG_FEE, | ||
majorityPercentage: DEFAULT_MAJORITY_PERCENTAGE, | ||
genesisValidators: new Validator[](0), | ||
activeValidatorsLimit: DEFAULT_ACTIVE_VALIDATORS_LIMIT | ||
}); | ||
|
||
return params; | ||
} | ||
} | ||
|
||
contract L3GatewayActorDiamond is IntegrationTestBase { | ||
address constant CHILD_NETWORK_ADDRESS_3 = address(31); | ||
|
||
function setUp() public virtual override { | ||
GatewayDiamond.ConstructorParams memory gwConstructorParams = defaultGatewayParams(); | ||
gatewayDiamond = createGatewayDiamond(gwConstructorParams); | ||
|
||
gwGetter = GatewayGetterFacet(address(gatewayDiamond)); | ||
gwManager = GatewayManagerFacet(address(gatewayDiamond)); | ||
gwXnetMessagingFacet = XnetMessagingFacet(address(gatewayDiamond)); | ||
gwMessenger = GatewayMessengerFacet(address(gatewayDiamond)); | ||
gwLouper = DiamondLoupeFacet(address(gatewayDiamond)); | ||
gwCutter = DiamondCutFacet(address(gatewayDiamond)); | ||
} | ||
|
||
function defaultGatewayParams() internal pure override returns (GatewayDiamond.ConstructorParams memory) { | ||
address[] memory path = new address[](3); | ||
path[0] = CHILD_NETWORK_ADDRESS; | ||
path[1] = CHILD_NETWORK_ADDRESS_2; | ||
path[1] = CHILD_NETWORK_ADDRESS_2; | ||
|
||
GatewayDiamond.ConstructorParams memory params = GatewayDiamond.ConstructorParams({ | ||
networkName: SubnetID({root: ROOTNET_CHAINID, route: path}), | ||
bottomUpCheckPeriod: DEFAULT_CHECKPOINT_PERIOD, | ||
msgFee: DEFAULT_CROSS_MSG_FEE, | ||
majorityPercentage: DEFAULT_MAJORITY_PERCENTAGE, | ||
genesisValidators: new Validator[](0), | ||
activeValidatorsLimit: DEFAULT_ACTIVE_VALIDATORS_LIMIT | ||
}); | ||
|
||
return params; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// SPDX-License-Identifier: MIT OR Apache-2.0 | ||
pragma solidity 0.8.19; | ||
|
||
import {StdInvariant} from "forge-std/StdInvariant.sol"; | ||
import {GatewayDiamond} from "../../src/GatewayDiamond.sol"; | ||
import {L1GatewayActorDiamond, L2GatewayActorDiamond, L3GatewayActorDiamond} from "../IntegrationTestPresets.sol"; | ||
import {GatewayActorHandler} from "./handlers/GatewayActorHandler.sol"; | ||
import {GatewayActorBasicProperties} from "./GatewayActorProperties.sol"; | ||
|
||
contract GatewayActorInvariantTests is StdInvariant, L1GatewayActorDiamond, GatewayActorBasicProperties { | ||
GatewayActorHandler private gatewayActorHandler; | ||
|
||
function setUp() public override { | ||
L1GatewayActorDiamond.setUp(); | ||
gatewayActorHandler = new GatewayActorHandler(gatewayDiamond); | ||
targetContract(address(gatewayActorHandler)); | ||
|
||
// assert specific properties of the infrastructure. | ||
assertEq(gwGetter.getNetworkName().route.length, 1); | ||
} | ||
} | ||
|
||
contract L2GatewayActorInvariantTests is L2GatewayActorDiamond, GatewayActorBasicProperties { | ||
GatewayActorHandler private gatewayActorHandler; | ||
|
||
function setUp() public override { | ||
L2GatewayActorDiamond.setUp(); | ||
gatewayActorHandler = new GatewayActorHandler(gatewayDiamond); | ||
targetContract(address(gatewayActorHandler)); | ||
|
||
// assert specific properties of the infrastructure. | ||
assertEq(gwGetter.getNetworkName().route.length, 2); | ||
} | ||
} | ||
|
||
contract L3GatewayActorInvariantTests is L3GatewayActorDiamond, GatewayActorBasicProperties { | ||
GatewayActorHandler private gatewayActorHandler; | ||
|
||
function setUp() public override { | ||
L3GatewayActorDiamond.setUp(); | ||
gatewayActorHandler = new GatewayActorHandler(gatewayDiamond); | ||
targetContract(address(gatewayActorHandler)); | ||
|
||
// assert specific properties of the infrastructure. | ||
assertEq(gwGetter.getNetworkName().route.length, 3); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// SPDX-License-Identifier: MIT OR Apache-2.0 | ||
pragma solidity 0.8.19; | ||
|
||
import {StdAssertions} from "forge-std/StdAssertions.sol"; | ||
import {GatewayGetterFacet} from "../../src/gateway/GatewayGetterFacet.sol"; | ||
import {IntegrationTestBase, TestGatewayActor} from "../IntegrationTestBase.sol"; | ||
|
||
/// @title GatewayActor properties. | ||
/// @dev It is suggested that all properties are defined here. | ||
/// To check that a concrete GatewayActor instance holds the properties that target contract should inherit from this contract. | ||
/// This contract must be abstract. | ||
abstract contract GatewayActorBasicProperties is StdAssertions, TestGatewayActor { | ||
/// @notice The number of subnets is consistent within GatewayActor mechanisms. | ||
function invariant_GA_01_consistent_subnet_number() public virtual { | ||
assertEq(gwGetter.totalSubnets(), gwGetter.listSubnets().length, "the number of subnets is not consistent"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// SPDX-License-Identifier: MIT OR Apache-2.0 | ||
pragma solidity 0.8.19; | ||
|
||
import "forge-std/StdUtils.sol"; | ||
import "forge-std/StdCheats.sol"; | ||
import {CommonBase} from "forge-std/Base.sol"; | ||
import {GatewayDiamond} from "../../../src/GatewayDiamond.sol"; | ||
import {BottomUpRouterFacet} from "../../../src/gateway/router/BottomUpRouterFacet.sol"; | ||
import {GatewayManagerFacet} from "../../../src/gateway/GatewayManagerFacet.sol"; | ||
import {EnumerableSet} from "openzeppelin-contracts/utils/structs/EnumerableSet.sol"; | ||
|
||
uint256 constant ETH_SUPPLY = 129_590_000 ether; | ||
|
||
contract GatewayActorHandler is CommonBase, StdCheats, StdUtils { | ||
GatewayManagerFacet managerFacet; | ||
|
||
uint256 private constant DEFAULT_MIN_VALIDATOR_STAKE = 10 ether; | ||
|
||
constructor(GatewayDiamond _gw) { | ||
managerFacet = GatewayManagerFacet(address(_gw)); | ||
|
||
deal(address(this), ETH_SUPPLY); | ||
} | ||
|
||
function register(uint256 amount) public { | ||
amount = bound(amount, 0, 3 * DEFAULT_MIN_VALIDATOR_STAKE); | ||
managerFacet.register(amount); | ||
} | ||
|
||
function stake(uint256 amount) public { | ||
amount = bound(amount, 0, 3 * DEFAULT_MIN_VALIDATOR_STAKE); | ||
managerFacet.addStake{value: amount}(); | ||
} | ||
|
||
function _pay(address to, uint256 amount) internal { | ||
(bool s, ) = to.call{value: amount}(""); | ||
require(s, "pay() failed"); | ||
} | ||
|
||
receive() external payable {} | ||
} |