diff --git a/.openzeppelin/base-sepolia.json b/.openzeppelin/base-sepolia.json index e433349..c65d360 100644 --- a/.openzeppelin/base-sepolia.json +++ b/.openzeppelin/base-sepolia.json @@ -1372,6 +1372,482 @@ "contract": "DLCManager", "src": "contracts/DLCManager.sol:47" }, + { + "label": "dlcs", + "offset": 0, + "slot": "252", + "type": "t_mapping(t_uint256,t_struct(DLC)9268_storage)", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:48" + }, + { + "label": "dlcIDsByUUID", + "offset": 0, + "slot": "253", + "type": "t_mapping(t_bytes32,t_uint256)", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:49" + }, + { + "label": "_minimumThreshold", + "offset": 0, + "slot": "254", + "type": "t_uint16", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:51" + }, + { + "label": "_threshold", + "offset": 2, + "slot": "254", + "type": "t_uint16", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:52" + }, + { + "label": "_signerCount", + "offset": 4, + "slot": "254", + "type": "t_uint16", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:53" + }, + { + "label": "tssCommitment", + "offset": 0, + "slot": "255", + "type": "t_bytes32", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:54" + }, + { + "label": "attestorGroupPubKey", + "offset": 0, + "slot": "256", + "type": "t_string_storage", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:55" + }, + { + "label": "dlcBTC", + "offset": 0, + "slot": "257", + "type": "t_contract(DLCBTC)9226", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:57" + }, + { + "label": "btcFeeRecipient", + "offset": 0, + "slot": "258", + "type": "t_string_storage", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:58" + }, + { + "label": "minimumDeposit", + "offset": 0, + "slot": "259", + "type": "t_uint256", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:59" + }, + { + "label": "maximumDeposit", + "offset": 0, + "slot": "260", + "type": "t_uint256", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:60" + }, + { + "label": "btcMintFeeRate", + "offset": 0, + "slot": "261", + "type": "t_uint256", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:61" + }, + { + "label": "btcRedeemFeeRate", + "offset": 0, + "slot": "262", + "type": "t_uint256", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:62" + }, + { + "label": "whitelistingEnabled", + "offset": 0, + "slot": "263", + "type": "t_bool", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:63" + }, + { + "label": "userVaults", + "offset": 0, + "slot": "264", + "type": "t_mapping(t_address,t_array(t_bytes32)dyn_storage)", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:65" + }, + { + "label": "_whitelistedAddresses", + "offset": 0, + "slot": "265", + "type": "t_mapping(t_address,t_bool)", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:66" + }, + { + "label": "__gap", + "offset": 0, + "slot": "266", + "type": "t_array(t_uint256)41_storage", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:67" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)41_storage": { + "label": "uint256[41]", + "numberOfBytes": "1312" + }, + "t_array(t_uint256)48_storage": { + "label": "uint256[48]", + "numberOfBytes": "1536" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(DLCBTC)9226": { + "label": "contract DLCBTC", + "numberOfBytes": "20" + }, + "t_enum(DLCStatus)9238": { + "label": "enum DLCLink.DLCStatus", + "members": [ + "READY", + "FUNDED", + "CLOSING", + "CLOSED", + "AUX_STATE_1", + "AUX_STATE_2", + "AUX_STATE_3", + "AUX_STATE_4", + "AUX_STATE_5" + ], + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_array(t_bytes32)dyn_storage)": { + "label": "mapping(address => bytes32[])", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_bool)": { + "label": "mapping(address => bool)", + "numberOfBytes": "32" + }, + "t_mapping(t_bytes32,t_struct(RoleData)747_storage)": { + "label": "mapping(bytes32 => struct AccessControlUpgradeable.RoleData)", + "numberOfBytes": "32" + }, + "t_mapping(t_bytes32,t_uint256)": { + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint256,t_struct(DLC)9268_storage)": { + "label": "mapping(uint256 => struct DLCLink.DLC)", + "numberOfBytes": "32" + }, + "t_string_storage": { + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(DLC)9268_storage": { + "label": "struct DLCLink.DLC", + "members": [ + { + "label": "uuid", + "type": "t_bytes32", + "offset": 0, + "slot": "0" + }, + { + "label": "protocolContract", + "type": "t_address", + "offset": 0, + "slot": "1" + }, + { + "label": "timestamp", + "type": "t_uint256", + "offset": 0, + "slot": "2" + }, + { + "label": "valueLocked", + "type": "t_uint256", + "offset": 0, + "slot": "3" + }, + { + "label": "creator", + "type": "t_address", + "offset": 0, + "slot": "4" + }, + { + "label": "status", + "type": "t_enum(DLCStatus)9238", + "offset": 20, + "slot": "4" + }, + { + "label": "fundingTxId", + "type": "t_string_storage", + "offset": 0, + "slot": "5" + }, + { + "label": "closingTxId", + "type": "t_string_storage", + "offset": 0, + "slot": "6" + }, + { + "label": "btcFeeRecipient", + "type": "t_string_storage", + "offset": 0, + "slot": "7" + }, + { + "label": "btcMintFeeBasisPoints", + "type": "t_uint256", + "offset": 0, + "slot": "8" + }, + { + "label": "btcRedeemFeeBasisPoints", + "type": "t_uint256", + "offset": 0, + "slot": "9" + }, + { + "label": "taprootPubKey", + "type": "t_string_storage", + "offset": 0, + "slot": "10" + }, + { + "label": "valueMinted", + "type": "t_uint256", + "offset": 0, + "slot": "11" + }, + { + "label": "wdTxId", + "type": "t_string_storage", + "offset": 0, + "slot": "12" + } + ], + "numberOfBytes": "416" + }, + "t_struct(RoleData)747_storage": { + "label": "struct AccessControlUpgradeable.RoleData", + "members": [ + { + "label": "members", + "type": "t_mapping(t_address,t_bool)", + "offset": 0, + "slot": "0" + }, + { + "label": "adminRole", + "type": "t_bytes32", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_uint16": { + "label": "uint16", + "numberOfBytes": "2" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint48": { + "label": "uint48", + "numberOfBytes": "6" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } + }, + "1204facb32434b600d4c54f0616b1f8174db5a43aa86b417a97c7e2737cca230": { + "address": "0x8f8625c2a9bC9770BcfE06AaE1Fcdd479fA60b83", + "txHash": "0xb24c63922f2f42d059477faabb5c3149178e6b2c56a222eedfa990a6dca1da27", + "layout": { + "solcVersion": "0.8.18", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC165Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41" + }, + { + "label": "_roles", + "offset": 0, + "slot": "101", + "type": "t_mapping(t_bytes32,t_struct(RoleData)747_storage)", + "contract": "AccessControlUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol:62" + }, + { + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)49_storage", + "contract": "AccessControlUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol:260" + }, + { + "label": "_pendingDefaultAdmin", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "AccessControlDefaultAdminRulesUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/AccessControlDefaultAdminRulesUpgradeable.sol:43" + }, + { + "label": "_pendingDefaultAdminSchedule", + "offset": 20, + "slot": "151", + "type": "t_uint48", + "contract": "AccessControlDefaultAdminRulesUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/AccessControlDefaultAdminRulesUpgradeable.sol:44" + }, + { + "label": "_currentDelay", + "offset": 26, + "slot": "151", + "type": "t_uint48", + "contract": "AccessControlDefaultAdminRulesUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/AccessControlDefaultAdminRulesUpgradeable.sol:46" + }, + { + "label": "_currentDefaultAdmin", + "offset": 0, + "slot": "152", + "type": "t_address", + "contract": "AccessControlDefaultAdminRulesUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/AccessControlDefaultAdminRulesUpgradeable.sol:47" + }, + { + "label": "_pendingDelay", + "offset": 20, + "slot": "152", + "type": "t_uint48", + "contract": "AccessControlDefaultAdminRulesUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/AccessControlDefaultAdminRulesUpgradeable.sol:50" + }, + { + "label": "_pendingDelaySchedule", + "offset": 26, + "slot": "152", + "type": "t_uint48", + "contract": "AccessControlDefaultAdminRulesUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/AccessControlDefaultAdminRulesUpgradeable.sol:51" + }, + { + "label": "__gap", + "offset": 0, + "slot": "153", + "type": "t_array(t_uint256)48_storage", + "contract": "AccessControlDefaultAdminRulesUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/AccessControlDefaultAdminRulesUpgradeable.sol:394" + }, + { + "label": "_paused", + "offset": 0, + "slot": "201", + "type": "t_bool", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" + }, + { + "label": "_index", + "offset": 0, + "slot": "251", + "type": "t_uint256", + "contract": "DLCManager", + "src": "contracts/DLCManager.sol:47" + }, { "label": "dlcs", "offset": 0, diff --git a/deploymentFiles/basesepolia/TimelockController.json b/deploymentFiles/basesepolia/TimelockController.json new file mode 100644 index 0000000..514c572 --- /dev/null +++ b/deploymentFiles/basesepolia/TimelockController.json @@ -0,0 +1,49 @@ +{ + "network": "basesepolia", + "updatedAt": "2024-10-08T16:47:01.355Z", + "gitSHA": "9c7dcb7", + "contract": { + "name": "TimelockController", + "address": "0x34E7e62bA1B1dD5c491d4e2e36f643CD415f72D5", + "signerAddress": "0x9506Ea24038609679732855F757041a3C1C06623", + "abi": [ + "constructor(uint256 minDelay, address[] proposers, address[] executors, address admin)", + "event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data)", + "event CallSalt(bytes32 indexed id, bytes32 salt)", + "event CallScheduled(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data, bytes32 predecessor, uint256 delay)", + "event Cancelled(bytes32 indexed id)", + "event MinDelayChange(uint256 oldDuration, uint256 newDuration)", + "event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole)", + "event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender)", + "event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender)", + "function CANCELLER_ROLE() view returns (bytes32)", + "function DEFAULT_ADMIN_ROLE() view returns (bytes32)", + "function EXECUTOR_ROLE() view returns (bytes32)", + "function PROPOSER_ROLE() view returns (bytes32)", + "function TIMELOCK_ADMIN_ROLE() view returns (bytes32)", + "function cancel(bytes32 id)", + "function execute(address target, uint256 value, bytes payload, bytes32 predecessor, bytes32 salt) payable", + "function executeBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) payable", + "function getMinDelay() view returns (uint256)", + "function getRoleAdmin(bytes32 role) view returns (bytes32)", + "function getTimestamp(bytes32 id) view returns (uint256)", + "function grantRole(bytes32 role, address account)", + "function hasRole(bytes32 role, address account) view returns (bool)", + "function hashOperation(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) pure returns (bytes32)", + "function hashOperationBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) pure returns (bytes32)", + "function isOperation(bytes32 id) view returns (bool)", + "function isOperationDone(bytes32 id) view returns (bool)", + "function isOperationPending(bytes32 id) view returns (bool)", + "function isOperationReady(bytes32 id) view returns (bool)", + "function onERC1155BatchReceived(address, address, uint256[], uint256[], bytes) returns (bytes4)", + "function onERC1155Received(address, address, uint256, uint256, bytes) returns (bytes4)", + "function onERC721Received(address, address, uint256, bytes) returns (bytes4)", + "function renounceRole(bytes32 role, address account)", + "function revokeRole(bytes32 role, address account)", + "function schedule(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt, uint256 delay)", + "function scheduleBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt, uint256 delay)", + "function supportsInterface(bytes4 interfaceId) view returns (bool)", + "function updateDelay(uint256 newDelay)" + ] + } +} diff --git a/scripts/50_contract-admin.js b/scripts/50_contract-admin.js index 1728507..2d5e145 100644 --- a/scripts/50_contract-admin.js +++ b/scripts/50_contract-admin.js @@ -241,6 +241,10 @@ module.exports = async function contractAdmin() { await saveDeploymentInfo( deploymentInfo(network, contractObject, contractName) ); + const contractConfig = contractConfigs.find( + (config) => config.name === contractName + ); + await contractConfig.verify(); } catch (error) { console.error(error); } @@ -256,6 +260,12 @@ module.exports = async function contractAdmin() { newImplementationAddress ); + console.log('Verifying new implementation...'); + await hardhat.run('verify:verify', { + address: newImplementationAddress, + }); + console.log('New implementation verified.'); + try { await hardhat.upgrades.upgradeProxy( proxyAddress, @@ -393,7 +403,18 @@ module.exports = async function contractAdmin() { console.log( chalk.bgYellow('Current ProxyAdmin owner:', currentAdmin) ); - if (currentAdmin == dlcAdminSafes.critical) return; + if (currentAdmin == dlcAdminSafes.critical) { + console.log( + chalk.bgRed( + 'Current ProxyAdmin owner is the Critical Multisig Already!' + ) + ); + if ( + (await promptUser('Are you sure you want to continue?')) === + false + ) + return; + } const newAdmin = await prompts({ type: 'text', diff --git a/scripts/helpers/safe-api-service.js b/scripts/helpers/safe-api-service.js index d1dd074..00cea1a 100644 --- a/scripts/helpers/safe-api-service.js +++ b/scripts/helpers/safe-api-service.js @@ -12,7 +12,10 @@ module.exports = async function safeContractProposal( signer, safeAddress ) { - const network = hardhat.network.name; + let network = hardhat.network.name; + + if (network === 'basesepolia') network = 'base-sepolia'; + console.log('Network', network); const ethAdapter = new EthersAdapter({ diff --git a/scripts/helpers/utils.js b/scripts/helpers/utils.js index 8628bc9..a1c989b 100644 --- a/scripts/helpers/utils.js +++ b/scripts/helpers/utils.js @@ -15,19 +15,6 @@ async function promptUser(message) { return response.continue; } -async function promptUserForNumber(message, defaultValue) { - if (process.env.CLI_MODE === 'noninteractive') { - return 0; - } - const response = await prompts({ - type: 'number', - name: 'number', - message, - initial: defaultValue, - }); - return response.number; -} - async function loadContractAddress(requirement, network) { const deployment = await loadDeploymentInfo(network, requirement); if (!deployment) { @@ -56,7 +43,6 @@ function getMinimumDelay(networkName) { module.exports = { promptUser, - promptUserForNumber, loadContractAddress, getMinimumDelay, }; diff --git a/scripts/test2.js b/scripts/test2.js new file mode 100644 index 0000000..484be14 --- /dev/null +++ b/scripts/test2.js @@ -0,0 +1,81 @@ +const hardhat = require('hardhat'); +const { promptUser, loadContractAddress } = require('./helpers/utils'); +const { + saveDeploymentInfo, + deploymentInfo, + loadDeploymentInfo, +} = require('./helpers/deployment-handlers_versioned'); +const proposeSafeTx = require('./helpers/safe-api-service'); + +async function main() { + await hardhat.run('compile'); + const accounts = await hardhat.ethers.getSigners(); + const deployer = accounts[0]; + const network = hardhat.network.name; + + const multisig = '0xebDC2027D3ee493B49553Befc1200e1cce9e2E08'; // basesep test + + const contractName = 'DLCManager'; + + const proxyContract = await loadContractAddress(contractName, network); + + const newImplementation = + await hardhat.ethers.getContractFactory(contractName); + console.log('Preparing upgrade...'); + const newImplementationAddress = await hardhat.upgrades.prepareUpgrade( + proxyContract, + newImplementation + ); + + console.log('Verifying new implementation...'); + await hardhat.run('verify:verify', { + address: newImplementationAddress, + }); + console.log('New implementation verified.'); + + const proxyAdmin = await hardhat.upgrades.admin.getInstance(); + const upgradeTx = await proxyAdmin.populateTransaction.upgrade( + proxyContract, + newImplementationAddress + ); + console.log('proxyContract', proxyContract); + console.log('newImplementationAddress', newImplementationAddress); + console.log('proxyAdmin.address', proxyAdmin.address); + console.log('upgradeTx', upgradeTx); + + // I want to call the TL contract to schedule the upgrade + const deployInfo = await loadDeploymentInfo(network, 'TimelockController'); + const timelockContract = new hardhat.ethers.Contract( + deployInfo.contract.address, + deployInfo.contract.abi, + deployer + ); + const timelockContractTxRequest = await timelockContract + .connect(deployer) + .populateTransaction[ + 'schedule' + ](proxyAdmin.address, 0, upgradeTx.data, '0x0000000000000000000000000000000000000000000000000000000000000000', '0x0000000000000000000000000000000000000000000000000000000000000000', 120); + console.log('timelockContractTxRequest', timelockContractTxRequest); + + await proposeSafeTx(timelockContractTxRequest, deployer, multisig); + + // After the delay period... + // const timelockContractTxRequestToExecute = await timelockContract + // .connect(deployer) + // .populateTransaction[ + // 'execute' + // ](proxyAdmin.address, 0, '0x99a88ec4000000000000000000000000050c24dbf1eec17babe5fc585f06116a259cc77a0000000000000000000000008f8625c2a9bc9770bcfe06aae1fcdd479fa60b83', '0x0000000000000000000000000000000000000000000000000000000000000000', '0x0000000000000000000000000000000000000000000000000000000000000000'); + // console.log( + // 'timelockContractTxRequestToExecute', + // timelockContractTxRequestToExecute + // ); + + // await proposeSafeTx(timelockContractTxRequestToExecute, deployer, multisig); +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + });