Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m3s
CI/CD Pipeline / Security Scanning (push) Successful in 2m18s
CI/CD Pipeline / Lint and Format (push) Failing after 34s
CI/CD Pipeline / Terraform Validation (push) Failing after 20s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 22s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 40s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 49s
OMNL reconcile anchor / Run omnl:reconcile and upload artifacts (push) Failing after 21s
Validation / validate-genesis (push) Successful in 25s
Validation / validate-terraform (push) Failing after 21s
Validation / validate-kubernetes (push) Failing after 8s
Validation / validate-smart-contracts (push) Failing after 8s
Validation / validate-security (push) Failing after 1m11s
Validation / validate-documentation (push) Failing after 14s
Verify Deployment / Verify Deployment (push) Failing after 45s
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m3s
CI/CD Pipeline / Security Scanning (push) Successful in 2m18s
CI/CD Pipeline / Lint and Format (push) Failing after 34s
CI/CD Pipeline / Terraform Validation (push) Failing after 20s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 22s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 40s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 49s
OMNL reconcile anchor / Run omnl:reconcile and upload artifacts (push) Failing after 21s
Validation / validate-genesis (push) Successful in 25s
Validation / validate-terraform (push) Failing after 21s
Validation / validate-kubernetes (push) Failing after 8s
Validation / validate-smart-contracts (push) Failing after 8s
Validation / validate-security (push) Failing after 1m11s
Validation / validate-documentation (push) Failing after 14s
Verify Deployment / Verify Deployment (push) Failing after 45s
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface, checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services, relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
26
script/DeployCCIPRelayBridgeLINK.s.sol
Normal file
26
script/DeployCCIPRelayBridgeLINK.s.sol
Normal file
@@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {CCIPRelayRouter} from "../contracts/relay/CCIPRelayRouter.sol";
|
||||
import {CCIPRelayBridgeLINK} from "../contracts/relay/CCIPRelayBridgeLINK.sol";
|
||||
|
||||
/// @notice Deploy CCIPRelayBridgeLINK on destination chain and authorize on existing CCIPRelayRouter.
|
||||
/// Env: PRIVATE_KEY, LINK_TOKEN_MAINNET (or DEST_LINK_ADDRESS), CCIP_RELAY_ROUTER_MAINNET
|
||||
contract DeployCCIPRelayBridgeLINK is Script {
|
||||
function run() external {
|
||||
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
|
||||
address link = vm.envAddress("LINK_TOKEN_MAINNET");
|
||||
address relayRouter = vm.envAddress("CCIP_RELAY_ROUTER_MAINNET");
|
||||
|
||||
vm.startBroadcast(deployerPrivateKey);
|
||||
|
||||
CCIPRelayBridgeLINK linkBridge = new CCIPRelayBridgeLINK(link, relayRouter);
|
||||
console.log("CCIPRelayBridgeLINK:", address(linkBridge));
|
||||
|
||||
CCIPRelayRouter(relayRouter).authorizeBridge(address(linkBridge));
|
||||
console.log("Authorized on CCIPRelayRouter:", relayRouter);
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
45
script/FundBridgeLinkViaCcip138.s.sol
Normal file
45
script/FundBridgeLinkViaCcip138.s.sol
Normal file
@@ -0,0 +1,45 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import {IRouterClient} from "../contracts/ccip/IRouterClient.sol";
|
||||
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
/// @notice CCIP-send Chain 138 LINK to a destination-chain bridge contract (operator funding).
|
||||
/// Env: PRIVATE_KEY, CCIP_ROUTER_CHAIN138, LINK_TOKEN_CHAIN138, DEST_SELECTOR, DEST_BRIDGE, LINK_AMOUNT_WEI
|
||||
contract FundBridgeLinkViaCcip138 is Script {
|
||||
function run() external {
|
||||
uint256 deployerKey = vm.envUint("PRIVATE_KEY");
|
||||
address router = vm.envAddress("CCIP_ROUTER_CHAIN138");
|
||||
address link = vm.envAddress("LINK_TOKEN_CHAIN138");
|
||||
uint64 destSelector = uint64(vm.envUint("DEST_SELECTOR"));
|
||||
address destBridge = vm.envAddress("DEST_BRIDGE");
|
||||
uint256 amount = vm.envUint("LINK_AMOUNT_WEI");
|
||||
|
||||
IRouterClient.TokenAmount[] memory tokenAmounts = new IRouterClient.TokenAmount[](1);
|
||||
tokenAmounts[0] = IRouterClient.TokenAmount({
|
||||
token: link,
|
||||
amount: amount,
|
||||
amountType: IRouterClient.TokenAmountType.Fiat
|
||||
});
|
||||
|
||||
IRouterClient.EVM2AnyMessage memory message = IRouterClient.EVM2AnyMessage({
|
||||
receiver: abi.encode(destBridge),
|
||||
data: "",
|
||||
tokenAmounts: tokenAmounts,
|
||||
feeToken: link,
|
||||
extraArgs: ""
|
||||
});
|
||||
|
||||
uint256 fee = IRouterClient(router).getFee(destSelector, message);
|
||||
console2.log("destBridge", destBridge);
|
||||
console2.log("amount", amount);
|
||||
console2.log("fee", fee);
|
||||
|
||||
vm.startBroadcast(deployerKey);
|
||||
IERC20(link).approve(router, amount + fee);
|
||||
(bytes32 messageId,) = IRouterClient(router).ccipSend(destSelector, message);
|
||||
console2.logBytes32(messageId);
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
42
script/FundBridgeLinkViaCcipMainnet.s.sol
Normal file
42
script/FundBridgeLinkViaCcipMainnet.s.sol
Normal file
@@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import {IRouterClient} from "@chainlink/contracts-ccip/contracts/interfaces/IRouterClient.sol";
|
||||
import {Client} from "@chainlink/contracts-ccip/contracts/libraries/Client.sol";
|
||||
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
/// @notice CCIP-send canonical mainnet LINK to a destination-chain bridge contract.
|
||||
/// Env: PRIVATE_KEY, CCIP_ROUTER_MAINNET, LINK_TOKEN_MAINNET, DEST_SELECTOR, DEST_BRIDGE, LINK_AMOUNT_WEI
|
||||
contract FundBridgeLinkViaCcipMainnet is Script {
|
||||
function run() external {
|
||||
uint256 deployerKey = vm.envUint("PRIVATE_KEY");
|
||||
address router = vm.envAddress("CCIP_ROUTER_MAINNET");
|
||||
address link = vm.envAddress("LINK_TOKEN_MAINNET");
|
||||
uint64 destSelector = uint64(vm.envUint("DEST_SELECTOR"));
|
||||
address destBridge = vm.envAddress("DEST_BRIDGE");
|
||||
uint256 amount = vm.envUint("LINK_AMOUNT_WEI");
|
||||
|
||||
Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1);
|
||||
tokenAmounts[0] = Client.EVMTokenAmount({token: link, amount: amount});
|
||||
|
||||
Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({
|
||||
receiver: abi.encode(destBridge),
|
||||
data: "",
|
||||
tokenAmounts: tokenAmounts,
|
||||
feeToken: link,
|
||||
extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 200_000}))
|
||||
});
|
||||
|
||||
uint256 fee = IRouterClient(router).getFee(destSelector, message);
|
||||
console2.log("destBridge", destBridge);
|
||||
console2.log("amount", amount);
|
||||
console2.log("fee", fee);
|
||||
|
||||
vm.startBroadcast(deployerKey);
|
||||
IERC20(link).approve(router, amount + fee);
|
||||
bytes32 messageId = IRouterClient(router).ccipSend(destSelector, message);
|
||||
console2.logBytes32(messageId);
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
49
script/bridge/trustless/DeployChain138StabilizerFinish.s.sol
Normal file
49
script/bridge/trustless/DeployChain138StabilizerFinish.s.sol
Normal file
@@ -0,0 +1,49 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {Stabilizer} from "../../../contracts/bridge/trustless/integration/Stabilizer.sol";
|
||||
import {StablecoinPegManager} from "../../../contracts/bridge/trustless/integration/StablecoinPegManager.sol";
|
||||
import {CommodityPegManager} from "../../../contracts/bridge/trustless/integration/CommodityPegManager.sol";
|
||||
|
||||
/// @notice Finish Chain 138 Stabilizer stack after peg managers are already deployed.
|
||||
/// @dev Env: STABLECOIN_PEG_MANAGER, COMMODITY_PEG_MANAGER, PRIVATE_POOL_REGISTRY, PRIVATE_KEY
|
||||
contract DeployChain138StabilizerFinish is Script {
|
||||
function run() external {
|
||||
require(block.chainid == 138, "chain138 only");
|
||||
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.envOr("STABILIZER_ADMIN", vm.addr(pk));
|
||||
address privatePoolRegistry = vm.envAddress("PRIVATE_POOL_REGISTRY");
|
||||
address stablecoinPeg = vm.envAddress("STABLECOIN_PEG_MANAGER");
|
||||
address commodityPeg = vm.envAddress("COMMODITY_PEG_MANAGER");
|
||||
|
||||
address cUsdc = vm.envOr("COMPLIANT_USDC_ADDRESS", vm.envOr("CUSDC_ADDRESS_138", address(0)));
|
||||
address cUsdt = vm.envOr("COMPLIANT_USDT_ADDRESS", vm.envOr("CUSDT_ADDRESS_138", address(0)));
|
||||
address weth = vm.envOr("WETH9", address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2));
|
||||
address xau = vm.envOr("XAU_ADDRESS_138", vm.envOr("cXAUC_ADDRESS_138", address(0x290E52a8819A4fbD0714E517225429aA2B70EC6b)));
|
||||
|
||||
StablecoinPegManager spm = StablecoinPegManager(stablecoinPeg);
|
||||
CommodityPegManager cpm = CommodityPegManager(commodityPeg);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
spm.registerWETH(weth);
|
||||
if (xau != address(0)) {
|
||||
cpm.setXAUAddress(xau);
|
||||
cpm.registerCommodity(xau, "XAU", 1e18);
|
||||
}
|
||||
|
||||
Stabilizer stabilizer = new Stabilizer(admin, privatePoolRegistry);
|
||||
stabilizer.setStablecoinPegSource(stablecoinPeg, cUsdc != address(0) ? cUsdc : cUsdt);
|
||||
if (xau != address(0)) {
|
||||
stabilizer.setCommodityPegSource(commodityPeg, xau);
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console2.log("Stabilizer", address(stabilizer));
|
||||
console2.log("StablecoinPegManager", stablecoinPeg);
|
||||
console2.log("CommodityPegManager", commodityPeg);
|
||||
}
|
||||
}
|
||||
57
script/bridge/trustless/DeployChain138StabilizerStack.s.sol
Normal file
57
script/bridge/trustless/DeployChain138StabilizerStack.s.sol
Normal file
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import "../../../contracts/bridge/trustless/integration/Stabilizer.sol";
|
||||
import "../../../contracts/bridge/trustless/integration/StablecoinPegManager.sol";
|
||||
import "../../../contracts/bridge/trustless/integration/CommodityPegManager.sol";
|
||||
|
||||
/// @notice Deploy peg managers + Stabilizer on Chain 138 (Defi Oracle Meta).
|
||||
/// @dev Requires PRIVATE_KEY, RESERVE_SYSTEM, PRIVATE_POOL_REGISTRY; optional STABILIZER_ADMIN, XAU peg asset.
|
||||
contract DeployChain138StabilizerStack is Script {
|
||||
function run() external {
|
||||
require(block.chainid == 138, "chain138 only");
|
||||
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address admin = vm.envOr("STABILIZER_ADMIN", deployer);
|
||||
address reserveSystem = vm.envAddress("RESERVE_SYSTEM");
|
||||
address privatePoolRegistry = vm.envAddress("PRIVATE_POOL_REGISTRY");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
StablecoinPegManager stablecoinPeg = new StablecoinPegManager(reserveSystem);
|
||||
CommodityPegManager commodityPeg = new CommodityPegManager(reserveSystem);
|
||||
|
||||
address cUsdc = vm.envOr("COMPLIANT_USDC_ADDRESS", vm.envOr("CUSDC_ADDRESS_138", address(0)));
|
||||
address cUsdt = vm.envOr("COMPLIANT_USDT_ADDRESS", vm.envOr("CUSDT_ADDRESS_138", address(0)));
|
||||
address weth = vm.envOr("WETH9", address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2));
|
||||
address xau = vm.envOr("XAU_ADDRESS_138", vm.envOr("cXAUC_ADDRESS_138", address(0x290E52a8819A4fbD0714E517225429aA2B70EC6b)));
|
||||
|
||||
if (cUsdc != address(0)) {
|
||||
stablecoinPeg.registerUSDStablecoin(cUsdc);
|
||||
}
|
||||
if (cUsdt != address(0)) {
|
||||
stablecoinPeg.registerUSDStablecoin(cUsdt);
|
||||
}
|
||||
stablecoinPeg.registerWETH(weth);
|
||||
|
||||
if (xau != address(0)) {
|
||||
commodityPeg.setXAUAddress(xau);
|
||||
commodityPeg.registerCommodity(xau, "XAU", 1e18);
|
||||
}
|
||||
|
||||
Stabilizer stabilizer = new Stabilizer(admin, privatePoolRegistry);
|
||||
stabilizer.setStablecoinPegSource(address(stablecoinPeg), cUsdc != address(0) ? cUsdc : cUsdt);
|
||||
if (xau != address(0)) {
|
||||
stabilizer.setCommodityPegSource(address(commodityPeg), xau);
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console2.log("StablecoinPegManager", address(stablecoinPeg));
|
||||
console2.log("CommodityPegManager", address(commodityPeg));
|
||||
console2.log("Stabilizer", address(stabilizer));
|
||||
console2.log("admin", admin);
|
||||
}
|
||||
}
|
||||
230
script/deploy/rwa/DeployRWATokenFactory138.s.sol
Normal file
230
script/deploy/rwa/DeployRWATokenFactory138.s.sol
Normal file
@@ -0,0 +1,230 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import {RWATokenRegistry} from "../../../contracts/rwa/RWATokenRegistry.sol";
|
||||
import {RWATokenFactory} from "../../../contracts/rwa/RWATokenFactory.sol";
|
||||
import {IRWATokenFactory} from "../../../contracts/rwa/IRWATokenFactory.sol";
|
||||
import {RWAToken} from "../../../contracts/rwa/RWAToken.sol";
|
||||
import {UniversalAssetRegistry} from "../../../contracts/registry/UniversalAssetRegistry.sol";
|
||||
|
||||
/**
|
||||
* @title DeployRWATokenFactory138
|
||||
* @notice Deploy RWATokenRegistry + RWATokenFactory and optionally all five Li* M00 indices on Chain 138.
|
||||
* @dev Taxonomy: config/rwa-capital-markets-taxonomy.v1.json. Not for c* eMoney (use DeployCompliantFiatTokens).
|
||||
*
|
||||
* Env:
|
||||
* PRIVATE_KEY, OWNER, ADMIN, COMPLIANCE_ADMIN, INDEX_PUBLISHER
|
||||
* UNIVERSAL_ASSET_REGISTRY (optional; pass address for factory wiring only)
|
||||
* REGISTER_IN_UAR — default 0; use RegisterRWAIndicesInUAR138.s.sol after REGISTRAR_ROLE grant
|
||||
* DEPLOY_LI_INDICES=1 to deploy LiXAU, LiPMG, LiBMG1–3 in one run
|
||||
* RWA_INITIAL_INDEX_VALUE (default 1e6 = 1.0 at 6 decimals)
|
||||
* RWA_INITIAL_SUPPLY (default 0 — mint via policy after index committee attestation)
|
||||
* RWA_METHODOLOGY_HASH (required for DEPLOY_LI_INDICES; default from m00-li-index-methodology-hash.v1.json via cast)
|
||||
* MULTISIG_ADMIN (optional) — grant factory DEPLOYER + registry/UAR REGISTRAR to multisig
|
||||
*/
|
||||
contract DeployRWATokenFactory138 is Script {
|
||||
uint8 constant DECIMALS = 6;
|
||||
uint256 constant DEFAULT_INDEX_VALUE = 1_000_000;
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address owner = vm.envOr("OWNER", deployer);
|
||||
address compliance = vm.envOr("COMPLIANCE_ADMIN", deployer);
|
||||
address publisher = vm.envOr("INDEX_PUBLISHER", deployer);
|
||||
address uar = vm.envOr("UNIVERSAL_ASSET_REGISTRY", address(0));
|
||||
// UAR registration reverts if factory lacks REGISTRAR_ROLE — keep off during one-shot deploy.
|
||||
bool registerInUar = vm.envOr("REGISTER_IN_UAR", uint256(0)) != 0;
|
||||
require(
|
||||
!registerInUar || uar != address(0),
|
||||
"REGISTER_IN_UAR requires UNIVERSAL_ASSET_REGISTRY"
|
||||
);
|
||||
uint256 initialIndexValue = vm.envOr("RWA_INITIAL_INDEX_VALUE", DEFAULT_INDEX_VALUE);
|
||||
uint256 initialSupply = vm.envOr("RWA_INITIAL_SUPPLY", uint256(0));
|
||||
address multisig = vm.envOr("MULTISIG_ADMIN", address(0));
|
||||
address governance = vm.envOr("GOVERNANCE_CONTROLLER", address(0));
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
// Deployer holds DEFAULT_ADMIN during bootstrap so grants succeed in one broadcast.
|
||||
RWATokenRegistry registry = new RWATokenRegistry(deployer);
|
||||
RWATokenFactory factory = new RWATokenFactory(deployer, address(registry), uar);
|
||||
registry.grantRole(registry.REGISTRAR_ROLE(), address(factory));
|
||||
|
||||
if (registerInUar && uar != address(0)) {
|
||||
UniversalAssetRegistry(uar).grantRole(
|
||||
UniversalAssetRegistry(uar).REGISTRAR_ROLE(),
|
||||
address(factory)
|
||||
);
|
||||
}
|
||||
|
||||
if (multisig != address(0)) {
|
||||
factory.grantRole(factory.DEPLOYER_ROLE(), multisig);
|
||||
registry.grantRole(registry.REGISTRAR_ROLE(), multisig);
|
||||
}
|
||||
if (governance != address(0)) {
|
||||
factory.grantRole(factory.DEFAULT_ADMIN_ROLE(), governance);
|
||||
registry.grantRole(registry.DEFAULT_ADMIN_ROLE(), governance);
|
||||
}
|
||||
|
||||
console.log("RWATokenRegistry", address(registry));
|
||||
console.log("RWATokenFactory", address(factory));
|
||||
|
||||
if (vm.envOr("DEPLOY_LI_INDICES", uint256(0)) != 0) {
|
||||
bytes32 methodologyHash = _resolveMethodologyHash();
|
||||
_deployAllLi(
|
||||
factory,
|
||||
owner,
|
||||
compliance,
|
||||
publisher,
|
||||
initialIndexValue,
|
||||
initialSupply,
|
||||
registerInUar,
|
||||
methodologyHash
|
||||
);
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
function _resolveMethodologyHash() internal view returns (bytes32) {
|
||||
string memory envHash = vm.envOr("RWA_METHODOLOGY_HASH", string(""));
|
||||
if (bytes(envHash).length > 0) {
|
||||
return vm.parseBytes32(envHash);
|
||||
}
|
||||
revert("RWA_METHODOLOGY_HASH required when DEPLOY_LI_INDICES=1");
|
||||
}
|
||||
|
||||
function _deployAllLi(
|
||||
RWATokenFactory factory,
|
||||
address owner,
|
||||
address compliance,
|
||||
address publisher,
|
||||
uint256 initialIndexValue,
|
||||
uint256 initialSupply,
|
||||
bool registerInUar,
|
||||
bytes32 methodologyHash
|
||||
) internal {
|
||||
_deployLi(
|
||||
factory,
|
||||
owner,
|
||||
compliance,
|
||||
publisher,
|
||||
"LiXAU",
|
||||
"XAU Liquidity Index (M00)",
|
||||
"LiXAU",
|
||||
"Precious Metals",
|
||||
"Commodity Index",
|
||||
"Gold",
|
||||
initialIndexValue,
|
||||
initialSupply,
|
||||
registerInUar,
|
||||
methodologyHash
|
||||
);
|
||||
_deployLi(
|
||||
factory,
|
||||
owner,
|
||||
compliance,
|
||||
publisher,
|
||||
"LiPMG",
|
||||
"Precious Metals Group Index (M00)",
|
||||
"LiPMG",
|
||||
"Precious Metals",
|
||||
"Basket Index",
|
||||
"Precious Metals",
|
||||
initialIndexValue,
|
||||
initialSupply,
|
||||
registerInUar,
|
||||
methodologyHash
|
||||
);
|
||||
_deployLi(
|
||||
factory,
|
||||
owner,
|
||||
compliance,
|
||||
publisher,
|
||||
"LiBMG1",
|
||||
"Base Metals Group Index 1 (M00)",
|
||||
"LiBMG1",
|
||||
"Industrial Metals",
|
||||
"Basket Index",
|
||||
"Base Metals",
|
||||
initialIndexValue,
|
||||
initialSupply,
|
||||
registerInUar,
|
||||
methodologyHash
|
||||
);
|
||||
_deployLi(
|
||||
factory,
|
||||
owner,
|
||||
compliance,
|
||||
publisher,
|
||||
"LiBMG2",
|
||||
"Base Metals Group Index 2 (M00)",
|
||||
"LiBMG2",
|
||||
"Industrial Metals",
|
||||
"Basket Index",
|
||||
"Battery Materials",
|
||||
initialIndexValue,
|
||||
initialSupply,
|
||||
registerInUar,
|
||||
methodologyHash
|
||||
);
|
||||
_deployLi(
|
||||
factory,
|
||||
owner,
|
||||
compliance,
|
||||
publisher,
|
||||
"LiBMG3",
|
||||
"Base Metals Group Index 3 (M00)",
|
||||
"LiBMG3",
|
||||
"Industrial Metals",
|
||||
"Basket Index",
|
||||
"Building Metals",
|
||||
initialIndexValue,
|
||||
initialSupply,
|
||||
registerInUar,
|
||||
methodologyHash
|
||||
);
|
||||
}
|
||||
|
||||
function _deployLi(
|
||||
RWATokenFactory factory,
|
||||
address owner,
|
||||
address compliance,
|
||||
address publisher,
|
||||
string memory ticker,
|
||||
string memory name,
|
||||
string memory symbol,
|
||||
string memory assetGroup,
|
||||
string memory instrumentType,
|
||||
string memory underlying,
|
||||
uint256 initialIndexValue,
|
||||
uint256 initialSupply,
|
||||
bool registerInUar,
|
||||
bytes32 methodologyHash
|
||||
) internal {
|
||||
address token = factory.deployRWAIndex(
|
||||
IRWATokenFactory.RWAProductConfig({
|
||||
indexTicker: ticker,
|
||||
name: name,
|
||||
symbol: symbol,
|
||||
decimals: DECIMALS,
|
||||
assetClass: "Commodities",
|
||||
assetGroup: assetGroup,
|
||||
instrumentType: instrumentType,
|
||||
underlyingAsset: underlying,
|
||||
gruLayer: "M00",
|
||||
jurisdiction: "International",
|
||||
initialOwner: owner,
|
||||
complianceAdmin: compliance,
|
||||
indexPublisher: publisher,
|
||||
initialIndexValue: initialIndexValue,
|
||||
initialSupply: initialSupply,
|
||||
methodologyDocumentHash: methodologyHash,
|
||||
registerInUniversalAssetRegistry: registerInUar
|
||||
})
|
||||
);
|
||||
console.log(ticker, token);
|
||||
}
|
||||
}
|
||||
68
script/deploy/rwa/RegisterRWAIndicesInUAR138.s.sol
Normal file
68
script/deploy/rwa/RegisterRWAIndicesInUAR138.s.sol
Normal file
@@ -0,0 +1,68 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import {RWATokenRegistry} from "../../../contracts/rwa/RWATokenRegistry.sol";
|
||||
import {UniversalAssetRegistry} from "../../../contracts/registry/UniversalAssetRegistry.sol";
|
||||
import {IRWAToken} from "../../../contracts/rwa/IRWAToken.sol";
|
||||
|
||||
/**
|
||||
* @title RegisterRWAIndicesInUAR138
|
||||
* @notice Register deployed Li* tokens in UniversalAssetRegistry (run after factory deploy + REGISTRAR_ROLE grant).
|
||||
* @dev Requires RWA_TOKEN_REGISTRY and UNIVERSAL_ASSET_REGISTRY. Broadcaster must hold UAR REGISTRAR_ROLE
|
||||
* or factory must have been granted REGISTRAR_ROLE and this script calls via factory (not implemented — direct UAR calls).
|
||||
*
|
||||
* Env: PRIVATE_KEY, RWA_TOKEN_REGISTRY, UNIVERSAL_ASSET_REGISTRY
|
||||
* Optional: LI_TICKERS=LiXAU,LiPMG,LiBMG1,LiBMG2,LiBMG3 (default all five)
|
||||
*/
|
||||
contract RegisterRWAIndicesInUAR138 is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address registryAddr = vm.envAddress("RWA_TOKEN_REGISTRY");
|
||||
address uarAddr = vm.envAddress("UNIVERSAL_ASSET_REGISTRY");
|
||||
|
||||
RWATokenRegistry registry = RWATokenRegistry(registryAddr);
|
||||
UniversalAssetRegistry uar = UniversalAssetRegistry(uarAddr);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
string memory tickersEnv = vm.envOr("LI_TICKERS", string(""));
|
||||
if (bytes(tickersEnv).length > 0) {
|
||||
string[] memory parts = vm.split(tickersEnv, ",");
|
||||
for (uint256 i = 0; i < parts.length; i++) {
|
||||
_registerOne(registry, uar, parts[i]);
|
||||
}
|
||||
} else {
|
||||
_registerOne(registry, uar, "LiXAU");
|
||||
_registerOne(registry, uar, "LiPMG");
|
||||
_registerOne(registry, uar, "LiBMG1");
|
||||
_registerOne(registry, uar, "LiBMG2");
|
||||
_registerOne(registry, uar, "LiBMG3");
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
function _registerOne(RWATokenRegistry registry, UniversalAssetRegistry uar, string memory ticker) internal {
|
||||
address token = registry.getToken(ticker);
|
||||
require(token != address(0), "token missing");
|
||||
IRWAToken rwa = IRWAToken(token);
|
||||
uar.registerRWAIndexAsset(
|
||||
token,
|
||||
_nameFor(ticker),
|
||||
ticker,
|
||||
6,
|
||||
"International"
|
||||
);
|
||||
console.log("UAR registered", ticker, token);
|
||||
}
|
||||
|
||||
function _nameFor(string memory ticker) internal pure returns (string memory) {
|
||||
if (keccak256(bytes(ticker)) == keccak256("LiXAU")) return "XAU Liquidity Index (M00)";
|
||||
if (keccak256(bytes(ticker)) == keccak256("LiPMG")) return "Precious Metals Group Index (M00)";
|
||||
if (keccak256(bytes(ticker)) == keccak256("LiBMG1")) return "Base Metals Group Index 1 (M00)";
|
||||
if (keccak256(bytes(ticker)) == keccak256("LiBMG2")) return "Base Metals Group Index 2 (M00)";
|
||||
if (keccak256(bytes(ticker)) == keccak256("LiBMG3")) return "Base Metals Group Index 3 (M00)";
|
||||
return ticker;
|
||||
}
|
||||
}
|
||||
70
script/deploy/rwa/WireRWATokenFactoryWeb3Controls138.s.sol
Normal file
70
script/deploy/rwa/WireRWATokenFactoryWeb3Controls138.s.sol
Normal file
@@ -0,0 +1,70 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import {RWATokenFactory} from "../../../contracts/rwa/RWATokenFactory.sol";
|
||||
import {RWATokenRegistry} from "../../../contracts/rwa/RWATokenRegistry.sol";
|
||||
import {PolicyProfileRegistry} from "../../../contracts/universal-resource/PolicyProfileRegistry.sol";
|
||||
import {OMNLJurisdictionPolicyRegistry} from "../../../contracts/hybx-omnl/OMNLJurisdictionPolicyRegistry.sol";
|
||||
|
||||
/**
|
||||
* @title WireRWATokenFactoryWeb3Controls138
|
||||
* @notice Post-deploy: C-W3-01 jurisdiction policy, C-W3-08 profile hash, C-W3-04 multisig roles, C-W3-07 governance admin.
|
||||
* Env: RWA_TOKEN_FACTORY, RWA_TOKEN_REGISTRY, POLICY_PROFILE_REGISTRY, OMNL_JURISDICTION_REGISTRY,
|
||||
* ID_JURISDICTION_POLICY_HASH, M00_PROFILE_CONTENT_HASH, OMNL_COMPLIANCE_MULTISIG, GOVERNANCE_CONTROLLER
|
||||
*/
|
||||
contract WireRWATokenFactoryWeb3Controls138 is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address factoryAddr = vm.envAddress("RWA_TOKEN_FACTORY");
|
||||
address multisig = vm.envOr("OMNL_COMPLIANCE_MULTISIG", vm.envOr("MULTISIG_ADMIN", address(0)));
|
||||
address governance = vm.envOr("GOVERNANCE_CONTROLLER", address(0));
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
RWATokenFactory factory = RWATokenFactory(factoryAddr);
|
||||
|
||||
if (multisig != address(0)) {
|
||||
if (!factory.hasRole(factory.DEPLOYER_ROLE(), multisig)) {
|
||||
factory.grantRole(factory.DEPLOYER_ROLE(), multisig);
|
||||
}
|
||||
console.log("DEPLOYER_ROLE ->", multisig);
|
||||
}
|
||||
|
||||
if (governance != address(0)) {
|
||||
if (!factory.hasRole(factory.DEFAULT_ADMIN_ROLE(), governance)) {
|
||||
factory.grantRole(factory.DEFAULT_ADMIN_ROLE(), governance);
|
||||
}
|
||||
console.log("DEFAULT_ADMIN_ROLE ->", governance);
|
||||
}
|
||||
|
||||
address pprAddr = vm.envOr("POLICY_PROFILE_REGISTRY", address(0));
|
||||
if (pprAddr != address(0)) {
|
||||
bytes32 profileHash = vm.envBytes32("M00_PROFILE_CONTENT_HASH");
|
||||
PolicyProfileRegistry(pprAddr).publishProfile(
|
||||
"m00_commodity_index_v1",
|
||||
profileHash,
|
||||
1,
|
||||
block.timestamp
|
||||
);
|
||||
console.log("Published m00_commodity_index_v1 on PolicyProfileRegistry");
|
||||
}
|
||||
|
||||
address jurAddr = vm.envOr("OMNL_JURISDICTION_REGISTRY", address(0));
|
||||
if (jurAddr != address(0)) {
|
||||
bytes32 idPolicyHash = vm.envBytes32("ID_JURISDICTION_POLICY_HASH");
|
||||
bytes32 jurisdictionId = keccak256("ID");
|
||||
OMNLJurisdictionPolicyRegistry(jurAddr).publishPolicy(
|
||||
jurisdictionId,
|
||||
idPolicyHash,
|
||||
3,
|
||||
2,
|
||||
2,
|
||||
true
|
||||
);
|
||||
console.log("Published ID jurisdiction policy");
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
@@ -18,54 +18,68 @@ import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
|
||||
* CUSDC_ADDRESS_138 - (optional) Compliant USDC; if set, creates vault → acUSDC + vdcUSDC.
|
||||
* CUSDT_ADDRESS_138 - (optional) Compliant USDT; if set, creates vault → acUSDT + vdcUSDT.
|
||||
* COMPLIANT_USDC_ADDRESS, COMPLIANT_USDT_ADDRESS - Fallback env names if CUSDC/CUSDT_138 unset.
|
||||
* cEURC_ADDRESS_138, cEURT_ADDRESS_138, cGBPC_ADDRESS_138, cGBPT_ADDRESS_138,
|
||||
* cAUDC_ADDRESS_138, cJPYC_ADDRESS_138, cCHFC_ADDRESS_138, cCADC_ADDRESS_138,
|
||||
* cXAUC_ADDRESS_138, cXAUT_ADDRESS_138 - Optional additional base tokens (6 decimals).
|
||||
*/
|
||||
contract DeployAcVdcSdcVaults is Script {
|
||||
uint8 constant DECIMALS = 6;
|
||||
bool constant DEBT_TRANSFERABLE = true;
|
||||
|
||||
struct TokenSpec {
|
||||
string envPrimary;
|
||||
string envAlt;
|
||||
string label;
|
||||
}
|
||||
|
||||
TokenSpec[] internal tokens;
|
||||
|
||||
function _initTokens() internal {
|
||||
tokens.push(TokenSpec("CUSDC_ADDRESS_138", "COMPLIANT_USDC_ADDRESS", "USDC"));
|
||||
tokens.push(TokenSpec("CUSDT_ADDRESS_138", "COMPLIANT_USDT_ADDRESS", "USDT"));
|
||||
tokens.push(TokenSpec("cEURC_ADDRESS_138", "", "EURC"));
|
||||
tokens.push(TokenSpec("cEURT_ADDRESS_138", "", "EURT"));
|
||||
tokens.push(TokenSpec("cGBPC_ADDRESS_138", "", "GBPC"));
|
||||
tokens.push(TokenSpec("cGBPT_ADDRESS_138", "", "GBPT"));
|
||||
tokens.push(TokenSpec("cAUDC_ADDRESS_138", "", "AUDC"));
|
||||
tokens.push(TokenSpec("cJPYC_ADDRESS_138", "", "JPYC"));
|
||||
tokens.push(TokenSpec("cCHFC_ADDRESS_138", "", "CHFC"));
|
||||
tokens.push(TokenSpec("cCADC_ADDRESS_138", "", "CADC"));
|
||||
tokens.push(TokenSpec("cXAUC_ADDRESS_138", "", "XAUC"));
|
||||
tokens.push(TokenSpec("cXAUT_ADDRESS_138", "", "XAUT"));
|
||||
}
|
||||
|
||||
function run() external {
|
||||
_initTokens();
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address owner = vm.envOr("OWNER", deployer);
|
||||
address entity = vm.envOr("ENTITY", deployer);
|
||||
|
||||
address factoryAddr = vm.envAddress("VAULT_FACTORY_ADDRESS");
|
||||
if (factoryAddr == address(0)) {
|
||||
factoryAddr = vm.envOr("VAULT_FACTORY", address(0));
|
||||
}
|
||||
require(factoryAddr != address(0), "VAULT_FACTORY_ADDRESS required");
|
||||
VaultFactory factory = VaultFactory(factoryAddr);
|
||||
|
||||
address cUsdc = _getToken("CUSDC_ADDRESS_138", "COMPLIANT_USDC_ADDRESS");
|
||||
address cUsdt = _getToken("CUSDT_ADDRESS_138", "COMPLIANT_USDT_ADDRESS");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
if (cUsdc != address(0)) {
|
||||
for (uint256 i = 0; i < tokens.length; i++) {
|
||||
address base = _getToken(tokens[i].envPrimary, tokens[i].envAlt);
|
||||
if (base == address(0)) continue;
|
||||
(address vault, address depositToken, address debtToken) = factory.createVaultWithDecimals(
|
||||
owner,
|
||||
entity,
|
||||
cUsdc,
|
||||
cUsdc,
|
||||
base,
|
||||
base,
|
||||
DECIMALS,
|
||||
DECIMALS,
|
||||
DEBT_TRANSFERABLE
|
||||
);
|
||||
console.log("USDC vault:", vault);
|
||||
console.log("acUSDC (deposit):", depositToken);
|
||||
console.log("vdcUSDC (debt):", debtToken);
|
||||
}
|
||||
|
||||
if (cUsdt != address(0)) {
|
||||
(address vault, address depositToken, address debtToken) = factory.createVaultWithDecimals(
|
||||
owner,
|
||||
entity,
|
||||
cUsdt,
|
||||
cUsdt,
|
||||
DECIMALS,
|
||||
DECIMALS,
|
||||
DEBT_TRANSFERABLE
|
||||
);
|
||||
console.log("USDT vault:", vault);
|
||||
console.log("acUSDT (deposit):", depositToken);
|
||||
console.log("vdcUSDT (debt):", debtToken);
|
||||
console.log(string.concat(tokens[i].label, " vault:"), vault);
|
||||
console.log(string.concat("ac", tokens[i].label, " (deposit):"), depositToken);
|
||||
console.log(string.concat("vdc", tokens[i].label, " (debt):"), debtToken);
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
56
script/deploy/vault/DeployAcVdcSdcVaults651940.s.sol
Normal file
56
script/deploy/vault/DeployAcVdcSdcVaults651940.s.sol
Normal file
@@ -0,0 +1,56 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
|
||||
|
||||
/// @notice M1 vault basket for ALL Mainnet (651940): AUSDC, AUSDT, WALL.
|
||||
contract DeployAcVdcSdcVaults651940 is Script {
|
||||
uint8 constant DECIMALS = 6;
|
||||
bool constant DEBT_TRANSFERABLE = true;
|
||||
uint8 constant GRU_TIER_M1 = 2;
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address owner = vm.envOr("OWNER", deployer);
|
||||
address entity = vm.envOr("ENTITY", vm.envOr("GRU_OMNL_ENTITY_ADDRESS", deployer));
|
||||
address factoryAddr = vm.envAddress("VAULT_FACTORY_ADDRESS");
|
||||
VaultFactory factory = VaultFactory(factoryAddr);
|
||||
|
||||
bytes32 ibanHash = vm.envBytes32("GRU_IBAN_HASH");
|
||||
bytes32 policyProfileKey = vm.envOr("GRU_POLICY_PROFILE_KEY", bytes32(0));
|
||||
|
||||
address[] memory bases = new address[](3);
|
||||
string[] memory labels = new string[](3);
|
||||
bases[0] = vm.envAddress("CUSDC_ADDRESS_651940");
|
||||
labels[0] = "AUSDC";
|
||||
bases[1] = vm.envAddress("AUSDT_ADDRESS_651940");
|
||||
labels[1] = "AUSDT";
|
||||
bases[2] = vm.envAddress("WALL_ADDRESS_651940");
|
||||
labels[2] = "WALL";
|
||||
|
||||
uint256 startIdx = vm.envOr("GRU_VAULT_START_INDEX", uint256(0));
|
||||
uint256 endIdx = vm.envOr("GRU_VAULT_END_INDEX", bases.length);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
for (uint256 i = startIdx; i < endIdx && i < bases.length; i++) {
|
||||
(address vault, address depositToken, address debtToken) = factory.createVaultWithDecimalsGRU(
|
||||
owner,
|
||||
entity,
|
||||
bases[i],
|
||||
bases[i],
|
||||
DECIMALS,
|
||||
DECIMALS,
|
||||
DEBT_TRANSFERABLE,
|
||||
GRU_TIER_M1,
|
||||
ibanHash,
|
||||
policyProfileKey
|
||||
);
|
||||
console.log(string.concat(labels[i], " vault:"), vault);
|
||||
console.log(string.concat("ac", labels[i], ":"), depositToken);
|
||||
console.log(string.concat("vdc", labels[i], ":"), debtToken);
|
||||
}
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
85
script/deploy/vault/DeployAcVdcSdcVaultsGRU.s.sol
Normal file
85
script/deploy/vault/DeployAcVdcSdcVaultsGRU.s.sol
Normal file
@@ -0,0 +1,85 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
|
||||
|
||||
/**
|
||||
* @title DeployAcVdcSdcVaultsGRU
|
||||
* @notice Create M1 ac/vdc vault pairs with GRU tier + IBAN + policy profile anchors.
|
||||
*/
|
||||
contract DeployAcVdcSdcVaultsGRU is Script {
|
||||
uint8 constant DECIMALS = 6;
|
||||
bool constant DEBT_TRANSFERABLE = true;
|
||||
uint8 constant GRU_TIER_M1 = 2;
|
||||
|
||||
struct TokenSpec {
|
||||
string envPrimary;
|
||||
string envAlt;
|
||||
string label;
|
||||
}
|
||||
|
||||
TokenSpec[] internal tokens;
|
||||
|
||||
function _initTokens() internal {
|
||||
tokens.push(TokenSpec("CUSDC_ADDRESS_138", "COMPLIANT_USDC_ADDRESS", "USDC"));
|
||||
tokens.push(TokenSpec("CUSDT_ADDRESS_138", "COMPLIANT_USDT_ADDRESS", "USDT"));
|
||||
tokens.push(TokenSpec("cEURC_ADDRESS_138", "", "EURC"));
|
||||
tokens.push(TokenSpec("cEURT_ADDRESS_138", "", "EURT"));
|
||||
tokens.push(TokenSpec("cGBPC_ADDRESS_138", "", "GBPC"));
|
||||
tokens.push(TokenSpec("cGBPT_ADDRESS_138", "", "GBPT"));
|
||||
tokens.push(TokenSpec("cAUDC_ADDRESS_138", "", "AUDC"));
|
||||
tokens.push(TokenSpec("cJPYC_ADDRESS_138", "", "JPYC"));
|
||||
tokens.push(TokenSpec("cCHFC_ADDRESS_138", "", "CHFC"));
|
||||
tokens.push(TokenSpec("cCADC_ADDRESS_138", "", "CADC"));
|
||||
tokens.push(TokenSpec("cXAUC_ADDRESS_138", "", "XAUC"));
|
||||
tokens.push(TokenSpec("cXAUT_ADDRESS_138", "", "XAUT"));
|
||||
}
|
||||
|
||||
function run() external {
|
||||
_initTokens();
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address owner = vm.envOr("OWNER", deployer);
|
||||
address entity = vm.envOr("ENTITY", vm.envOr("GRU_OMNL_ENTITY_ADDRESS", deployer));
|
||||
|
||||
address factoryAddr = vm.envAddress("VAULT_FACTORY_ADDRESS");
|
||||
VaultFactory factory = VaultFactory(factoryAddr);
|
||||
|
||||
bytes32 ibanHash = vm.envBytes32("GRU_IBAN_HASH");
|
||||
bytes32 policyProfileKey = vm.envOr("GRU_POLICY_PROFILE_KEY", bytes32(0));
|
||||
uint256 startIdx = vm.envOr("GRU_VAULT_START_INDEX", uint256(0));
|
||||
uint256 endIdx = vm.envOr("GRU_VAULT_END_INDEX", tokens.length);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
for (uint256 i = startIdx; i < endIdx && i < tokens.length; i++) {
|
||||
address base = _getToken(tokens[i].envPrimary, tokens[i].envAlt);
|
||||
if (base == address(0)) continue;
|
||||
(address vault, address depositToken, address debtToken) = factory.createVaultWithDecimalsGRU(
|
||||
owner,
|
||||
entity,
|
||||
base,
|
||||
base,
|
||||
DECIMALS,
|
||||
DECIMALS,
|
||||
DEBT_TRANSFERABLE,
|
||||
GRU_TIER_M1,
|
||||
ibanHash,
|
||||
policyProfileKey
|
||||
);
|
||||
console.log(string.concat(tokens[i].label, " vault:"), vault);
|
||||
console.log(string.concat("ac", tokens[i].label, ":"), depositToken);
|
||||
console.log(string.concat("vdc", tokens[i].label, ":"), debtToken);
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
function _getToken(string memory primary, string memory altKey) internal view returns (address) {
|
||||
address a = vm.envOr(primary, address(0));
|
||||
if (a != address(0)) return a;
|
||||
if (bytes(altKey).length == 0) return address(0);
|
||||
return vm.envOr(altKey, address(0));
|
||||
}
|
||||
}
|
||||
21
script/deploy/vault/DeployCREATE2FactoryIfNeeded.s.sol
Normal file
21
script/deploy/vault/DeployCREATE2FactoryIfNeeded.s.sol
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {CREATE2Factory} from "../../../contracts/utils/CREATE2Factory.sol";
|
||||
|
||||
/// @notice Deploy CREATE2Factory when missing on target chain (one-time CREATE).
|
||||
contract DeployCREATE2FactoryIfNeeded is Script {
|
||||
function run() external {
|
||||
address existing = vm.envOr("CREATE2_FACTORY_ADDRESS", address(0));
|
||||
if (existing != address(0) && existing.code.length > 0) {
|
||||
console2.log("CREATE2Factory already live:", existing);
|
||||
return;
|
||||
}
|
||||
|
||||
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
|
||||
CREATE2Factory factory = new CREATE2Factory();
|
||||
vm.stopBroadcast();
|
||||
console2.log("CREATE2Factory deployed:", address(factory));
|
||||
}
|
||||
}
|
||||
34
script/deploy/vault/DeployGRUVaultProtocol.s.sol
Normal file
34
script/deploy/vault/DeployGRUVaultProtocol.s.sol
Normal file
@@ -0,0 +1,34 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {GRUEntityIbanRegistry} from "../../../contracts/vault/GRUEntityIbanRegistry.sol";
|
||||
import {GRUVaultIndex} from "../../../contracts/vault/GRUVaultIndex.sol";
|
||||
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
|
||||
|
||||
/// @notice Deploy GRU protocol registries and wire an existing or new VaultFactory.
|
||||
/// @dev Run after DeployVaultSystem or pass VAULT_FACTORY_ADDRESS to wire index on live factory.
|
||||
contract DeployGRUVaultProtocol is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.envOr("GRU_VAULT_ADMIN", vm.addr(pk));
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
GRUEntityIbanRegistry ibanRegistry = new GRUEntityIbanRegistry(admin);
|
||||
GRUVaultIndex vaultIndex = new GRUVaultIndex(admin);
|
||||
|
||||
address factoryAddr = vm.envOr("VAULT_FACTORY_ADDRESS", address(0));
|
||||
if (factoryAddr != address(0)) {
|
||||
VaultFactory(factoryAddr).setGruVaultIndex(address(vaultIndex));
|
||||
vaultIndex.grantFactoryRole(factoryAddr);
|
||||
console2.log("Wired VaultFactory", factoryAddr);
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console2.log("GRUEntityIbanRegistry", address(ibanRegistry));
|
||||
console2.log("GRUVaultIndex", address(vaultIndex));
|
||||
console2.log("admin", admin);
|
||||
}
|
||||
}
|
||||
50
script/deploy/vault/DeployGRUVaultRegistriesCreate2.s.sol
Normal file
50
script/deploy/vault/DeployGRUVaultRegistriesCreate2.s.sol
Normal file
@@ -0,0 +1,50 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {CREATE2Factory} from "../../../contracts/utils/CREATE2Factory.sol";
|
||||
import {GRUEntityIbanRegistry} from "../../../contracts/vault/GRUEntityIbanRegistry.sol";
|
||||
import {GRUVaultIndex} from "../../../contracts/vault/GRUVaultIndex.sol";
|
||||
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
|
||||
|
||||
/// @notice Deterministic GRU registry deploy via CREATE2Factory (cross-chain parity).
|
||||
contract DeployGRUVaultRegistriesCreate2 is Script {
|
||||
uint256 constant SALT_IBAN = uint256(keccak256("GRUEntityIbanRegistry"));
|
||||
uint256 constant SALT_INDEX = uint256(keccak256("GRUVaultIndex"));
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.envOr("GRU_VAULT_ADMIN", vm.addr(pk));
|
||||
address factoryAddr = vm.envAddress("CREATE2_FACTORY_ADDRESS");
|
||||
|
||||
CREATE2Factory factory = CREATE2Factory(factoryAddr);
|
||||
|
||||
bytes memory ibanInit = abi.encodePacked(type(GRUEntityIbanRegistry).creationCode, abi.encode(admin));
|
||||
bytes memory indexInit = abi.encodePacked(type(GRUVaultIndex).creationCode, abi.encode(admin));
|
||||
|
||||
address predictedIban = factory.computeAddress(ibanInit, SALT_IBAN);
|
||||
address predictedIndex = factory.computeAddress(indexInit, SALT_INDEX);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
address ibanReg = predictedIban.code.length > 0
|
||||
? predictedIban
|
||||
: factory.deploy(ibanInit, SALT_IBAN);
|
||||
address vaultIndex = predictedIndex.code.length > 0
|
||||
? predictedIndex
|
||||
: factory.deploy(indexInit, SALT_INDEX);
|
||||
|
||||
address factoryAddrVault = vm.envOr("VAULT_FACTORY_ADDRESS", address(0));
|
||||
if (factoryAddrVault != address(0) && factoryAddrVault.code.length > 0) {
|
||||
VaultFactory(factoryAddrVault).setGruVaultIndex(vaultIndex);
|
||||
GRUVaultIndex(vaultIndex).grantFactoryRole(factoryAddrVault);
|
||||
console2.log("Wired VaultFactory", factoryAddrVault);
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console2.log("CREATE2Factory", factoryAddr);
|
||||
console2.log("GRUEntityIbanRegistry", ibanReg);
|
||||
console2.log("GRUVaultIndex", vaultIndex);
|
||||
}
|
||||
}
|
||||
17
script/deploy/vault/DeployNewGRUVaultIndex138.s.sol
Normal file
17
script/deploy/vault/DeployNewGRUVaultIndex138.s.sol
Normal file
@@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {GRUVaultIndex} from "../../../contracts/vault/GRUVaultIndex.sol";
|
||||
|
||||
/// @notice Deploy GRUVaultIndex v2 (patch + import support) on hub 138.
|
||||
contract DeployNewGRUVaultIndex138 is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.addr(pk);
|
||||
vm.startBroadcast(pk);
|
||||
GRUVaultIndex idx = new GRUVaultIndex(admin);
|
||||
vm.stopBroadcast();
|
||||
console2.log("GRUVaultIndex:", address(idx));
|
||||
}
|
||||
}
|
||||
50
script/deploy/vault/DeployVaultFactory651940.s.sol
Normal file
50
script/deploy/vault/DeployVaultFactory651940.s.sol
Normal file
@@ -0,0 +1,50 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {Vault} from "../../../contracts/vault/Vault.sol";
|
||||
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
|
||||
import {DepositToken} from "../../../contracts/vault/tokens/DepositToken.sol";
|
||||
import {DebtToken} from "../../../contracts/vault/tokens/DebtToken.sol";
|
||||
import {Ledger} from "../../../contracts/vault/Ledger.sol";
|
||||
import {RegulatedEntityRegistry} from "../../../contracts/vault/RegulatedEntityRegistry.sol";
|
||||
|
||||
/// @notice Deploy VaultFactory on 651940 after core system addresses are live.
|
||||
contract DeployVaultFactory651940 is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.addr(pk);
|
||||
|
||||
RegulatedEntityRegistry entityRegistry =
|
||||
RegulatedEntityRegistry(vm.envAddress("REGULATED_ENTITY_REGISTRY"));
|
||||
Ledger ledger = Ledger(vm.envAddress("LEDGER_ADDRESS"));
|
||||
address collateralAdapter = vm.envAddress("COLLATERAL_ADAPTER_ADDRESS");
|
||||
address eMoneyJoinAddr = vm.envAddress("EMONEY_JOIN_ADDRESS");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
Vault vaultImpl = new Vault(
|
||||
admin, admin, address(ledger), address(entityRegistry), collateralAdapter, eMoneyJoinAddr
|
||||
);
|
||||
DepositToken depositTokenImpl = new DepositToken();
|
||||
DebtToken debtTokenImpl = new DebtToken();
|
||||
|
||||
VaultFactory vaultFactory = new VaultFactory(
|
||||
admin,
|
||||
address(vaultImpl),
|
||||
address(depositTokenImpl),
|
||||
address(debtTokenImpl),
|
||||
address(ledger),
|
||||
address(entityRegistry),
|
||||
collateralAdapter,
|
||||
eMoneyJoinAddr
|
||||
);
|
||||
console.log("Vault Factory:", address(vaultFactory));
|
||||
|
||||
ledger.grantRole(ledger.VAULT_FACTORY_ROLE(), address(vaultFactory));
|
||||
entityRegistry.grantRole(entityRegistry.REGISTRAR_ROLE(), address(vaultFactory));
|
||||
|
||||
vm.stopBroadcast();
|
||||
console.log("=== [651940] VaultFactory wired ===");
|
||||
}
|
||||
}
|
||||
@@ -126,8 +126,8 @@ contract DeployVaultSystem is Script {
|
||||
// Step 10: Grant roles and configure
|
||||
console.log("\n10. Configuring roles and parameters...");
|
||||
|
||||
// Grant factory vault role
|
||||
ledger.grantVaultRole(address(vaultFactory));
|
||||
// Grant factory permission to register vaults on ledger
|
||||
ledger.grantRole(ledger.VAULT_FACTORY_ROLE(), address(vaultFactory));
|
||||
|
||||
// Set risk parameters (registers assets and sets params)
|
||||
ledger.setRiskParameters(
|
||||
@@ -146,7 +146,7 @@ contract DeployVaultSystem is Script {
|
||||
}
|
||||
|
||||
// Grant factory role to create vaults
|
||||
entityRegistry.grantRole(keccak256("ENTITY_REGISTRAR_ROLE"), address(vaultFactory));
|
||||
entityRegistry.grantRole(entityRegistry.REGISTRAR_ROLE(), address(vaultFactory));
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
|
||||
71
script/deploy/vault/DeployVaultSystem651940Core.s.sol
Normal file
71
script/deploy/vault/DeployVaultSystem651940Core.s.sol
Normal file
@@ -0,0 +1,71 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {RegulatedEntityRegistry} from "../../../contracts/vault/RegulatedEntityRegistry.sol";
|
||||
import {XAUOracle} from "../../../contracts/vault/XAUOracle.sol";
|
||||
import {RateAccrual} from "../../../contracts/vault/RateAccrual.sol";
|
||||
import {Ledger} from "../../../contracts/vault/Ledger.sol";
|
||||
import {Liquidation} from "../../../contracts/vault/Liquidation.sol";
|
||||
import {CollateralAdapter} from "../../../contracts/vault/adapters/CollateralAdapter.sol";
|
||||
import {eMoneyJoin} from "../../../contracts/vault/adapters/eMoneyJoin.sol";
|
||||
import {Aggregator} from "../../../contracts/oracle/Aggregator.sol";
|
||||
|
||||
/// @notice Deploy vault system core on ALL Mainnet (651940) without VaultFactory (forge broadcast workaround).
|
||||
contract DeployVaultSystem651940Core is Script {
|
||||
uint256 public constant DEFAULT_LIQUIDATION_RATIO = 10000;
|
||||
uint256 public constant DEFAULT_CREDIT_MULTIPLIER = 50000;
|
||||
uint256 public constant DEFAULT_DEBT_CEILING = 1000000e18;
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.addr(pk);
|
||||
address treasury = vm.envOr("TREASURY_ADDRESS", admin);
|
||||
address ethAddress = address(0);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
console.log("=== [651940] Vault system core ===");
|
||||
RegulatedEntityRegistry entityRegistry = new RegulatedEntityRegistry(admin);
|
||||
console.log("RegulatedEntityRegistry:", address(entityRegistry));
|
||||
|
||||
Aggregator ethPriceFeed = new Aggregator("ETH/XAU", admin, 3600, 50);
|
||||
ethPriceFeed.addTransmitter(admin);
|
||||
ethPriceFeed.updateAnswer(0.05e18);
|
||||
console.log("ETH Price Feed:", address(ethPriceFeed));
|
||||
|
||||
Aggregator btcPriceFeed = new Aggregator("BTC/XAU", admin, 3600, 50);
|
||||
btcPriceFeed.addTransmitter(admin);
|
||||
btcPriceFeed.updateAnswer(0.5e18);
|
||||
console.log("BTC Price Feed:", address(btcPriceFeed));
|
||||
|
||||
XAUOracle xauOracle = new XAUOracle(admin);
|
||||
xauOracle.addPriceFeed(address(ethPriceFeed), 10000);
|
||||
xauOracle.addPriceFeed(address(btcPriceFeed), 10000);
|
||||
xauOracle.updatePrice();
|
||||
console.log("XAU Oracle:", address(xauOracle));
|
||||
|
||||
RateAccrual rateAccrual = new RateAccrual(admin);
|
||||
rateAccrual.setInterestRate(address(0), 500);
|
||||
console.log("Rate Accrual:", address(rateAccrual));
|
||||
|
||||
Ledger ledger = new Ledger(admin, address(xauOracle), address(rateAccrual));
|
||||
console.log("Ledger:", address(ledger));
|
||||
|
||||
Liquidation liquidation = new Liquidation(admin, address(ledger), address(xauOracle), treasury);
|
||||
console.log("Liquidation:", address(liquidation));
|
||||
|
||||
CollateralAdapter collateralAdapter = new CollateralAdapter(admin, address(ledger));
|
||||
console.log("Collateral Adapter:", address(collateralAdapter));
|
||||
|
||||
eMoneyJoin eMoneyJoinContract = new eMoneyJoin(admin);
|
||||
console.log("eMoney Join:", address(eMoneyJoinContract));
|
||||
|
||||
ledger.setRiskParameters(
|
||||
ethAddress, DEFAULT_DEBT_CEILING, DEFAULT_LIQUIDATION_RATIO, DEFAULT_CREDIT_MULTIPLIER
|
||||
);
|
||||
|
||||
vm.stopBroadcast();
|
||||
console.log("=== [651940] core complete (VaultFactory separate) ===");
|
||||
}
|
||||
}
|
||||
94
script/deploy/vault/DeployVaultSystemFinish.s.sol
Normal file
94
script/deploy/vault/DeployVaultSystemFinish.s.sol
Normal file
@@ -0,0 +1,94 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {Ledger} from "../../../contracts/vault/Ledger.sol";
|
||||
import {RegulatedEntityRegistry} from "../../../contracts/vault/RegulatedEntityRegistry.sol";
|
||||
import {XAUOracle} from "../../../contracts/vault/XAUOracle.sol";
|
||||
import {RateAccrual} from "../../../contracts/vault/RateAccrual.sol";
|
||||
import {Liquidation} from "../../../contracts/vault/Liquidation.sol";
|
||||
import {CollateralAdapter} from "../../../contracts/vault/adapters/CollateralAdapter.sol";
|
||||
import {eMoneyJoin} from "../../../contracts/vault/adapters/eMoneyJoin.sol";
|
||||
import {Vault} from "../../../contracts/vault/Vault.sol";
|
||||
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
|
||||
import {DepositToken} from "../../../contracts/vault/tokens/DepositToken.sol";
|
||||
import {DebtToken} from "../../../contracts/vault/tokens/DebtToken.sol";
|
||||
import {Aggregator} from "../../../contracts/oracle/Aggregator.sol";
|
||||
|
||||
/**
|
||||
* @title DeployVaultSystemFinish
|
||||
* @notice Resume vault system deploy when DeployVaultSystem broadcast stalled mid-flight.
|
||||
* @dev Requires env addresses for components already on-chain (see run-gru-vault-protocol-operator.sh).
|
||||
*/
|
||||
contract DeployVaultSystemFinish is Script {
|
||||
uint256 public constant DEFAULT_LIQUIDATION_RATIO = 10000;
|
||||
uint256 public constant DEFAULT_CREDIT_MULTIPLIER = 50000;
|
||||
uint256 public constant DEFAULT_DEBT_CEILING = 1000000e18;
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.addr(pk);
|
||||
address treasury = vm.envOr("TREASURY_ADDRESS", admin);
|
||||
address ethAddress = address(0);
|
||||
|
||||
RegulatedEntityRegistry entityRegistry =
|
||||
RegulatedEntityRegistry(vm.envAddress("REGULATED_ENTITY_REGISTRY"));
|
||||
XAUOracle xauOracle = XAUOracle(vm.envAddress("XAU_ORACLE_ADDRESS"));
|
||||
address ethPriceFeed = vm.envAddress("ETH_PRICE_FEED_ADDRESS");
|
||||
address btcPriceFeed = vm.envAddress("BTC_PRICE_FEED_ADDRESS");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
console.log("=== Finishing Vault System (from XAUOracle config) ===");
|
||||
|
||||
xauOracle.addPriceFeed(ethPriceFeed, 10000);
|
||||
xauOracle.addPriceFeed(btcPriceFeed, 10000);
|
||||
Aggregator(ethPriceFeed).updateAnswer(0.05e18);
|
||||
Aggregator(btcPriceFeed).updateAnswer(0.5e18);
|
||||
xauOracle.updatePrice();
|
||||
console.log("XAUOracle configured");
|
||||
|
||||
RateAccrual rateAccrual = new RateAccrual(admin);
|
||||
rateAccrual.setInterestRate(address(0), 500);
|
||||
console.log("RateAccrual:", address(rateAccrual));
|
||||
|
||||
Ledger ledger = new Ledger(admin, address(xauOracle), address(rateAccrual));
|
||||
console.log("Ledger:", address(ledger));
|
||||
|
||||
Liquidation liquidation = new Liquidation(admin, address(ledger), address(xauOracle), treasury);
|
||||
console.log("Liquidation:", address(liquidation));
|
||||
|
||||
CollateralAdapter collateralAdapter = new CollateralAdapter(admin, address(ledger));
|
||||
console.log("Collateral Adapter:", address(collateralAdapter));
|
||||
|
||||
eMoneyJoin eMoneyJoinContract = new eMoneyJoin(admin);
|
||||
console.log("eMoney Join:", address(eMoneyJoinContract));
|
||||
|
||||
Vault vaultImpl = new Vault(
|
||||
admin, admin, address(ledger), address(entityRegistry), address(collateralAdapter), address(eMoneyJoinContract)
|
||||
);
|
||||
DepositToken depositTokenImpl = new DepositToken();
|
||||
DebtToken debtTokenImpl = new DebtToken();
|
||||
|
||||
VaultFactory vaultFactory = new VaultFactory(
|
||||
admin,
|
||||
address(vaultImpl),
|
||||
address(depositTokenImpl),
|
||||
address(debtTokenImpl),
|
||||
address(ledger),
|
||||
address(entityRegistry),
|
||||
address(collateralAdapter),
|
||||
address(eMoneyJoinContract)
|
||||
);
|
||||
console.log("Vault Factory:", address(vaultFactory));
|
||||
|
||||
ledger.grantRole(ledger.VAULT_FACTORY_ROLE(), address(vaultFactory));
|
||||
ledger.setRiskParameters(ethAddress, DEFAULT_DEBT_CEILING, DEFAULT_LIQUIDATION_RATIO, DEFAULT_CREDIT_MULTIPLIER);
|
||||
|
||||
entityRegistry.grantRole(entityRegistry.REGISTRAR_ROLE(), address(vaultFactory));
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("\n=== Vault System Finish Complete ===");
|
||||
}
|
||||
}
|
||||
66
script/deploy/vault/ImportGruVaultRecord138.s.sol
Normal file
66
script/deploy/vault/ImportGruVaultRecord138.s.sol
Normal file
@@ -0,0 +1,66 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {GRUVaultIndex} from "../../../contracts/vault/GRUVaultIndex.sol";
|
||||
|
||||
interface IGRUVaultIndexLegacy {
|
||||
function allVaults(uint256 index) external view returns (address);
|
||||
function vaults(address vault)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
address entity,
|
||||
address baseToken,
|
||||
address depositToken,
|
||||
address debtToken,
|
||||
uint8 gruTier,
|
||||
bytes32 ibanHash,
|
||||
bytes32 policyProfileKey,
|
||||
uint256 recordedAt,
|
||||
bool active
|
||||
);
|
||||
}
|
||||
|
||||
/// @notice Import one legacy vault record into new GRUVaultIndex (use GRU_MIGRATE_INDEX).
|
||||
contract ImportGruVaultRecord138 is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address oldIndex = vm.envAddress("OLD_GRU_VAULT_INDEX");
|
||||
address newIndex = vm.envAddress("NEW_GRU_VAULT_INDEX");
|
||||
bytes32 policyKey = vm.envBytes32("GRU_POLICY_PROFILE_KEY");
|
||||
uint256 idx = vm.envUint("GRU_MIGRATE_INDEX");
|
||||
|
||||
IGRUVaultIndexLegacy legacy = IGRUVaultIndexLegacy(oldIndex);
|
||||
GRUVaultIndex target = GRUVaultIndex(newIndex);
|
||||
|
||||
address vault;
|
||||
try legacy.allVaults(idx) returns (address v) {
|
||||
vault = v;
|
||||
} catch {
|
||||
revert("ImportGruVaultRecord138: index out of range");
|
||||
}
|
||||
|
||||
(
|
||||
address entity,
|
||||
address baseToken,
|
||||
address depositToken,
|
||||
address debtToken,
|
||||
uint8 gruTier,
|
||||
bytes32 ibanHash,
|
||||
bytes32 existingKey,
|
||||
uint256 recordedAt,
|
||||
bool active
|
||||
) = legacy.vaults(vault);
|
||||
require(active, "ImportGruVaultRecord138: inactive");
|
||||
|
||||
bytes32 key = existingKey == bytes32(0) ? policyKey : existingKey;
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
target.importVault(
|
||||
vault, entity, baseToken, depositToken, debtToken, gruTier, ibanHash, key, recordedAt
|
||||
);
|
||||
vm.stopBroadcast();
|
||||
console2.log("Imported", vault, "policy", vm.toString(key));
|
||||
}
|
||||
}
|
||||
82
script/deploy/vault/MigrateGRUVaultIndex138.s.sol
Normal file
82
script/deploy/vault/MigrateGRUVaultIndex138.s.sol
Normal file
@@ -0,0 +1,82 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {GRUVaultIndex} from "../../../contracts/vault/GRUVaultIndex.sol";
|
||||
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
|
||||
|
||||
interface IGRUVaultIndexLegacy {
|
||||
function allVaults(uint256 index) external view returns (address);
|
||||
function vaults(address vault)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
address entity,
|
||||
address baseToken,
|
||||
address depositToken,
|
||||
address debtToken,
|
||||
uint8 gruTier,
|
||||
bytes32 ibanHash,
|
||||
bytes32 policyProfileKey,
|
||||
uint256 recordedAt,
|
||||
bool active
|
||||
);
|
||||
}
|
||||
|
||||
/// @notice Deploy GRUVaultIndex v2 and migrate records from legacy index with policy profile backfill.
|
||||
contract MigrateGRUVaultIndex138 is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.addr(pk);
|
||||
address oldIndex = vm.envAddress("OLD_GRU_VAULT_INDEX");
|
||||
address factory = vm.envAddress("VAULT_FACTORY_ADDRESS");
|
||||
bytes32 policyKey = vm.envBytes32("GRU_POLICY_PROFILE_KEY");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
GRUVaultIndex newIndex = new GRUVaultIndex(admin);
|
||||
console2.log("New GRUVaultIndex:", address(newIndex));
|
||||
|
||||
IGRUVaultIndexLegacy legacy = IGRUVaultIndexLegacy(oldIndex);
|
||||
uint256 imported;
|
||||
|
||||
for (uint256 i = 0; i < 32; i++) {
|
||||
address vault;
|
||||
try legacy.allVaults(i) returns (address v) {
|
||||
vault = v;
|
||||
} catch {
|
||||
break;
|
||||
}
|
||||
if (vault == address(0)) break;
|
||||
|
||||
(
|
||||
address entity,
|
||||
address baseToken,
|
||||
address depositToken,
|
||||
address debtToken,
|
||||
uint8 gruTier,
|
||||
bytes32 ibanHash,
|
||||
bytes32 existingKey,
|
||||
uint256 recordedAt,
|
||||
bool active
|
||||
) = legacy.vaults(vault);
|
||||
|
||||
if (!active) continue;
|
||||
|
||||
bytes32 key = existingKey == bytes32(0) ? policyKey : existingKey;
|
||||
newIndex.importVault(
|
||||
vault, entity, baseToken, depositToken, debtToken, gruTier, ibanHash, key, recordedAt
|
||||
);
|
||||
imported++;
|
||||
console2.log("Imported vault", vault);
|
||||
}
|
||||
|
||||
newIndex.grantFactoryRole(factory);
|
||||
VaultFactory(factory).setGruVaultIndex(address(newIndex));
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console2.log("Migrated vault count:", imported);
|
||||
console2.log("Update GRU_VAULT_INDEX to", address(newIndex));
|
||||
}
|
||||
}
|
||||
44
script/deploy/vault/RegisterGRUEntityAndIban.s.sol
Normal file
44
script/deploy/vault/RegisterGRUEntityAndIban.s.sol
Normal file
@@ -0,0 +1,44 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {RegulatedEntityRegistry} from "../../../contracts/vault/RegulatedEntityRegistry.sol";
|
||||
import {GRUEntityIbanRegistry} from "../../../contracts/vault/GRUEntityIbanRegistry.sol";
|
||||
|
||||
/// @notice Register OMNL/DBIS entity + IBAN binding for GRU vault operations.
|
||||
contract RegisterGRUEntityAndIban is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address entity = vm.envOr("GRU_OMNL_ENTITY_ADDRESS", vm.addr(pk));
|
||||
address entityRegistryAddr = vm.envAddress("REGULATED_ENTITY_REGISTRY");
|
||||
address ibanRegistryAddr = vm.envAddress("GRU_ENTITY_IBAN_REGISTRY");
|
||||
|
||||
bytes32 jurisdictionHash = vm.envOr("GRU_JURISDICTION_HASH", keccak256("OMNL"));
|
||||
bytes32 ibanHash = vm.envBytes32("GRU_IBAN_HASH");
|
||||
address directIban = vm.envOr("GRU_DIRECT_IBAN_ADDRESS", entity);
|
||||
|
||||
RegulatedEntityRegistry entityRegistry = RegulatedEntityRegistry(entityRegistryAddr);
|
||||
GRUEntityIbanRegistry ibanRegistry = GRUEntityIbanRegistry(ibanRegistryAddr);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
if (!entityRegistry.isEligible(entity)) {
|
||||
address[] memory wallets = new address[](1);
|
||||
wallets[0] = entity;
|
||||
entityRegistry.registerEntity(entity, jurisdictionHash, wallets);
|
||||
console2.log("Registered entity", entity);
|
||||
} else {
|
||||
console2.log("Entity already registered", entity);
|
||||
}
|
||||
|
||||
(address existing,,, bool active) = ibanRegistry.getRecord(ibanHash);
|
||||
if (!active) {
|
||||
ibanRegistry.registerIban(ibanHash, entity, jurisdictionHash, directIban);
|
||||
console2.log("Registered IBAN hash", vm.toString(ibanHash));
|
||||
} else {
|
||||
console2.log("IBAN already active for entity", existing);
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
44
script/deploy/vault/RegisterGruVaultLedgerAssets.s.sol
Normal file
44
script/deploy/vault/RegisterGruVaultLedgerAssets.s.sol
Normal file
@@ -0,0 +1,44 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {Ledger} from "../../../contracts/vault/Ledger.sol";
|
||||
|
||||
/// @notice Register M1 c* tokens as ledger assets with default GRU vault risk parameters.
|
||||
contract RegisterGruVaultLedgerAssets is Script {
|
||||
uint256 constant DEFAULT_DEBT_CEILING = 1_000_000e18;
|
||||
uint256 constant DEFAULT_LIQUIDATION_RATIO = 10_000;
|
||||
uint256 constant DEFAULT_CREDIT_MULTIPLIER = 50_000;
|
||||
|
||||
function run() external {
|
||||
address ledgerAddr = vm.envAddress("LEDGER_ADDRESS");
|
||||
Ledger ledger = Ledger(ledgerAddr);
|
||||
|
||||
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
|
||||
|
||||
_registerIfSet(ledger, vm.envOr("CUSDC_ADDRESS_138", vm.envOr("COMPLIANT_USDC_ADDRESS", address(0))));
|
||||
_registerIfSet(ledger, vm.envOr("CUSDT_ADDRESS_138", vm.envOr("COMPLIANT_USDT_ADDRESS", address(0))));
|
||||
_registerIfSet(ledger, vm.envOr("cEURC_ADDRESS_138", address(0)));
|
||||
_registerIfSet(ledger, vm.envOr("cEURT_ADDRESS_138", address(0)));
|
||||
_registerIfSet(ledger, vm.envOr("cGBPC_ADDRESS_138", address(0)));
|
||||
_registerIfSet(ledger, vm.envOr("cGBPT_ADDRESS_138", address(0)));
|
||||
_registerIfSet(ledger, vm.envOr("cAUDC_ADDRESS_138", address(0)));
|
||||
_registerIfSet(ledger, vm.envOr("cJPYC_ADDRESS_138", address(0)));
|
||||
_registerIfSet(ledger, vm.envOr("cCHFC_ADDRESS_138", address(0)));
|
||||
_registerIfSet(ledger, vm.envOr("cCADC_ADDRESS_138", address(0)));
|
||||
_registerIfSet(ledger, vm.envOr("cXAUC_ADDRESS_138", address(0)));
|
||||
_registerIfSet(ledger, vm.envOr("cXAUT_ADDRESS_138", address(0)));
|
||||
|
||||
_registerIfSet(ledger, vm.envOr("CUSDC_ADDRESS_651940", vm.envOr("AUSDC_ADDRESS_651940", address(0))));
|
||||
_registerIfSet(ledger, vm.envOr("AUSDT_ADDRESS_651940", vm.envOr("CUSDT_ADDRESS_651940", address(0))));
|
||||
_registerIfSet(ledger, vm.envOr("WALL_ADDRESS_651940", address(0)));
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
function _registerIfSet(Ledger ledger, address asset) internal {
|
||||
if (asset == address(0)) return;
|
||||
ledger.setRiskParameters(asset, DEFAULT_DEBT_CEILING, DEFAULT_LIQUIDATION_RATIO, DEFAULT_CREDIT_MULTIPLIER);
|
||||
console2.log("Registered ledger asset", asset);
|
||||
}
|
||||
}
|
||||
22
script/deploy/vault/WireGRUVaultFactoryToIndex.s.sol
Normal file
22
script/deploy/vault/WireGRUVaultFactoryToIndex.s.sol
Normal file
@@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
|
||||
import {GRUVaultIndex} from "../../../contracts/vault/GRUVaultIndex.sol";
|
||||
|
||||
/// @notice Wire an existing VaultFactory to an existing GRUVaultIndex (post-deploy on any chain).
|
||||
contract WireGRUVaultFactoryToIndex is Script {
|
||||
function run() external {
|
||||
address factoryAddr = vm.envAddress("VAULT_FACTORY_ADDRESS");
|
||||
address indexAddr = vm.envAddress("GRU_VAULT_INDEX");
|
||||
|
||||
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
|
||||
VaultFactory(factoryAddr).setGruVaultIndex(indexAddr);
|
||||
GRUVaultIndex(indexAddr).grantFactoryRole(factoryAddr);
|
||||
vm.stopBroadcast();
|
||||
|
||||
console2.log("Wired VaultFactory", factoryAddr);
|
||||
console2.log("GRUVaultIndex", indexAddr);
|
||||
}
|
||||
}
|
||||
24
script/hybx-omnl/DeployOMNLComplianceCoreV2.s.sol
Normal file
24
script/hybx-omnl/DeployOMNLComplianceCoreV2.s.sol
Normal file
@@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {ComplianceCore} from "../../contracts/hybx-omnl/ComplianceCore.sol";
|
||||
|
||||
/// @notice Deploy ComplianceCore pointing at ReserveCommitmentStore v2 (immutable reserves pointer).
|
||||
contract DeployOMNLComplianceCoreV2 is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address registry = vm.envAddress("OMNL_INSTRUMENT_REGISTRY_138");
|
||||
address reserves = vm.envAddress("OMNL_RESERVE_STORE_V2_138");
|
||||
address breakers = vm.envAddress("OMNL_CIRCUIT_BREAKER_138");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
ComplianceCore coreV2 = new ComplianceCore(registry, reserves, breakers);
|
||||
vm.stopBroadcast();
|
||||
|
||||
console2.log("ComplianceCoreV2", address(coreV2));
|
||||
console2.log("registry", registry);
|
||||
console2.log("reservesV2", reserves);
|
||||
console2.log("breakers", breakers);
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,11 @@ import {InstrumentRegistry} from "../../contracts/hybx-omnl/InstrumentRegistry.s
|
||||
import {ReserveCommitmentStore} from "../../contracts/hybx-omnl/ReserveCommitmentStore.sol";
|
||||
import {OMNLCircuitBreaker} from "../../contracts/hybx-omnl/OMNLCircuitBreaker.sol";
|
||||
import {ComplianceCore} from "../../contracts/hybx-omnl/ComplianceCore.sol";
|
||||
import {OMNLJurisdictionPolicyRegistry} from "../../contracts/hybx-omnl/OMNLJurisdictionPolicyRegistry.sol";
|
||||
import {OMNLNotaryRegistry} from "../../contracts/hybx-omnl/OMNLNotaryRegistry.sol";
|
||||
import {OMNLComplianceMultisig} from "../../contracts/hybx-omnl/OMNLComplianceMultisig.sol";
|
||||
|
||||
/// @notice Deploy core OMNL stack (registry, reserves, breakers, compliance). Mirror receiver is chain-specific.
|
||||
/// @notice Deploy core OMNL stack + Web3 compliance (registry, reserves, breakers, compliance, notary, multisig).
|
||||
contract DeployOMNLStack is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
@@ -20,11 +23,22 @@ contract DeployOMNLStack is Script {
|
||||
OMNLCircuitBreaker breakers = new OMNLCircuitBreaker(admin);
|
||||
ComplianceCore core = new ComplianceCore(address(registry), address(reserves), address(breakers));
|
||||
|
||||
OMNLJurisdictionPolicyRegistry jurisdiction = new OMNLJurisdictionPolicyRegistry(admin);
|
||||
OMNLNotaryRegistry notary = new OMNLNotaryRegistry(admin, address(jurisdiction));
|
||||
OMNLComplianceMultisig multisig = new OMNLComplianceMultisig(admin, address(notary));
|
||||
|
||||
bytes32 jurId = keccak256("ID");
|
||||
bytes32 matrixId = keccak256("ID-OMNL-001");
|
||||
reserves.configureNotaryGate(address(notary), false, jurId, matrixId);
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console2.log("InstrumentRegistry", address(registry));
|
||||
console2.log("ReserveCommitmentStore", address(reserves));
|
||||
console2.log("OMNLCircuitBreaker", address(breakers));
|
||||
console2.log("ComplianceCore", address(core));
|
||||
console2.log("OMNLJurisdictionPolicyRegistry", address(jurisdiction));
|
||||
console2.log("OMNLNotaryRegistry", address(notary));
|
||||
console2.log("OMNLComplianceMultisig", address(multisig));
|
||||
}
|
||||
}
|
||||
|
||||
27
script/hybx-omnl/DeployOMNLWeb3Compliance.s.sol
Normal file
27
script/hybx-omnl/DeployOMNLWeb3Compliance.s.sol
Normal file
@@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {OMNLJurisdictionPolicyRegistry} from "../../contracts/hybx-omnl/OMNLJurisdictionPolicyRegistry.sol";
|
||||
import {OMNLNotaryRegistry} from "../../contracts/hybx-omnl/OMNLNotaryRegistry.sol";
|
||||
import {OMNLComplianceMultisig} from "../../contracts/hybx-omnl/OMNLComplianceMultisig.sol";
|
||||
|
||||
/// @notice Deploy Web3 compliance layer: jurisdiction policy registry, notary, multisig.
|
||||
contract DeployOMNLWeb3Compliance is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.envOr("OMNL_WEB3_ADMIN", vm.addr(pk));
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
OMNLJurisdictionPolicyRegistry jurisdiction = new OMNLJurisdictionPolicyRegistry(admin);
|
||||
OMNLNotaryRegistry notary = new OMNLNotaryRegistry(admin, address(jurisdiction));
|
||||
OMNLComplianceMultisig multisig = new OMNLComplianceMultisig(admin, address(notary));
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console2.log("OMNLJurisdictionPolicyRegistry", address(jurisdiction));
|
||||
console2.log("OMNLNotaryRegistry", address(notary));
|
||||
console2.log("OMNLComplianceMultisig", address(multisig));
|
||||
}
|
||||
}
|
||||
42
script/hybx-omnl/MigrateOMNLReserveStoreV2.s.sol
Normal file
42
script/hybx-omnl/MigrateOMNLReserveStoreV2.s.sol
Normal file
@@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {ReserveCommitmentStore} from "../../contracts/hybx-omnl/ReserveCommitmentStore.sol";
|
||||
|
||||
/// @notice Deploy ReserveCommitmentStore v2 (notary gate ABI), migrate commitment from legacy store.
|
||||
contract MigrateOMNLReserveStoreV2 is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.envOr("OMNL_WEB3_ADMIN", vm.addr(pk));
|
||||
address legacyStore = vm.envAddress("OMNL_RESERVE_STORE_138");
|
||||
address notary = vm.envAddress("OMNL_NOTARY_REGISTRY");
|
||||
bytes32 lineId = vm.envBytes32("OMNL_HEALTH_LINE_ID");
|
||||
|
||||
bytes32 jurId = keccak256(bytes(vm.envOr("OMNL_JURISDICTION_ID", string("ID"))));
|
||||
bytes32 matrixId = keccak256(bytes(vm.envOr("OMNL_MATRIX_CONTROL_ID", string("ID-OMNL-001"))));
|
||||
bool requireNotary = vm.envOr("OMNL_REQUIRE_NOTARIZED_RESERVE", false);
|
||||
uint256 attTh = vm.envOr("OMNL_RESERVE_ATTESTATION_THRESHOLD", uint256(3));
|
||||
|
||||
ReserveCommitmentStore legacy = ReserveCommitmentStore(legacyStore);
|
||||
ReserveCommitmentStore.Commitment memory c = legacy.getCommitment(lineId);
|
||||
address mirror = legacy.mirrorReceiver();
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
ReserveCommitmentStore storeV2 = new ReserveCommitmentStore(admin);
|
||||
storeV2.configureNotaryGate(notary, requireNotary, jurId, matrixId);
|
||||
storeV2.setAttestationThreshold(attTh);
|
||||
if (mirror != address(0)) {
|
||||
storeV2.setMirrorReceiver(mirror);
|
||||
}
|
||||
storeV2.commitReserve(lineId, c.R, c.validUntil, c.evidenceHash, c.merkleRoot);
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console2.log("ReserveCommitmentStoreV2", address(storeV2));
|
||||
console2.log("legacyStore", legacyStore);
|
||||
console2.log("notaryGate", notary);
|
||||
console2.log("migratedVersion", storeV2.getCommitment(lineId).version);
|
||||
}
|
||||
}
|
||||
27
script/hybx-omnl/PublishJurisdictionPolicies.s.sol
Normal file
27
script/hybx-omnl/PublishJurisdictionPolicies.s.sol
Normal file
@@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {OMNLJurisdictionPolicyRegistry} from "../../contracts/hybx-omnl/OMNLJurisdictionPolicyRegistry.sol";
|
||||
|
||||
/// @notice Publish Indonesia pilot policy (extend via env for more jurisdictions).
|
||||
contract PublishJurisdictionPolicies is Script {
|
||||
function run() external {
|
||||
address registry = vm.envAddress("OMNL_JURISDICTION_REGISTRY");
|
||||
bytes32 policyHash = vm.envBytes32("OMNL_JURISDICTION_POLICY_HASH");
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
|
||||
bytes32 jurId = keccak256(bytes(vm.envOr("OMNL_JURISDICTION_ID", string("ID"))));
|
||||
uint8 notaryTh = uint8(vm.envOr("OMNL_NOTARY_THRESHOLD", uint256(3)));
|
||||
uint8 reserveTh = uint8(vm.envOr("OMNL_RESERVE_ATTESTATION_THRESHOLD", uint256(3)));
|
||||
uint8 adminTh = uint8(vm.envOr("OMNL_ADMIN_MULTISIG_THRESHOLD", uint256(3)));
|
||||
bool prod = vm.envOr("OMNL_JURISDICTION_PRODUCTION_READY", true);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
OMNLJurisdictionPolicyRegistry(registry).publishPolicy(
|
||||
jurId, policyHash, notaryTh, reserveTh, adminTh, prod
|
||||
);
|
||||
vm.stopBroadcast();
|
||||
console2.log("Published policy for jurisdiction", vm.toString(jurId));
|
||||
}
|
||||
}
|
||||
32
script/hybx-omnl/RefreshReserveAttestation.s.sol
Normal file
32
script/hybx-omnl/RefreshReserveAttestation.s.sol
Normal file
@@ -0,0 +1,32 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {ReserveCommitmentStore} from "../../contracts/hybx-omnl/ReserveCommitmentStore.sol";
|
||||
|
||||
/// @notice Refresh reserve TTL and optionally bump R / evidence hashes.
|
||||
contract RefreshReserveAttestation is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address storeAddr = vm.envAddress("OMNL_RESERVE_STORE_138");
|
||||
bytes32 lineId = vm.envBytes32("OMNL_HEALTH_LINE_ID");
|
||||
|
||||
uint256 ttlDays = vm.envOr("OMNL_RESERVE_TTL_DAYS", uint256(90));
|
||||
uint256 validUntil = block.timestamp + ttlDays * 1 days;
|
||||
|
||||
ReserveCommitmentStore store = ReserveCommitmentStore(storeAddr);
|
||||
ReserveCommitmentStore.Commitment memory c = store.getCommitment(lineId);
|
||||
|
||||
uint256 R = vm.envOr("OMNL_RESERVE_R", c.R);
|
||||
bytes32 evidence = vm.envOr("OMNL_RESERVE_EVIDENCE_HASH", c.evidenceHash);
|
||||
bytes32 merkle = vm.envOr("OMNL_RESERVE_MERKLE_ROOT", c.merkleRoot);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
store.commitReserve(lineId, R, validUntil, evidence, merkle);
|
||||
vm.stopBroadcast();
|
||||
|
||||
console2.log("Reserve refreshed lineId", vm.toString(lineId));
|
||||
console2.log("validUntil", validUntil);
|
||||
console2.log("R", R);
|
||||
}
|
||||
}
|
||||
47
script/hybx-omnl/RemediateOmnlM1Cap.s.sol
Normal file
47
script/hybx-omnl/RemediateOmnlM1Cap.s.sol
Normal file
@@ -0,0 +1,47 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
interface IMintableM0 {
|
||||
function mint(address to, uint256 amount) external;
|
||||
function mint(address to, uint256 amount, bytes32 reasonHash) external;
|
||||
}
|
||||
|
||||
/// @notice Mint M0 (cUSDT) so that S1 <= 5 * S0 for the health line (policy cap remediation).
|
||||
contract RemediateOmnlM1Cap is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address tokenM0 = vm.envAddress("OMNL_TOKEN_M0");
|
||||
address tokenM1 = vm.envAddress("OMNL_TOKEN_M1");
|
||||
address mintTo = vm.envOr("OMNL_M1_REMEDIATION_MINT_TO", vm.addr(pk));
|
||||
|
||||
uint256 s0 = IERC20(tokenM0).totalSupply();
|
||||
uint256 s1 = IERC20(tokenM1).totalSupply();
|
||||
|
||||
uint256 requiredS0 = (s1 + 4) / 5;
|
||||
if (s0 >= requiredS0) {
|
||||
console2.log("No mint required; s0", s0, "requiredS0", requiredS0);
|
||||
return;
|
||||
}
|
||||
uint256 delta = requiredS0 - s0;
|
||||
bytes32 reason = keccak256("OMNL-M1-CAP-REMEDIATION");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
IMintableM0 m0 = IMintableM0(tokenM0);
|
||||
try m0.mint(mintTo, delta, reason) {
|
||||
} catch {
|
||||
m0.mint(mintTo, delta);
|
||||
}
|
||||
vm.stopBroadcast();
|
||||
|
||||
uint256 s0After = IERC20(tokenM0).totalSupply();
|
||||
uint256 s1After = IERC20(tokenM1).totalSupply();
|
||||
bool m1OkAfter = s1After <= s0After * 5;
|
||||
console2.log("Minted delta", delta, "to", mintTo);
|
||||
console2.log("s0After", s0After);
|
||||
console2.log("s1After", s1After);
|
||||
console2.log("m1OkAfter", m1OkAfter);
|
||||
}
|
||||
}
|
||||
33
script/hybx-omnl/WireOMNLWeb3Compliance.s.sol
Normal file
33
script/hybx-omnl/WireOMNLWeb3Compliance.s.sol
Normal file
@@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {ReserveCommitmentStore} from "../../contracts/hybx-omnl/ReserveCommitmentStore.sol";
|
||||
import {OMNLNotaryRegistry} from "../../contracts/hybx-omnl/OMNLNotaryRegistry.sol";
|
||||
import {OMNLComplianceMultisig} from "../../contracts/hybx-omnl/OMNLComplianceMultisig.sol";
|
||||
|
||||
/// @notice Wire reserve store notary gate + align attestation threshold with jurisdiction policy.
|
||||
contract WireOMNLWeb3Compliance is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address reserves = vm.envAddress("OMNL_RESERVE_COMMITMENT_STORE");
|
||||
address notary = vm.envAddress("OMNL_NOTARY_REGISTRY");
|
||||
OMNLComplianceMultisig multisig = OMNLComplianceMultisig(payable(vm.envAddress("OMNL_COMPLIANCE_MULTISIG")));
|
||||
|
||||
bytes32 jurId = keccak256(bytes(vm.envOr("OMNL_JURISDICTION_ID", string("ID"))));
|
||||
bytes32 matrixId = keccak256(bytes(vm.envOr("OMNL_MATRIX_CONTROL_ID", string("ID-OMNL-001"))));
|
||||
bool requireNotary = vm.envOr("OMNL_REQUIRE_NOTARIZED_RESERVE", true);
|
||||
uint256 attTh = vm.envOr("OMNL_RESERVE_ATTESTATION_THRESHOLD", uint256(3));
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
ReserveCommitmentStore(reserves).configureNotaryGate(notary, requireNotary, jurId, matrixId);
|
||||
ReserveCommitmentStore(reserves).setAttestationThreshold(attTh);
|
||||
|
||||
address admin = vm.addr(pk);
|
||||
OMNLNotaryRegistry(notary).grantRole(OMNLNotaryRegistry(notary).NOTARY_ADMIN_ROLE(), address(multisig));
|
||||
multisig.grantRole(multisig.PROPOSER_ROLE(), admin);
|
||||
vm.stopBroadcast();
|
||||
|
||||
console2.log("Wired notary gate on ReserveCommitmentStore", reserves);
|
||||
}
|
||||
}
|
||||
151
script/m00-diamond/DeployM00DiamondHub138.s.sol
Normal file
151
script/m00-diamond/DeployM00DiamondHub138.s.sol
Normal file
@@ -0,0 +1,151 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import {GrcDiamond} from "@gru/GrcDiamond.sol";
|
||||
import {IDiamondCut} from "@gru/interfaces/IDiamondCut.sol";
|
||||
import {PauseFacet} from "@gru/facets/PauseFacet.sol";
|
||||
import {AccessFacet} from "@gru/facets/AccessFacet.sol";
|
||||
import {M00MainnetBridgeFacet} from "../../contracts/m00-diamond/facets/M00MainnetBridgeFacet.sol";
|
||||
import {M00DiamondInit} from "../../contracts/m00-diamond/M00DiamondInit.sol";
|
||||
import {RWAInstrumentFacet} from "../../contracts/rwa/diamond/facets/RWAInstrumentFacet.sol";
|
||||
import {RWADocumentFacet} from "../../contracts/rwa/diamond/facets/RWADocumentFacet.sol";
|
||||
import {RWAStandardsRegistryFacet} from "../../contracts/rwa/diamond/facets/RWAStandardsRegistryFacet.sol";
|
||||
import {IM00MainnetBridgeFacet} from "../../contracts/m00-diamond/interfaces/IM00MainnetBridgeFacet.sol";
|
||||
import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";
|
||||
|
||||
/**
|
||||
* @title DeployM00DiamondHub138
|
||||
* @notice Deploy GRC-2535 M00 Diamond hub on Chain 138 with RWA + mainnet mirror/tether/checkpoint bridge facet.
|
||||
* @dev Paris profile mandatory. Wire env from project .env (load-project-env before forge).
|
||||
*
|
||||
* Env: PRIVATE_KEY, GOVERNANCE_CONTROLLER or OWNER
|
||||
* CHAIN138_BATCH_EMITTER, TRANSACTION_MIRROR_ADDRESS (138 local), CHAIN138_MAINNET_CHECKPOINT_PROXY (mainnet)
|
||||
* TRANSACTION_MIRROR_MAINNET, MAINNET_TETHER_ADDRESS
|
||||
* RWA_TOKEN_FACTORY, RWA_TOKEN_REGISTRY
|
||||
*/
|
||||
contract DeployM00DiamondHub138 is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address governance = vm.envOr("GOVERNANCE_CONTROLLER", vm.envOr("OWNER", deployer));
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
// Diamond owner must be broadcaster for initial diamondCut (ErrUpgradeRole otherwise).
|
||||
GrcDiamond diamond = new GrcDiamond(deployer, "M00.1.0");
|
||||
PauseFacet pause = new PauseFacet();
|
||||
AccessFacet access = new AccessFacet();
|
||||
M00MainnetBridgeFacet bridge = new M00MainnetBridgeFacet(governance);
|
||||
RWAInstrumentFacet rwaInst = new RWAInstrumentFacet(governance);
|
||||
RWADocumentFacet rwaDoc = new RWADocumentFacet(governance);
|
||||
RWAStandardsRegistryFacet rwaStd = new RWAStandardsRegistryFacet(governance);
|
||||
M00DiamondInit init = new M00DiamondInit();
|
||||
|
||||
IDiamondCut.FacetCut[] memory cut = _buildCuts(
|
||||
address(pause), address(access), address(bridge), address(rwaInst), address(rwaDoc), address(rwaStd)
|
||||
);
|
||||
|
||||
IM00MainnetBridgeFacet.BridgeConfig memory cfg = IM00MainnetBridgeFacet.BridgeConfig({
|
||||
chain138BatchEmitter: vm.envOr("CHAIN138_BATCH_EMITTER", address(0)),
|
||||
chain138Mirror: vm.envOr("TRANSACTION_MIRROR_ADDRESS", address(0)),
|
||||
mainnetCheckpoint: vm.envOr("CHAIN138_MAINNET_CHECKPOINT_PROXY", address(0)),
|
||||
mainnetMirror: vm.envOr("TRANSACTION_MIRROR_MAINNET", address(0)),
|
||||
mainnetTether: vm.envOr("MAINNET_TETHER_ADDRESS", address(0)),
|
||||
rwaTokenFactory: vm.envOr("RWA_TOKEN_FACTORY", address(0)),
|
||||
rwaTokenRegistry: vm.envOr("RWA_TOKEN_REGISTRY", address(0))
|
||||
});
|
||||
|
||||
diamond.diamondCut(cut, address(init), abi.encodeCall(M00DiamondInit.init, (cfg, governance)));
|
||||
|
||||
console.log("M00Diamond", address(diamond));
|
||||
console.log("M00MainnetBridgeFacet", address(bridge));
|
||||
console.log("RWAInstrumentFacet", address(rwaInst));
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
function _buildCuts(
|
||||
address pause,
|
||||
address access,
|
||||
address bridge,
|
||||
address rwaInst,
|
||||
address rwaDoc,
|
||||
address rwaStd
|
||||
) internal pure returns (IDiamondCut.FacetCut[] memory cut) {
|
||||
cut = new IDiamondCut.FacetCut[](6);
|
||||
cut[0] = _add(pause, _pauseSelectors());
|
||||
cut[1] = _add(access, _accessSelectors());
|
||||
cut[2] = _add(bridge, _bridgeSelectors());
|
||||
cut[3] = _add(rwaInst, _rwaInstSelectors());
|
||||
cut[4] = _add(rwaDoc, _rwaDocSelectors());
|
||||
cut[5] = _add(rwaStd, _rwaStdSelectors());
|
||||
}
|
||||
|
||||
function _add(address facet, bytes4[] memory sels)
|
||||
internal
|
||||
pure
|
||||
returns (IDiamondCut.FacetCut memory)
|
||||
{
|
||||
return IDiamondCut.FacetCut({
|
||||
facetAddress: facet,
|
||||
action: IDiamondCut.FacetCutAction.Add,
|
||||
functionSelectors: sels
|
||||
});
|
||||
}
|
||||
|
||||
function _pauseSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](4);
|
||||
s[0] = PauseFacet.setGlobalPause.selector;
|
||||
s[1] = PauseFacet.setFunctionPause.selector;
|
||||
s[2] = PauseFacet.isPaused.selector;
|
||||
s[3] = PauseFacet.isGlobalPaused.selector;
|
||||
}
|
||||
|
||||
function _accessSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](6);
|
||||
s[0] = AccessFacet.grantRoles.selector;
|
||||
s[1] = AccessFacet.revokeRoles.selector;
|
||||
s[2] = AccessFacet.ROLE_UPGRADE_BIT.selector;
|
||||
s[3] = AccessFacet.ROLE_GOVERNANCE_BIT.selector;
|
||||
s[4] = AccessFacet.ROLE_INDEX_BIT.selector;
|
||||
s[5] = AccessFacet.ROLE_MONETARY_BIT.selector;
|
||||
}
|
||||
|
||||
function _bridgeSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](11);
|
||||
s[0] = M00MainnetBridgeFacet.wireMainnetBridge.selector;
|
||||
s[1] = M00MainnetBridgeFacet.getMainnetBridgeConfig.selector;
|
||||
s[2] = M00MainnetBridgeFacet.commitBatchOn138.selector;
|
||||
s[3] = M00MainnetBridgeFacet.sendBatchToMainnet.selector;
|
||||
s[4] = M00MainnetBridgeFacet.scheduleMirrorToMainnet.selector;
|
||||
s[5] = M00MainnetBridgeFacet.mirrorOnMainnet.selector;
|
||||
s[6] = M00MainnetBridgeFacet.anchorStateProofOnMainnet.selector;
|
||||
s[7] = M00MainnetBridgeFacet.ackInboundCheckpoint.selector;
|
||||
s[8] = IAccessControl.grantRole.selector;
|
||||
s[9] = IAccessControl.revokeRole.selector;
|
||||
s[10] = IAccessControl.hasRole.selector;
|
||||
}
|
||||
|
||||
function _rwaInstSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](5);
|
||||
s[0] = RWAInstrumentFacet.setIssuanceMode.selector;
|
||||
s[1] = RWAInstrumentFacet.setInstrumentIdentity.selector;
|
||||
s[2] = RWAInstrumentFacet.setTokenPointer.selector;
|
||||
s[3] = RWAInstrumentFacet.getIssuanceMode.selector;
|
||||
s[4] = RWAInstrumentFacet.getTokenPointer.selector;
|
||||
}
|
||||
|
||||
function _rwaDocSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](2);
|
||||
s[0] = RWADocumentFacet.anchorDocument.selector;
|
||||
s[1] = RWADocumentFacet.setPrimaryContentHash.selector;
|
||||
}
|
||||
|
||||
function _rwaStdSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](3);
|
||||
s[0] = RWAStandardsRegistryFacet.enableStandard.selector;
|
||||
s[1] = RWAStandardsRegistryFacet.disableStandard.selector;
|
||||
s[2] = RWAStandardsRegistryFacet.bindAssetStandardFacet.selector;
|
||||
}
|
||||
}
|
||||
33
script/m00-diamond/UpgradeM00DiamondAcl138.s.sol
Normal file
33
script/m00-diamond/UpgradeM00DiamondAcl138.s.sol
Normal file
@@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import {IDiamondCut} from "@gru/interfaces/IDiamondCut.sol";
|
||||
import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";
|
||||
|
||||
/**
|
||||
* @notice Add OZ AccessControl admin selectors to existing M00MainnetBridgeFacet on live hub.
|
||||
*/
|
||||
contract UpgradeM00DiamondAcl138 is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address diamond = vm.envAddress("M00_DIAMOND_HUB");
|
||||
address bridgeFacet = vm.envAddress("M00_MAINNET_BRIDGE_FACET");
|
||||
|
||||
bytes4[] memory sels = new bytes4[](3);
|
||||
sels[0] = IAccessControl.grantRole.selector;
|
||||
sels[1] = IAccessControl.revokeRole.selector;
|
||||
sels[2] = IAccessControl.hasRole.selector;
|
||||
|
||||
IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);
|
||||
cut[0] = IDiamondCut.FacetCut({
|
||||
facetAddress: bridgeFacet,
|
||||
action: IDiamondCut.FacetCutAction.Add,
|
||||
functionSelectors: sels
|
||||
});
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
IDiamondCut(diamond).diamondCut(cut, address(0), "");
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
35
script/mainnet-checkpoint/CheckpointConfigLib.s.sol
Normal file
35
script/mainnet-checkpoint/CheckpointConfigLib.s.sol
Normal file
@@ -0,0 +1,35 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script} from "forge-std/Script.sol";
|
||||
import {CheckpointHubConfig} from "../../contracts/mainnet-checkpoint/libraries/CheckpointHubConfig.sol";
|
||||
import {BatchEmitterConfig} from "../../contracts/mainnet-checkpoint/libraries/BatchEmitterConfig.sol";
|
||||
|
||||
/// @notice Shared env → config parsing for deploy/configure scripts.
|
||||
abstract contract CheckpointConfigScript is Script {
|
||||
function hubConfigFromEnv() internal view returns (CheckpointHubConfig.HubConfig memory cfg) {
|
||||
cfg = CheckpointHubConfig.mainnetDefaults();
|
||||
cfg.batchSize = uint16(vm.envOr("CHECKPOINT_BATCH_SIZE", uint256(cfg.batchSize)));
|
||||
cfg.maxBatchWaitSeconds = uint32(vm.envOr("CHECKPOINT_MAX_WAIT_SECONDS", uint256(cfg.maxBatchWaitSeconds)));
|
||||
cfg.minPaymentValueWei = vm.envOr("CHECKPOINT_MIN_PAYMENT_VALUE_WEI", uint256(0));
|
||||
cfg.requireValidatorSigs = vm.envOr("CHECKPOINT_REQUIRE_VALIDATOR_SIGS", cfg.requireValidatorSigs);
|
||||
cfg.allowCalldataOnlySubmit = vm.envOr("CHECKPOINT_ALLOW_CALLDATA_ONLY", cfg.allowCalldataOnlySubmit);
|
||||
cfg.allowCCIPIngress = vm.envOr("CHECKPOINT_ALLOW_CCIP_INGRESS", cfg.allowCCIPIngress);
|
||||
cfg.enforcePreviousBatchId = vm.envOr("CHECKPOINT_ENFORCE_PREVIOUS_BATCH_ID", cfg.enforcePreviousBatchId);
|
||||
cfg.ccipRouter = vm.envOr("CCIP_ROUTER_MAINNET", address(0));
|
||||
cfg.sourceChainSelector = uint64(vm.envOr("CCIP_CHAIN_SELECTOR_138", uint256(0)));
|
||||
cfg.batchEmitterOnSource = vm.envOr("CHAIN138_BATCH_EMITTER", address(0));
|
||||
cfg.legacyMirrorV1 = vm.envOr("TRANSACTION_MIRROR_MAINNET", address(0));
|
||||
cfg.legacyTetherV1 = vm.envOr("MAINNET_TETHER_ADDRESS", address(0));
|
||||
cfg.submitterAttestationSigner = vm.envOr("CHECKPOINT_ATTESTATION_SIGNER", address(0));
|
||||
CheckpointHubConfig.validate(cfg);
|
||||
}
|
||||
|
||||
function emitterConfigFromEnv() internal view returns (BatchEmitterConfig.EmitterConfig memory cfg) {
|
||||
cfg.ccipRouter = vm.envAddress("CCIP_ROUTER_CHAIN138");
|
||||
cfg.linkToken = vm.envAddress("LINK_TOKEN_CHAIN138");
|
||||
cfg.mainnetChainSelector = uint64(vm.envUint("CCIP_CHAIN_SELECTOR_MAINNET"));
|
||||
cfg.mainnetCheckpoint = vm.envAddress("CHAIN138_MAINNET_CHECKPOINT_PROXY");
|
||||
BatchEmitterConfig.validate(cfg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {SubmitRateLimitExtension} from "../../contracts/mainnet-checkpoint/extensions/SubmitRateLimitExtension.sol";
|
||||
import {TimelockSubmitExtension} from "../../contracts/mainnet-checkpoint/extensions/TimelockSubmitExtension.sol";
|
||||
import {ValidatorSigVerifierExtension} from "../../contracts/mainnet-checkpoint/extensions/ValidatorSigVerifierExtension.sol";
|
||||
import {TokenTransferFilterExtension} from "../../contracts/mainnet-checkpoint/extensions/TokenTransferFilterExtension.sol";
|
||||
import {ZkStateRootVerifierExtension} from "../../contracts/mainnet-checkpoint/extensions/ZkStateRootVerifierExtension.sol";
|
||||
import {BlockHeaderOracleExtension} from "../../contracts/mainnet-checkpoint/extensions/BlockHeaderOracleExtension.sol";
|
||||
import {MinPaymentValueExtension} from "../../contracts/mainnet-checkpoint/extensions/MinPaymentValueExtension.sol";
|
||||
|
||||
/// @notice Per-extension granular tuning from env (post-deploy).
|
||||
contract ConfigureCheckpointExtensions is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
address rateLimit = vm.envOr("EXT_RATE_LIMIT", address(0));
|
||||
if (rateLimit != address(0)) {
|
||||
uint256 maxPerHour = vm.envOr("CHECKPOINT_RATE_LIMIT_MAX_PER_HOUR", uint256(120));
|
||||
SubmitRateLimitExtension(rateLimit).setMaxBatchesPerHour(maxPerHour);
|
||||
console.log("RateLimit max/hour", maxPerHour);
|
||||
}
|
||||
|
||||
address timelock = vm.envOr("EXT_TIMELOCK", address(0));
|
||||
if (timelock != address(0)) {
|
||||
uint256 delay = vm.envOr("CHECKPOINT_TIMELOCK_DELAY_SECONDS", uint256(48 hours));
|
||||
TimelockSubmitExtension(timelock).setDelay(delay);
|
||||
console.log("Timelock delay", delay);
|
||||
}
|
||||
|
||||
address validator = vm.envOr("EXT_VALIDATOR_SIG", address(0));
|
||||
if (validator != address(0)) {
|
||||
address hub = vm.envAddress("CHAIN138_MAINNET_CHECKPOINT_PROXY");
|
||||
ValidatorSigVerifierExtension(validator).setVerifyingContract(hub);
|
||||
uint256 threshold = vm.envOr("CHECKPOINT_VALIDATOR_THRESHOLD", uint256(1));
|
||||
address[] memory addrs = new address[](1);
|
||||
addrs[0] = vm.envOr("CHECKPOINT_VALIDATOR_ADDRESS", vm.addr(pk));
|
||||
ValidatorSigVerifierExtension(validator).setValidators(addrs, threshold);
|
||||
}
|
||||
|
||||
address tokenFilter = vm.envOr("EXT_TOKEN_FILTER", address(0));
|
||||
if (tokenFilter != address(0)) {
|
||||
TokenTransferFilterExtension filter = TokenTransferFilterExtension(tokenFilter);
|
||||
bool allowNative = vm.envOr("CHECKPOINT_TOKEN_FILTER_ALLOW_NATIVE", true);
|
||||
uint256 minNative = vm.envOr("CHECKPOINT_TOKEN_FILTER_MIN_NATIVE_WEI", uint256(0));
|
||||
filter.setAllowNative(allowNative, minNative);
|
||||
_allowToken(filter, vm.envOr("CUSDT_CHAIN138", address(0)));
|
||||
_allowToken(filter, vm.envOr("CUSDC_CHAIN138", address(0)));
|
||||
}
|
||||
|
||||
address zk = vm.envOr("EXT_ZK_STATE_ROOT", address(0));
|
||||
if (zk != address(0)) {
|
||||
bool requireZk = vm.envOr("CHECKPOINT_REQUIRE_ZK_PROOF", false);
|
||||
ZkStateRootVerifierExtension(zk).setRequireZkProof(requireZk);
|
||||
}
|
||||
|
||||
address blockOracle = vm.envOr("EXT_BLOCK_ORACLE", address(0));
|
||||
if (blockOracle != address(0)) {
|
||||
BlockHeaderOracleExtension oracle = BlockHeaderOracleExtension(blockOracle);
|
||||
oracle.setRequireOracleRecord(vm.envOr("CHECKPOINT_BLOCK_ORACLE_REQUIRED", true));
|
||||
address updater = vm.envOr("CHECKPOINT_ORACLE_UPDATER", vm.addr(pk));
|
||||
oracle.grantRole(keccak256("ORACLE_UPDATER_ROLE"), updater);
|
||||
}
|
||||
|
||||
address minPay = vm.envOr("EXT_MIN_PAYMENT", address(0));
|
||||
address hubProxy = vm.envOr("CHAIN138_MAINNET_CHECKPOINT_PROXY", address(0));
|
||||
if (minPay != address(0) && hubProxy != address(0)) {
|
||||
MinPaymentValueExtension(minPay).setHub(hubProxy);
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
function _allowToken(TokenTransferFilterExtension filter, address token) internal {
|
||||
if (token == address(0)) return;
|
||||
filter.setAllowedToken(token, true);
|
||||
console.log("Allowed token", token);
|
||||
}
|
||||
}
|
||||
26
script/mainnet-checkpoint/ConfigureCheckpointHub.s.sol
Normal file
26
script/mainnet-checkpoint/ConfigureCheckpointHub.s.sol
Normal file
@@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {Chain138MainnetCheckpoint} from "../../contracts/mainnet-checkpoint/Chain138MainnetCheckpoint.sol";
|
||||
import {CheckpointHubConfig} from "../../contracts/mainnet-checkpoint/libraries/CheckpointHubConfig.sol";
|
||||
import {CheckpointConfigScript} from "./CheckpointConfigLib.s.sol";
|
||||
|
||||
/// @notice Apply granular hub config from env (post-deploy). Run predeploy gate first.
|
||||
contract ConfigureCheckpointHub is CheckpointConfigScript {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address proxy = vm.envAddress("CHAIN138_MAINNET_CHECKPOINT_PROXY");
|
||||
Chain138MainnetCheckpoint hub = Chain138MainnetCheckpoint(proxy);
|
||||
CheckpointHubConfig.HubConfig memory cfg = hubConfigFromEnv();
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
hub.applyConfig(cfg);
|
||||
vm.stopBroadcast();
|
||||
|
||||
CheckpointHubConfig.HubConfig memory onChain = hub.getFullConfig();
|
||||
console.log("batchSize", onChain.batchSize);
|
||||
console.log("maxBatchWaitSeconds", onChain.maxBatchWaitSeconds);
|
||||
console.log("allowCCIPIngress", onChain.allowCCIPIngress);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {AddressActivityRegistry} from "../../contracts/mainnet-checkpoint/AddressActivityRegistry.sol";
|
||||
|
||||
contract DeployAddressActivityRegistry is Script {
|
||||
function run() external {
|
||||
address admin = vm.envOr("CHECKPOINT_ADMIN", msg.sender);
|
||||
vm.startBroadcast();
|
||||
AddressActivityRegistry registry = new AddressActivityRegistry(admin);
|
||||
console.log("AddressActivityRegistry:", address(registry));
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {AddressActivityRegistryV2} from "../../contracts/mainnet-checkpoint/AddressActivityRegistryV2.sol";
|
||||
|
||||
contract DeployAddressActivityRegistryV2 is Script {
|
||||
function run() external {
|
||||
address admin = vm.envOr("CHECKPOINT_ADMIN", msg.sender);
|
||||
vm.startBroadcast();
|
||||
AddressActivityRegistryV2 registry = new AddressActivityRegistryV2(admin);
|
||||
console.log("AddressActivityRegistryV2:", address(registry));
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {MirrorDetailExtension} from "../../contracts/mainnet-checkpoint/extensions/MirrorDetailExtension.sol";
|
||||
import {ValidatorSigVerifierExtension} from "../../contracts/mainnet-checkpoint/extensions/ValidatorSigVerifierExtension.sol";
|
||||
import {AttestationURIExtension} from "../../contracts/mainnet-checkpoint/extensions/AttestationURIExtension.sol";
|
||||
import {SubmitRateLimitExtension} from "../../contracts/mainnet-checkpoint/extensions/SubmitRateLimitExtension.sol";
|
||||
import {TokenTransferFilterExtension} from "../../contracts/mainnet-checkpoint/extensions/TokenTransferFilterExtension.sol";
|
||||
import {CwTransportLinkExtension} from "../../contracts/mainnet-checkpoint/extensions/CwTransportLinkExtension.sol";
|
||||
import {TimelockSubmitExtension} from "../../contracts/mainnet-checkpoint/extensions/TimelockSubmitExtension.sol";
|
||||
import {MetricsExtension} from "../../contracts/mainnet-checkpoint/extensions/MetricsExtension.sol";
|
||||
import {ZkStateRootVerifierExtension} from "../../contracts/mainnet-checkpoint/extensions/ZkStateRootVerifierExtension.sol";
|
||||
import {PaymasterHintExtension} from "../../contracts/mainnet-checkpoint/extensions/PaymasterHintExtension.sol";
|
||||
import {L2OracleAdapterExtension} from "../../contracts/mainnet-checkpoint/extensions/L2OracleAdapterExtension.sol";
|
||||
import {BlockHeaderOracleExtension} from "../../contracts/mainnet-checkpoint/extensions/BlockHeaderOracleExtension.sol";
|
||||
import {MinPaymentValueExtension} from "../../contracts/mainnet-checkpoint/extensions/MinPaymentValueExtension.sol";
|
||||
import {LegacyCheckpointAdapter} from "../../contracts/mainnet-checkpoint/LegacyCheckpointAdapter.sol";
|
||||
|
||||
/// @notice Deploy all optional extension modules + legacy read adapter (non-proxy).
|
||||
contract DeployAllCheckpointExtensions is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.envOr("CHECKPOINT_ADMIN", vm.addr(pk));
|
||||
address checkpoint = vm.envAddress("CHAIN138_MAINNET_CHECKPOINT_PROXY");
|
||||
address mirror = vm.envOr("TRANSACTION_MIRROR_MAINNET", address(0));
|
||||
address tether = vm.envOr("MAINNET_TETHER_ADDRESS", address(0));
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
console.log("MirrorDetail:", address(new MirrorDetailExtension()));
|
||||
console.log("ValidatorSig:", address(new ValidatorSigVerifierExtension()));
|
||||
console.log("AttestationURI:", address(new AttestationURIExtension()));
|
||||
console.log("RateLimit:", address(new SubmitRateLimitExtension()));
|
||||
console.log("TokenFilter:", address(new TokenTransferFilterExtension()));
|
||||
console.log("CwLink:", address(new CwTransportLinkExtension()));
|
||||
console.log("Timelock:", address(new TimelockSubmitExtension()));
|
||||
console.log("Metrics:", address(new MetricsExtension()));
|
||||
console.log("ZkStateRoot:", address(new ZkStateRootVerifierExtension()));
|
||||
console.log("PaymasterHint:", address(new PaymasterHintExtension()));
|
||||
console.log("L2Oracle:", address(new L2OracleAdapterExtension()));
|
||||
console.log("BlockOracle:", address(new BlockHeaderOracleExtension(admin)));
|
||||
console.log("MinPayment:", address(new MinPaymentValueExtension()));
|
||||
console.log("AddressActivityRegistry: deploy separately via scripts/deployment/deploy-address-activity-registry.sh");
|
||||
if (mirror != address(0) && tether != address(0)) {
|
||||
console.log("LegacyAdapter:", address(new LegacyCheckpointAdapter(checkpoint, mirror, tether)));
|
||||
}
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
28
script/mainnet-checkpoint/DeployChain138BatchEmitter.s.sol
Normal file
28
script/mainnet-checkpoint/DeployChain138BatchEmitter.s.sol
Normal file
@@ -0,0 +1,28 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
||||
import {Chain138BatchEmitter} from "../../contracts/mainnet-checkpoint/chain138/Chain138BatchEmitter.sol";
|
||||
|
||||
contract DeployChain138BatchEmitter is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.envOr("CHECKPOINT_ADMIN", vm.addr(pk));
|
||||
address ccipRouter = vm.envAddress("CCIP_ROUTER_CHAIN138");
|
||||
address linkToken = vm.envAddress("LINK_TOKEN_CHAIN138");
|
||||
uint64 mainnetSelector = uint64(vm.envUint("CCIP_CHAIN_SELECTOR_MAINNET"));
|
||||
address mainnetCheckpoint = vm.envAddress("CHAIN138_MAINNET_CHECKPOINT_PROXY");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
Chain138BatchEmitter impl = new Chain138BatchEmitter();
|
||||
bytes memory initData = abi.encodeCall(
|
||||
Chain138BatchEmitter.initialize,
|
||||
(admin, ccipRouter, linkToken, mainnetSelector, mainnetCheckpoint)
|
||||
);
|
||||
ERC1967Proxy proxy = new ERC1967Proxy(address(impl), initData);
|
||||
console.log("Chain138BatchEmitter impl:", address(impl));
|
||||
console.log("Chain138BatchEmitter proxy:", address(proxy));
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
||||
import {Chain138MainnetCheckpoint} from "../../contracts/mainnet-checkpoint/Chain138MainnetCheckpoint.sol";
|
||||
|
||||
contract DeployChain138MainnetCheckpoint is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.envOr("CHECKPOINT_ADMIN", vm.addr(pk));
|
||||
address ccipRouter = vm.envAddress("CCIP_ROUTER_MAINNET");
|
||||
uint64 sourceSelector = uint64(vm.envUint("CCIP_CHAIN_SELECTOR_138"));
|
||||
address batchEmitter = vm.envOr("CHAIN138_BATCH_EMITTER", address(0));
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
Chain138MainnetCheckpoint impl = new Chain138MainnetCheckpoint();
|
||||
bytes memory initData = abi.encodeCall(
|
||||
Chain138MainnetCheckpoint.initialize,
|
||||
(admin, ccipRouter, sourceSelector, batchEmitter)
|
||||
);
|
||||
ERC1967Proxy proxy = new ERC1967Proxy(address(impl), initData);
|
||||
console.log("Chain138MainnetCheckpoint impl:", address(impl));
|
||||
console.log("Chain138MainnetCheckpoint proxy:", address(proxy));
|
||||
console.log("Admin:", admin);
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {Chain138ParticipantSurface} from "../../contracts/mainnet-checkpoint/Chain138ParticipantSurface.sol";
|
||||
|
||||
contract DeployChain138ParticipantSurface is Script {
|
||||
function run() external {
|
||||
address admin = vm.envOr("CHECKPOINT_ADMIN", msg.sender);
|
||||
vm.startBroadcast();
|
||||
Chain138ParticipantSurface surface = new Chain138ParticipantSurface(admin);
|
||||
console.log("Chain138ParticipantSurface:", address(surface));
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
15
script/mainnet-checkpoint/DeployISO20022IntakeGateway.s.sol
Normal file
15
script/mainnet-checkpoint/DeployISO20022IntakeGateway.s.sol
Normal file
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {ISO20022IntakeGateway} from "../../contracts/mainnet-checkpoint/ISO20022IntakeGateway.sol";
|
||||
|
||||
contract DeployISO20022IntakeGateway is Script {
|
||||
function run() external {
|
||||
address admin = vm.envOr("CHECKPOINT_ADMIN", msg.sender);
|
||||
vm.startBroadcast();
|
||||
ISO20022IntakeGateway gateway = new ISO20022IntakeGateway(admin);
|
||||
console.log("ISO20022IntakeGateway:", address(gateway));
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
21
script/mainnet-checkpoint/ReenableCheckpointExtensions.s.sol
Normal file
21
script/mainnet-checkpoint/ReenableCheckpointExtensions.s.sol
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {Chain138MainnetCheckpoint} from "../../contracts/mainnet-checkpoint/Chain138MainnetCheckpoint.sol";
|
||||
import {ExtensionIds} from "../../contracts/mainnet-checkpoint/libraries/ExtensionIds.sol";
|
||||
|
||||
/// @notice Re-enable extensions after hub v3 + token filter replace (env: EXT_VALIDATOR_SIG optional sanity).
|
||||
contract ReenableCheckpointExtensions is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
Chain138MainnetCheckpoint hub = Chain138MainnetCheckpoint(vm.envAddress("CHAIN138_MAINNET_CHECKPOINT_PROXY"));
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
hub.setExtensionActive(ExtensionIds.VALIDATOR_SIG, true);
|
||||
console.log("VALIDATOR_SIG active");
|
||||
hub.setExtensionActive(ExtensionIds.TOKEN_FILTER, true);
|
||||
console.log("TOKEN_FILTER active");
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
42
script/mainnet-checkpoint/RegisterCheckpointExtensions.s.sol
Normal file
42
script/mainnet-checkpoint/RegisterCheckpointExtensions.s.sol
Normal file
@@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {Chain138MainnetCheckpoint} from "../../contracts/mainnet-checkpoint/Chain138MainnetCheckpoint.sol";
|
||||
import {ExtensionIds} from "../../contracts/mainnet-checkpoint/libraries/ExtensionIds.sol";
|
||||
import {ICheckpointExtension} from "../../contracts/mainnet-checkpoint/interfaces/ICheckpointExtension.sol";
|
||||
|
||||
/// @notice Register deployed extensions on the checkpoint hub (env: EXT_* addresses).
|
||||
contract RegisterCheckpointExtensions is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address proxy = vm.envAddress("CHAIN138_MAINNET_CHECKPOINT_PROXY");
|
||||
Chain138MainnetCheckpoint hub = Chain138MainnetCheckpoint(proxy);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
_register(hub, ExtensionIds.METRICS, vm.envAddress("EXT_METRICS"));
|
||||
_register(hub, ExtensionIds.CONTENT_URI, vm.envAddress("EXT_ATTESTATION_URI"));
|
||||
_register(hub, ExtensionIds.RATE_LIMIT, vm.envAddress("EXT_RATE_LIMIT"));
|
||||
_register(hub, ExtensionIds.VALIDATOR_SIG, vm.envAddress("EXT_VALIDATOR_SIG"));
|
||||
_register(hub, ExtensionIds.TOKEN_FILTER, vm.envAddress("EXT_TOKEN_FILTER"));
|
||||
_register(hub, ExtensionIds.CW_LINK, vm.envAddress("EXT_CW_LINK"));
|
||||
_register(hub, ExtensionIds.GOV_TIMELOCK, vm.envAddress("EXT_TIMELOCK"));
|
||||
_register(hub, ExtensionIds.MIRROR_DETAIL, vm.envAddress("EXT_MIRROR_DETAIL"));
|
||||
_register(hub, ExtensionIds.ZK_STATE_ROOT, vm.envAddress("EXT_ZK_STATE_ROOT"));
|
||||
_register(hub, ExtensionIds.PAYMASTER_HINT, vm.envAddress("EXT_PAYMASTER_HINT"));
|
||||
_register(hub, ExtensionIds.L2_ORACLE, vm.envAddress("EXT_L2_ORACLE"));
|
||||
_register(hub, ExtensionIds.BLOCK_ORACLE, vm.envAddress("EXT_BLOCK_ORACLE"));
|
||||
_register(hub, ExtensionIds.MIN_PAYMENT, vm.envAddress("EXT_MIN_PAYMENT"));
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
function _register(Chain138MainnetCheckpoint hub, bytes32 id, address module) internal {
|
||||
if (module == address(0)) return;
|
||||
uint32 hooks = ICheckpointExtension(module).HOOK_BEFORE_SUBMIT()
|
||||
| ICheckpointExtension(module).HOOK_AFTER_SUBMIT()
|
||||
| ICheckpointExtension(module).HOOK_ON_CCIP()
|
||||
| ICheckpointExtension(module).HOOK_VERIFY_LEAF();
|
||||
hub.registerExtension(id, module, hooks);
|
||||
console.log("Registered", vm.toString(id), module);
|
||||
}
|
||||
}
|
||||
27
script/mainnet-checkpoint/ReplaceMirrorDetailExtension.s.sol
Normal file
27
script/mainnet-checkpoint/ReplaceMirrorDetailExtension.s.sol
Normal file
@@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {Chain138MainnetCheckpoint} from "../../contracts/mainnet-checkpoint/Chain138MainnetCheckpoint.sol";
|
||||
import {MirrorDetailExtension} from "../../contracts/mainnet-checkpoint/extensions/MirrorDetailExtension.sol";
|
||||
import {ExtensionIds} from "../../contracts/mainnet-checkpoint/libraries/ExtensionIds.sol";
|
||||
|
||||
contract ReplaceMirrorDetailExtension is Script {
|
||||
function run() external {
|
||||
address proxy = vm.envAddress("CHAIN138_MAINNET_CHECKPOINT_PROXY");
|
||||
address oldMirror = vm.envAddress("EXT_MIRROR_DETAIL");
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
MirrorDetailExtension mirror = new MirrorDetailExtension();
|
||||
console.log("New MirrorDetail:", address(mirror));
|
||||
|
||||
Chain138MainnetCheckpoint hub = Chain138MainnetCheckpoint(proxy);
|
||||
hub.setExtensionActive(ExtensionIds.MIRROR_DETAIL, true);
|
||||
hub.revokeExtension(ExtensionIds.MIRROR_DETAIL);
|
||||
hub.registerExtension(ExtensionIds.MIRROR_DETAIL, address(mirror), mirror.HOOK_AFTER_SUBMIT());
|
||||
hub.setExtensionActive(ExtensionIds.MIRROR_DETAIL, true);
|
||||
console.log("Replaced mirror (old was):", oldMirror);
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {Chain138MainnetCheckpoint} from "../../contracts/mainnet-checkpoint/Chain138MainnetCheckpoint.sol";
|
||||
import {ExtensionIds} from "../../contracts/mainnet-checkpoint/libraries/ExtensionIds.sol";
|
||||
import {TokenTransferFilterExtension} from "../../contracts/mainnet-checkpoint/extensions/TokenTransferFilterExtension.sol";
|
||||
import {ICheckpointExtension} from "../../contracts/mainnet-checkpoint/interfaces/ICheckpointExtension.sol";
|
||||
|
||||
/// @notice Deploy fixed TokenTransferFilterExtension and swap on hub (revoke + register).
|
||||
contract ReplaceTokenTransferFilterExtension is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address hubAddr = vm.envAddress("CHAIN138_MAINNET_CHECKPOINT_PROXY");
|
||||
Chain138MainnetCheckpoint hub = Chain138MainnetCheckpoint(hubAddr);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
TokenTransferFilterExtension filter = new TokenTransferFilterExtension();
|
||||
console.log("New TokenTransferFilter:", address(filter));
|
||||
|
||||
bool allowNative = vm.envOr("CHECKPOINT_TOKEN_FILTER_ALLOW_NATIVE", true);
|
||||
uint256 minNative = vm.envOr("CHECKPOINT_TOKEN_FILTER_MIN_NATIVE_WEI", uint256(0));
|
||||
filter.setAllowNative(allowNative, minNative);
|
||||
|
||||
bytes32 id = ExtensionIds.TOKEN_FILTER;
|
||||
(, , bool wasActive) = hub.getExtension(id);
|
||||
if (!wasActive) {
|
||||
hub.setExtensionActive(id, true);
|
||||
}
|
||||
hub.revokeExtension(id);
|
||||
uint32 hooks = ICheckpointExtension(address(filter)).HOOK_BEFORE_SUBMIT()
|
||||
| ICheckpointExtension(address(filter)).HOOK_AFTER_SUBMIT()
|
||||
| ICheckpointExtension(address(filter)).HOOK_ON_CCIP()
|
||||
| ICheckpointExtension(address(filter)).HOOK_VERIFY_LEAF();
|
||||
hub.registerExtension(id, address(filter), hooks);
|
||||
hub.setExtensionActive(id, true);
|
||||
console.log("TOKEN_FILTER registered and active");
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
22
script/mainnet-checkpoint/SimulateSubmitFromCalldata.s.sol
Normal file
22
script/mainnet-checkpoint/SimulateSubmitFromCalldata.s.sol
Normal file
@@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {Chain138MainnetCheckpoint} from "../../contracts/mainnet-checkpoint/Chain138MainnetCheckpoint.sol";
|
||||
|
||||
/// @notice Replay aggregator calldata on a mainnet fork to surface revert reason.
|
||||
contract SimulateSubmitFromCalldata is Script {
|
||||
function run() external {
|
||||
address hub = vm.envAddress("CHAIN138_MAINNET_CHECKPOINT_PROXY");
|
||||
bytes memory data = vm.envBytes("CHECKPOINT_SUBMIT_CALLDATA");
|
||||
vm.prank(vm.envAddress("CHECKPOINT_SUBMIT_FROM"));
|
||||
(bool ok, bytes memory ret) = hub.call(data);
|
||||
if (!ok) {
|
||||
if (ret.length > 0) {
|
||||
console.logBytes(ret);
|
||||
}
|
||||
revert("submit simulation failed");
|
||||
}
|
||||
console.log("ok, latest", Chain138MainnetCheckpoint(hub).getLatestBatchId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {Chain138MainnetCheckpoint} from "../../contracts/mainnet-checkpoint/Chain138MainnetCheckpoint.sol";
|
||||
|
||||
/// @notice UUPS upgrade: extension hook wiring (validator sigs vs leaf payload). IMPLEMENTATION_VERSION 3.
|
||||
contract UpgradeChain138MainnetCheckpointV3 is Script {
|
||||
function run() external {
|
||||
address proxy = vm.envAddress("CHAIN138_MAINNET_CHECKPOINT_PROXY");
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
Chain138MainnetCheckpoint newImpl = new Chain138MainnetCheckpoint();
|
||||
console.log("New impl:", address(newImpl));
|
||||
Chain138MainnetCheckpoint(proxy).upgradeToAndCall(address(newImpl), "");
|
||||
console.log("Upgraded proxy:", proxy);
|
||||
require(Chain138MainnetCheckpoint(proxy).IMPLEMENTATION_VERSION() == 3, "version");
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {Chain138MainnetCheckpoint} from "../../contracts/mainnet-checkpoint/Chain138MainnetCheckpoint.sol";
|
||||
|
||||
/// @notice UUPS upgrade: PaymentLeafV2 submit + V2 extension payloads. IMPLEMENTATION_VERSION 4.
|
||||
contract UpgradeChain138MainnetCheckpointV4 is Script {
|
||||
function run() external {
|
||||
address proxy = vm.envAddress("CHAIN138_MAINNET_CHECKPOINT_PROXY");
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
Chain138MainnetCheckpoint newImpl = new Chain138MainnetCheckpoint();
|
||||
console.log("New impl v4:", address(newImpl));
|
||||
Chain138MainnetCheckpoint(proxy).upgradeToAndCall(address(newImpl), "");
|
||||
require(Chain138MainnetCheckpoint(proxy).IMPLEMENTATION_VERSION() == 4, "version");
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
15
script/ops/DeployCWMirrorMeshBatch.s.sol
Normal file
15
script/ops/DeployCWMirrorMeshBatch.s.sol
Normal file
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import {CWMirrorMeshBatch} from "../../contracts/ops/CWMirrorMeshBatch.sol";
|
||||
|
||||
contract DeployCWMirrorMeshBatch is Script {
|
||||
function run() external returns (CWMirrorMeshBatch batch) {
|
||||
address bridge = vm.envAddress("CW_L1_BRIDGE_CHAIN138");
|
||||
address link = vm.envAddress("LINK_TOKEN_CHAIN138");
|
||||
vm.startBroadcast();
|
||||
batch = new CWMirrorMeshBatch(bridge, link);
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console2} from "forge-std/Script.sol";
|
||||
import {PolicyProfileRegistry} from "../../../contracts/universal-resource/PolicyProfileRegistry.sol";
|
||||
|
||||
/// @notice Publish commercial_emoney_m1_v1 profile anchor on live PolicyProfileRegistry.
|
||||
contract PublishCommercialEmoneyM1Profile is Script {
|
||||
function run() external {
|
||||
PolicyProfileRegistry reg = PolicyProfileRegistry(vm.envAddress("POLICY_PROFILE_REGISTRY_ADDRESS"));
|
||||
bytes32 contentHash = vm.envBytes32("COMMERCIAL_EMONEY_M1_CONTENT_HASH");
|
||||
|
||||
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
|
||||
reg.publishProfile("commercial_emoney_m1_v1", contentHash, 1, block.timestamp);
|
||||
vm.stopBroadcast();
|
||||
|
||||
bytes32 key = reg.profileKey("commercial_emoney_m1_v1");
|
||||
console2.log("Published commercial_emoney_m1_v1");
|
||||
console2.logBytes32(key);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user