-
Notifications
You must be signed in to change notification settings - Fork 8
Description
I'm running into an issue while using a script really similar to the following:
pragma solidity >=0.8.28 <0.9.0;
import { Contract } from "../src/Contract.sol";
import { Script } from "forge-std/Script.sol";
import { console } from "forge-std/console.sol";
import { Upgrades, Options } from "@openzeppelin/foundry-upgrades/Upgrades.sol";
import { Safe } from "safe-utils/Safe.sol";
import { IProxyAdmin } from "@openzeppelin/foundry-upgrades/internal/interfaces/IProxyAdmin.sol";
contract DeployScript is Script {
using Safe for *;
error Invalid();
string public constant BUILD_INFO_DIR = "old-build-info/";
// Gnosis Safe instance
Safe.Client safe;
// Optimism test contracts
string public constant network = "optimism";
address public constant SAFE_ADDRESS = address(2); // CHANGE THIS
address public constant PROXY = address(1); // CHANGE THIS
function run() public {
vm.createSelectFork(network);
vm.startBroadcast();
console.log('Upgrading in', network);
_upgradeContractMultisig();
vm.stopBroadcast();
}
// Methods to propose an upgrade to the proxy implementation
function _upgradeContractMultisig() internal {
_upgradeViaMultisig(PROXY, "Contract");
}
/// @notice Prepares the upgrade of the proxy implementation to a new version.
/// @param proxy The address of the proxy contract to upgrade.
/// @param oldContract The name of the old contract to upgrade.
function _upgradeViaMultisig(address proxy, string memory oldContract) public {
if (proxy == address(0) || bytes(oldContract).length == 0) {
revert Invalid();
}
safe.initialize(SAFE_ADDRESS);
// https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades?tab=readme-ov-file#upgrade-a-proxy-or-beacon
Options memory opts;
opts.referenceBuildInfoDir = string(abi.encodePacked(BUILD_INFO_DIR, network));
opts.referenceContract = string(abi.encodePacked(network, ":", oldContract));
string memory contractFile = string(abi.encodePacked(oldContract, ".sol"));
// Validate and deploy new implementation
address newImpl = Upgrades.prepareUpgrade(contractFile, opts);
// Propose upgrade tx with multisig
safe.proposeTransaction(
Upgrades.getAdminAddress(proxy),
abi.encodeCall(IProxyAdmin.upgradeAndCall, (proxy, newImpl, "")),
DEPLOYER,
"m/44'/60'/0'/0/0"
);
}
}
In my script I am deploying a new contract (in this case via Upgrades.prepareUpgrade(contractFile, opts) to deploy a new implementation contract for a proxy) and then I'm trying to propose a tx in the multisig to update the proxy. What I see is that it first triggers an error like below (I guess during the simulation step)
stating that the Ledger is already in use basically.
What happens next is that the new implementation contract is deployed and verified normally but there is no prompt to sign the multisig tx and so the tx is not posted on the Safe.
Any idea why? Seems like some sort of race condition where the Ledger is used both for deploying and signing the Safe tx at the same time
