fix: harden V1 deployment manifests
This commit is contained in:
@@ -13,6 +13,7 @@ contract CheckState is DemoScript {
|
||||
|
||||
function run() external view {
|
||||
_requireSupportedChain(block.chainid);
|
||||
_printEducationalWarning();
|
||||
string memory stage = vm.envOr("DEMO_EXPECTED_STAGE", string("v1"));
|
||||
bool deployedStage = keccak256(bytes(stage)) == keccak256("deployed");
|
||||
Manifest memory manifest = _readManifest(_manifestPath(ACTIVE_MANIFEST_PATH), !deployedStage);
|
||||
|
||||
@@ -9,6 +9,7 @@ import {DemoScript} from "./lib/DemoScript.sol";
|
||||
contract DeployV1 is DemoScript {
|
||||
function run() external returns (address tokenAddress, address proxy, address implementation) {
|
||||
_requireSupportedChain(block.chainid);
|
||||
_printEducationalWarning();
|
||||
address sender = vm.envAddress("SCRIPT_SENDER");
|
||||
|
||||
if (block.chainid == ANVIL_CHAIN_ID) {
|
||||
@@ -50,7 +51,7 @@ contract DeployV1 is DemoScript {
|
||||
_writeManifest(_manifestPath(PENDING_MANIFEST_PATH), manifest);
|
||||
}
|
||||
|
||||
function _actors(address sender) private returns (string[] memory labels, address[] memory actors) {
|
||||
function _actors(address sender) private view returns (string[] memory labels, address[] memory actors) {
|
||||
if (block.chainid == ANVIL_CHAIN_ID) {
|
||||
labels = new string[](3);
|
||||
actors = new address[](3);
|
||||
|
||||
@@ -8,8 +8,8 @@ import {DemoScript} from "./lib/DemoScript.sol";
|
||||
contract SeedV1Demo is DemoScript {
|
||||
function run() external {
|
||||
if (block.chainid != ANVIL_CHAIN_ID) revert UnsupportedChain(block.chainid);
|
||||
_printEducationalWarning();
|
||||
Manifest memory manifest = _readManifest(_manifestPath(ACTIVE_MANIFEST_PATH), true);
|
||||
if (manifest.actors.length != 3 || manifest.actorLabels.length != 3) revert InvalidManifestSchema(1);
|
||||
|
||||
(uint256 ownerKey, address owner) = _deriveLocalActor(block.chainid, 0);
|
||||
(uint256 aliceKey, address alice) = _deriveLocalActor(block.chainid, 1);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
pragma solidity 0.8.35;
|
||||
|
||||
import {Script} from "forge-std/Script.sol";
|
||||
import {console2} from "forge-std/console2.sol";
|
||||
import {BankV1} from "../../src/BankV1.sol";
|
||||
import {MockUSDC} from "../../src/MockUSDC.sol";
|
||||
|
||||
@@ -11,12 +12,14 @@ abstract contract DemoScript is Script {
|
||||
string internal constant ANVIL_TEST_PHRASE = "test test test test test test test test test test test junk";
|
||||
string internal constant PENDING_MANIFEST_PATH = "deployments/pending.json";
|
||||
string internal constant ACTIVE_MANIFEST_PATH = "deployments/active.json";
|
||||
string internal constant EDUCATIONAL_WARNING = unicode"Educational demo — mock token — never use real funds.";
|
||||
|
||||
error UnsupportedChain(uint256 chainId);
|
||||
error ManifestChainMismatch(uint256 expected, uint256 actual);
|
||||
error MissingCode(string label, address target);
|
||||
error InvalidDeploymentBlock();
|
||||
error InvalidManifestSchema(uint256 schemaVersion);
|
||||
error InvalidActorConfiguration();
|
||||
error UnexpectedState(string label, uint256 expected, uint256 actual);
|
||||
error UnexpectedAddress(string label, address expected, address actual);
|
||||
|
||||
@@ -39,7 +42,11 @@ abstract contract DemoScript is Script {
|
||||
if (chainId != ANVIL_CHAIN_ID && chainId != BASE_SEPOLIA_CHAIN_ID) revert UnsupportedChain(chainId);
|
||||
}
|
||||
|
||||
function _deriveLocalActor(uint256 chainId, uint32 index) internal returns (uint256 privateKey, address actor) {
|
||||
function _deriveLocalActor(uint256 chainId, uint32 index)
|
||||
internal
|
||||
pure
|
||||
returns (uint256 privateKey, address actor)
|
||||
{
|
||||
if (chainId != ANVIL_CHAIN_ID) revert UnsupportedChain(chainId);
|
||||
privateKey = vm.deriveKey(ANVIL_TEST_PHRASE, index);
|
||||
actor = vm.addr(privateKey);
|
||||
@@ -67,6 +74,7 @@ abstract contract DemoScript is Script {
|
||||
if (manifest.schemaVersion != 1) revert InvalidManifestSchema(manifest.schemaVersion);
|
||||
if (manifest.chainId != block.chainid) revert ManifestChainMismatch(block.chainid, manifest.chainId);
|
||||
if (active && manifest.deploymentBlock == 0) revert InvalidDeploymentBlock();
|
||||
_validateActorConfiguration(manifest);
|
||||
_requireCode("token", manifest.token);
|
||||
_requireCode("proxy", manifest.proxy);
|
||||
_requireCode("implementation", manifest.implementation);
|
||||
@@ -76,6 +84,44 @@ abstract contract DemoScript is Script {
|
||||
if (target == address(0) || target.code.length == 0) revert MissingCode(label, target);
|
||||
}
|
||||
|
||||
function _validateActorConfiguration(Manifest memory manifest) internal pure {
|
||||
if (manifest.actorLabels.length != manifest.actors.length) revert InvalidActorConfiguration();
|
||||
if (manifest.chainId == ANVIL_CHAIN_ID) {
|
||||
if (
|
||||
manifest.actorLabels.length != 3 || !_equals(manifest.network, "anvil")
|
||||
|| !_equals(manifest.actorLabels[0], "owner") || !_equals(manifest.actorLabels[1], "Alice")
|
||||
|| !_equals(manifest.actorLabels[2], "Bob")
|
||||
) revert InvalidActorConfiguration();
|
||||
|
||||
(, address owner) = _deriveLocalActor(ANVIL_CHAIN_ID, 0);
|
||||
(, address alice) = _deriveLocalActor(ANVIL_CHAIN_ID, 1);
|
||||
(, address bob) = _deriveLocalActor(ANVIL_CHAIN_ID, 2);
|
||||
if (
|
||||
manifest.actors[0] != manifest.owner || manifest.actors[0] != owner || manifest.actors[1] != alice
|
||||
|| manifest.actors[2] != bob
|
||||
) revert InvalidActorConfiguration();
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
manifest.chainId != BASE_SEPOLIA_CHAIN_ID || manifest.actorLabels.length != 1
|
||||
|| !_equals(manifest.network, "base-sepolia") || !_equals(manifest.actorLabels[0], "owner")
|
||||
|| manifest.actors[0] != manifest.owner
|
||||
) revert InvalidActorConfiguration();
|
||||
}
|
||||
|
||||
function _educationalWarning() internal pure returns (string memory) {
|
||||
return EDUCATIONAL_WARNING;
|
||||
}
|
||||
|
||||
function _printEducationalWarning() internal pure {
|
||||
console2.log(EDUCATIONAL_WARNING);
|
||||
}
|
||||
|
||||
function _equals(string memory left, string memory right) private pure returns (bool) {
|
||||
return keccak256(bytes(left)) == keccak256(bytes(right));
|
||||
}
|
||||
|
||||
function _serializeManifest(Manifest memory manifest) internal returns (string memory json) {
|
||||
string memory objectKey = "demo-manifest";
|
||||
vm.serializeUint(objectKey, "schemaVersion", manifest.schemaVersion);
|
||||
|
||||
Reference in New Issue
Block a user