> loading_
# Walkthrough: Understanding the eager copy fix and how to verify it
#
# The bug: ProgramInvokeFactoryImpl previously passed a reference to the
# caller's data buffer when constructing a child ProgramInvoke. If the
# caller's memory was later modified, the child's calldata could change.
#
# Below is a Solidity pattern that would have been vulnerable, plus a
# Hardhat test to confirm the fix is in place on RSK.
# --- contracts/CalldataIntegrity.sol ---
# // SPDX-License-Identifier: MIT
# pragma solidity ^0.8.0;
#
# contract Inner {
# // Reads calldata at two different points separated by a sub-operation
# function verify(uint256 expected) external pure returns (bool) {
# // First read of calldata
# uint256 firstRead = expected; // solc will use CALLDATALOAD
#
# // Simulate work that, pre-fix, might have triggered a buffer mutation
# uint256 dummy;
# assembly {
# dummy := calldataload(4) // explicit second read of same slot
# }
#
# // Both reads must return the same value
# return firstRead == dummy;
# }
# }
#
# contract Outer {
# // Calls Inner and then does memory-expanding work
# function testIntegrity(address inner, uint256 val) external returns (bool) {
# // Encode the call — this is the data that gets passed
# bytes memory payload = abi.encodeWithSelector(
# Inner.verify.selector,
# val
# );
#
# // Make the call
# (bool success, bytes memory result) = inner.call(payload);
# require(success, "Inner call failed");
#
# // Expand memory aggressively after the call
# // Pre-fix, if the reference was shared, this could corrupt data
# bytes memory expansion = new bytes(4096);
# expansion[0] = 0xff;
#
# return abi.decode(result, (bool));
# }
# }
# --- test/calldataIntegrity.test.js ---
# const { expect } = require("chai");
# const { ethers } = require("hardhat");
#
# describe("Calldata Integrity (RSKCORE-5466 fix)", function () {
# it("should return stable calldata across reads in a child frame", async function () {
# const Inner = await ethers.getContractFactory("Inner");
# const inner = await Inner.deploy();
# await inner.deployed();
#
# const Outer = await ethers.getContractFactory("Outer");
# const outer = await Outer.deploy();
# await outer.deployed();
#
# // Test with various values including edge cases
# const testValues = [
# 0,
# 1,
# ethers.constants.MaxUint256,
# 42,
# ethers.BigNumber.from("0xdeadbeefdeadbeef")
# ];
#
# for (const val of testValues) {
# const result = await outer.callStatic.testIntegrity(inner.address, val);
# // Post-fix, calldata should always be consistent
# expect(result).to.equal(true, `Calldata mismatch for value ${val}`);
# }
# });
# });
#
# --- hardhat.config.js (RSK Testnet target) ---
# // Ensure you're pointing at an RSK node with the fix applied
# // networks: {
# // rskTestnet: {
# // url: "https://public-node.testnet.rsk.co",
# // chainId: 31,
# // accounts: [process.env.RSK_PRIVATE_KEY]
# // }
# // }
#
# // Run: npx hardhat test --network rskTestnet