feat: add guarded Base Sepolia encore
This commit is contained in:
@@ -20,6 +20,7 @@ abstract contract DemoScript is Script {
|
||||
error InvalidDeploymentBlock();
|
||||
error InvalidManifestSchema(uint256 schemaVersion);
|
||||
error InvalidActorConfiguration();
|
||||
error InvalidPublicRpcUrl();
|
||||
error UnexpectedState(string label, uint256 expected, uint256 actual);
|
||||
error UnexpectedAddress(string label, address expected, address actual);
|
||||
|
||||
@@ -60,6 +61,72 @@ abstract contract DemoScript is Script {
|
||||
return vm.envOr("DEPLOYMENT_MANIFEST_PATH", defaultPath);
|
||||
}
|
||||
|
||||
function _requireBaseSender(address scriptSender) internal view returns (address sender) {
|
||||
sender = vm.envAddress("BASE_SEPOLIA_SENDER");
|
||||
_assertAddress("BASE_SEPOLIA_SENDER", scriptSender, sender);
|
||||
}
|
||||
|
||||
function _requireBaseConfig(address scriptSender)
|
||||
internal
|
||||
view
|
||||
returns (address sender, address recipient, string memory publicRpcUrl)
|
||||
{
|
||||
sender = _requireBaseSender(scriptSender);
|
||||
recipient = vm.envAddress("BASE_SEPOLIA_RECIPIENT");
|
||||
if (sender == address(0) || recipient == address(0) || sender == recipient) revert InvalidActorConfiguration();
|
||||
publicRpcUrl = vm.envString("BASE_SEPOLIA_PUBLIC_RPC_URL");
|
||||
_requirePublicHttpsUrl(publicRpcUrl);
|
||||
}
|
||||
|
||||
function _requirePublicHttpsUrl(string memory value) internal pure {
|
||||
bytes memory url = bytes(value);
|
||||
bytes memory prefix = bytes("https://");
|
||||
if (url.length <= prefix.length) revert InvalidPublicRpcUrl();
|
||||
for (uint256 i; i < prefix.length; ++i) {
|
||||
if (url[i] != prefix[i]) revert InvalidPublicRpcUrl();
|
||||
}
|
||||
|
||||
bool query;
|
||||
uint256 queryStart;
|
||||
for (uint256 i = prefix.length; i < url.length; ++i) {
|
||||
bytes1 character = url[i];
|
||||
if (!query && character == "@") revert InvalidPublicRpcUrl();
|
||||
if (character == "?") {
|
||||
query = true;
|
||||
queryStart = i + 1;
|
||||
break;
|
||||
}
|
||||
if (character == "#") break;
|
||||
}
|
||||
if (!query) return;
|
||||
|
||||
bytes memory lowered = new bytes(url.length - queryStart);
|
||||
for (uint256 i; i < lowered.length; ++i) {
|
||||
uint8 character = uint8(url[queryStart + i]);
|
||||
lowered[i] = character >= 65 && character <= 90 ? bytes1(character + 32) : bytes1(character);
|
||||
}
|
||||
if (
|
||||
_containsBytes(lowered, bytes("key=")) || _containsBytes(lowered, bytes("token="))
|
||||
|| _containsBytes(lowered, bytes("secret=")) || _containsBytes(lowered, bytes("password="))
|
||||
|| _containsBytes(lowered, bytes("credential="))
|
||||
) revert InvalidPublicRpcUrl();
|
||||
}
|
||||
|
||||
function _containsBytes(bytes memory haystack, bytes memory needle) private pure returns (bool) {
|
||||
if (needle.length > haystack.length) return false;
|
||||
for (uint256 i; i + needle.length <= haystack.length; ++i) {
|
||||
bool matches = true;
|
||||
for (uint256 j; j < needle.length; ++j) {
|
||||
if (haystack[i + j] != needle[j]) {
|
||||
matches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (matches) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function _readManifest(string memory path, bool active) internal view returns (Manifest memory manifest) {
|
||||
string memory json = vm.readFile(path);
|
||||
_assertExactManifestSchema(json);
|
||||
@@ -112,7 +179,7 @@ abstract contract DemoScript is Script {
|
||||
}
|
||||
|
||||
function _parseActors(string memory json, uint256 chainId) private view returns (Actor[] memory actors) {
|
||||
uint256 actorCount = chainId == ANVIL_CHAIN_ID ? 3 : 1;
|
||||
uint256 actorCount = chainId == ANVIL_CHAIN_ID ? 3 : 2;
|
||||
actors = new Actor[](actorCount);
|
||||
for (uint256 i; i < actorCount; ++i) {
|
||||
string memory index = vm.toString(i);
|
||||
@@ -157,9 +224,13 @@ abstract contract DemoScript is Script {
|
||||
}
|
||||
|
||||
if (
|
||||
manifest.chainId != BASE_SEPOLIA_CHAIN_ID || manifest.actors.length != 1
|
||||
|| !_equals(manifest.network, "baseSepolia") || !_equals(manifest.actors[0].label, "owner")
|
||||
|| manifest.actors[0].address_ != manifest.owner
|
||||
manifest.chainId != BASE_SEPOLIA_CHAIN_ID || manifest.actors.length != 2
|
||||
|| !_equals(manifest.network, "baseSepolia") || !_equals(manifest.actors[0].label, "Presenter")
|
||||
|| !_equals(manifest.actors[1].label, "Recipient") || manifest.actors[0].address_ != manifest.owner
|
||||
) revert InvalidActorConfiguration();
|
||||
if (
|
||||
manifest.actors[0].address_ == address(0) || manifest.actors[1].address_ == address(0)
|
||||
|| manifest.actors[0].address_ == manifest.actors[1].address_
|
||||
) revert InvalidActorConfiguration();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user