diff --git a/.openzeppelin/unknown-11155420.json b/.openzeppelin/unknown-11155420.json new file mode 100644 index 0000000..9ef3e5a --- /dev/null +++ b/.openzeppelin/unknown-11155420.json @@ -0,0 +1,338 @@ +{ + "manifestVersion": "3.2", + "proxies": [ + { + "address": "0x9C168ECBa01408DF02bd6C1C7A50EE0a63859b30", + "txHash": "0x8c67f928d82bd9106988a62626f9733f71d34e5136cc698dcd25f5b2d8ba4624", + "kind": "uups" + } + ], + "impls": { + "ffba80a60111f1737f38dce51bee86dfc90fd923770d821897056b42abfca104": { + "address": "0x789a96537e1808b9e6E895f61d2163074f2386f6", + "txHash": "0xa8688af36a55f10e605695c5b4d1ff0fc38b532d4818cd811d186d04ffc9326b", + "layout": { + "solcVersion": "0.8.17", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_balances", + "offset": 0, + "slot": "51", + "type": "t_mapping(t_address,t_uint256)", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:37" + }, + { + "label": "_allowances", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:39" + }, + { + "label": "_totalSupply", + "offset": 0, + "slot": "53", + "type": "t_uint256", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:41" + }, + { + "label": "_name", + "offset": 0, + "slot": "54", + "type": "t_string_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:43" + }, + { + "label": "_symbol", + "offset": 0, + "slot": "55", + "type": "t_string_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:44" + }, + { + "label": "__gap", + "offset": 0, + "slot": "56", + "type": "t_array(t_uint256)45_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:394" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC20BurnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol:51" + }, + { + "label": "_paused", + "offset": 0, + "slot": "151", + "type": "t_bool", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" + }, + { + "label": "__gap", + "offset": 0, + "slot": "201", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC165Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41" + }, + { + "label": "_roles", + "offset": 0, + "slot": "251", + "type": "t_mapping(t_bytes32,t_struct(RoleData)34_storage)", + "contract": "AccessControlUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol:61" + }, + { + "label": "__gap", + "offset": 0, + "slot": "252", + "type": "t_array(t_uint256)49_storage", + "contract": "AccessControlUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol:259" + }, + { + "label": "_HASHED_NAME", + "offset": 0, + "slot": "301", + "type": "t_bytes32", + "contract": "EIP712Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol:32" + }, + { + "label": "_HASHED_VERSION", + "offset": 0, + "slot": "302", + "type": "t_bytes32", + "contract": "EIP712Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol:33" + }, + { + "label": "__gap", + "offset": 0, + "slot": "303", + "type": "t_array(t_uint256)50_storage", + "contract": "EIP712Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol:120" + }, + { + "label": "_nonces", + "offset": 0, + "slot": "353", + "type": "t_mapping(t_address,t_struct(Counter)4520_storage)", + "contract": "ERC20PermitUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol:28" + }, + { + "label": "_PERMIT_TYPEHASH_DEPRECATED_SLOT", + "offset": 0, + "slot": "354", + "type": "t_bytes32", + "contract": "ERC20PermitUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol:40", + "renamedFrom": "_PERMIT_TYPEHASH" + }, + { + "label": "__gap", + "offset": 0, + "slot": "355", + "type": "t_array(t_uint256)49_storage", + "contract": "ERC20PermitUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol:108" + }, + { + "label": "__gap", + "offset": 0, + "slot": "404", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC20FlashMintUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20FlashMintUpgradeable.sol:108" + }, + { + "label": "__gap", + "offset": 0, + "slot": "454", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:211" + }, + { + "label": "__gap", + "offset": 0, + "slot": "504", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:107" + }, + { + "label": "_flashFee", + "offset": 0, + "slot": "554", + "type": "t_struct(Factor)11295_storage", + "contract": "Xocolatl", + "src": "contracts/Xocolatl.sol:44" + }, + { + "label": "flashFeeReceiver", + "offset": 0, + "slot": "556", + "type": "t_address", + "contract": "Xocolatl", + "src": "contracts/Xocolatl.sol:45" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)45_storage": { + "label": "uint256[45]", + "numberOfBytes": "1440" + }, + "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_mapping(t_address,t_bool)": { + "label": "mapping(address => bool)", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_struct(Counter)4520_storage)": { + "label": "mapping(address => struct CountersUpgradeable.Counter)", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_uint256)": { + "label": "mapping(address => uint256)", + "numberOfBytes": "32" + }, + "t_mapping(t_bytes32,t_struct(RoleData)34_storage)": { + "label": "mapping(bytes32 => struct AccessControlUpgradeable.RoleData)", + "numberOfBytes": "32" + }, + "t_string_storage": { + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(Counter)4520_storage": { + "label": "struct CountersUpgradeable.Counter", + "members": [ + { + "label": "_value", + "type": "t_uint256", + "offset": 0, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Factor)11295_storage": { + "label": "struct Xocolatl.Factor", + "members": [ + { + "label": "numerator", + "type": "t_uint256", + "offset": 0, + "slot": "0" + }, + { + "label": "denominator", + "type": "t_uint256", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_struct(RoleData)34_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_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } + } + } +} diff --git a/hardhat.config.js b/hardhat.config.js index 42b826c..7ba08d5 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -108,6 +108,11 @@ module.exports = { url: `https://rpc.scroll.io/`, accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : {mnemonic: mnemonic()}, }, + optimism_sepolia: { + url: "https://sepolia.optimism.io", + accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : {mnemonic: mnemonic()}, + chainId: 11155420, + }, }, sourcify: { enabled: true, @@ -139,6 +144,14 @@ module.exports = { browserURL: "https://basescan.org/", }, }, + { + network: "optimismSepolia", + chainId: 11155420, + urls: { + apiURL: "https://api-sepolia-optimistic.etherscan.io/api", + browserURL: "https://sepolia-optimism.etherscan.io/", + }, + }, ], }, }; diff --git a/scripts/const.js b/scripts/const.js index 427e1d8..5301e6d 100644 --- a/scripts/const.js +++ b/scripts/const.js @@ -10,6 +10,7 @@ const LADAO_MULTISIGS = { linea: "", polygonzkevm: "", scroll: "0x840A6f02e31eBa9761Ceb18471524B71B506E7F4", + optimismSepolia: "0x5B2aE816E92bE1b8022dC13eAB9fd77e3232e9C8", }; const CONTRACT_DEPLOYER_FACTORY = "0xF8faF9319e5CDDfda173B0a6461f19765AAAbf03"; @@ -192,6 +193,14 @@ const ASSETS = { }, }, }, + optimismSepolia: { + weth: { + address: "0x4200000000000000000000000000000000000006", + storageSlots: { + balanceOf: 3, + }, + }, + }, }; const ORACLE_CONTRACTS = { @@ -254,6 +263,11 @@ const ORACLE_CONTRACTS = { pyth: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", ethusd: "0x6bF14CB0A831078629D993FDeBcB182b21A8774C", }, + optimismSepolia: { + sequencer: "0xAaa227BEC672216a007755878f6b5bB8776f52CC", // mock sequencer uptime contract + pyth: "0x0708325268dF9F66270F1401206434524814508b", + ethusd: "0x61Ec26aA57019C486B10502285c5A3D4A4750AD7", + }, }; const TLATLALIANI_CONTRACTS = { diff --git a/scripts/optimismsepolia/00_deploy_xocolatl.js b/scripts/optimismsepolia/00_deploy_xocolatl.js new file mode 100644 index 0000000..be6a15b --- /dev/null +++ b/scripts/optimismsepolia/00_deploy_xocolatl.js @@ -0,0 +1,28 @@ +const {NETWORK, setDeploymentsPath, setPublishPath, publishUpdates} = require("../utils"); +const {VERSION} = require("./utils_optimismsepolia"); + +const {deployXocolatl} = require("../tasks/deployXocolatl"); +const {handOverDefaultAdmin} = require("../tasks/rolesHandOver"); + +const deployBackedAsset = async () => { + console.log("\n\n 📡 Deploying...\n"); + const xoc = await deployXocolatl(); + await handOverDefaultAdmin(xoc); +}; + +const main = async () => { + if (NETWORK !== "optimismSepolia") { + throw new Error("Set 'NETWORK=optimismSepolia' in .env file"); + } + await setDeploymentsPath(VERSION); + await setPublishPath(VERSION); + await deployBackedAsset(); + await publishUpdates(); +}; + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(`\n${error}\n`); + process.exit(1); + }); diff --git a/scripts/optimismsepolia/01_deploy_system.js b/scripts/optimismsepolia/01_deploy_system.js new file mode 100644 index 0000000..04730a3 --- /dev/null +++ b/scripts/optimismsepolia/01_deploy_system.js @@ -0,0 +1,95 @@ +const {NETWORK, getContract, setDeploymentsPath, setPublishPath, publishUpdates} = require("../utils"); +const {TREASURY, RESERVE_CAPS, VERSION, WNATIVE} = require("./utils_optimismsepolia"); +const {deployAccountLiquidator} = require("../tasks/deployAccountLiquidator"); +const {deployAssetsAccountant} = require("../tasks/deployAssetsAccountant"); +const {deployHouseOfCoin} = require("../tasks/deployHouseOfCoin"); +const {deployHouseOfReserveImplementation} = require("../tasks/deployHouseOfReserve"); +const {deployOracleFactoryL2} = require("../tasks/deployOracleFactoryL2"); +const {deployOracleImplementations} = require("../tasks/deployOracleImplementations"); +const {deployReserveBeaconFactory} = require("../tasks/deployReserveBeaconFactory"); +const {ORACLE_CONTRACTS} = require("../const"); +const {rolesHandOverAssetsAccountant, handOverOwnership} = require("../tasks/rolesHandOver"); +const {setUpAssetsAccountant} = require("../tasks/setUpAssetsAccountant"); +const {setupOracleFactory} = require("../tasks/setupOracleFactory"); +const {deployUsdMxnPythWrapper} = require("../tasks/deployUsdMxnPythWrapper"); +const {deployReserveViaFactory} = require("../tasks/deployReserveViaFactory"); + +const deploySystemContracts = async () => { + console.log("\n\n 📡 Deploying...\n"); + xoc = await getContract("Xocolatl", "Xocolatl"); + console.log("xoc", await xoc.getAddress()); + + const accountant = await deployAssetsAccountant(); + + const coinhouse = await deployHouseOfCoin(await xoc.getAddress(), await accountant.getAddress(), TREASURY); + const reservehouseImpl = await deployHouseOfReserveImplementation(); + const factory = await deployReserveBeaconFactory( + await reservehouseImpl.getAddress(), + await xoc.getAddress(), + await accountant.getAddress(), + WNATIVE, + ); + const liquidator = await deployAccountLiquidator(await coinhouse.getAddress(), await accountant.getAddress()); + + await setUpAssetsAccountant( + accountant, + await coinhouse.getAddress(), + await liquidator.getAddress(), + await factory.getAddress(), + ); + + const {computedPriceFeedImpl, invPriceFeedImpl, priceFeedPythWrapperImpl} = await deployOracleImplementations([ + "ComputedPriceFeedWithSequencer", + "InversePriceFeed", + "PriceFeedPythWrapper", + ]); + + const oracleFactory = await deployOracleFactoryL2(); + await setupOracleFactory(oracleFactory, computedPriceFeedImpl, invPriceFeedImpl, priceFeedPythWrapperImpl); + const pythWrapperUsdMxn = await deployUsdMxnPythWrapper(oracleFactory, ORACLE_CONTRACTS[NETWORK].pyth); + console.log("last inside deploy system"); + const reservehouseWeth = await deployReserveViaFactory( + factory, + oracleFactory, + WNATIVE, + RESERVE_CAPS.weth.defaultInitialLimit, + ethers.parseUnits("0.8", 18), + ethers.parseUnits("0.85", 18), + 15000, + await pythWrapperUsdMxn.getAddress(), + ORACLE_CONTRACTS[NETWORK].ethusd, + ); + + await rolesHandOverAssetsAccountant(accountant); + await handOverOwnership(coinhouse); + await handOverOwnership(factory); + await handOverOwnership(oracleFactory); + await handOverOwnership(liquidator); + await handOverOwnership(reservehouseWeth); + + // In addition the multisig needs to queue + // 1.- Xocolatl contract grants minter role to Coinhouse + // 2.- Xocolatl contract grants burner role to Coinhouse + // 3.- Xocolatl contract grants burner role to Liquidator + // For example: + // await xoc.grantRole(minter, await coinhouse.getAddress()); + // await xoc.grantRole(burner, await coinhouse.getAddress()); + // await xoc.grantRole(burner, await liquidator.getAddress()); +}; + +const main = async () => { + if (NETWORK !== "optimismSepolia") { + throw new Error("Set 'NETWORK=optimismSepolia' in .env file"); + } + await setDeploymentsPath(VERSION); + await setPublishPath(VERSION); + await deploySystemContracts(); + await publishUpdates(); +}; + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(`\n${error}\n`); + process.exit(1); + }); diff --git a/scripts/optimismsepolia/utils_optimismsepolia.js b/scripts/optimismsepolia/utils_optimismsepolia.js new file mode 100644 index 0000000..e1204d8 --- /dev/null +++ b/scripts/optimismsepolia/utils_optimismsepolia.js @@ -0,0 +1,27 @@ +const {ethers} = require("hardhat"); +const {ASSETS, LADAO_MULTISIGS} = require("../const"); + +const VERSION = "2.0.0"; + +const RESERVE_CAPS = { + weth: { + defaultInitialLimit: ethers.parseUnits("5", 18), + }, + wsteth: { + defaultInitialLimit: ethers.parseUnits("5", 18), + }, + op: { + defaultInitialLimit: ethers.parseUnits("5000", 18), + }, +}; + +const WNATIVE = ASSETS.optimismSepolia.weth.address; +const TREASURY = LADAO_MULTISIGS.optimismSepolia; + +module.exports = { + VERSION, + WNATIVE, + RESERVE_CAPS, + ASSETS, + TREASURY, +};