WIP: Chain138 deployment scripts, flash receivers, HYBX OMNL recovery
This commit is contained in:
74
script/DeployCWReserveSettlementStack.s.sol
Normal file
74
script/DeployCWReserveSettlementStack.s.sol
Normal file
@@ -0,0 +1,74 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {CWNavOracle} from "../contracts/cw-settlement/CWNavOracle.sol";
|
||||
import {CWRedemptionQueue} from "../contracts/cw-settlement/CWRedemptionQueue.sol";
|
||||
import {CWStabilityFund} from "../contracts/cw-settlement/CWStabilityFund.sol";
|
||||
import {CWBuybackExecutor} from "../contracts/cw-settlement/CWBuybackExecutor.sol";
|
||||
import {CWProtocolTreasury} from "../contracts/cw-settlement/CWProtocolTreasury.sol";
|
||||
import {CWReserveVerifier} from "../contracts/bridge/integration/CWReserveVerifier.sol";
|
||||
|
||||
interface ICWMultiTokenBridgeL1Admin {
|
||||
function setReserveVerifier(address newVerifier) external;
|
||||
}
|
||||
|
||||
/**
|
||||
* @title DeployCWReserveSettlementStack
|
||||
* @notice Deploy NAV oracle, redemption queue, stability fund, buyback, treasury, and reserve verifier on Chain 138.
|
||||
*
|
||||
* Env:
|
||||
* PRIVATE_KEY, RPC_URL_138
|
||||
* CW_L1_BRIDGE (default 0x152ed3e9912161b76bdfd368d0c84b7c31c10de7)
|
||||
* CW_RESERVE_SYSTEM (default 0x607e97cD626f209facfE48c1464815DDE15B5093)
|
||||
* CW_CANONICAL_USDT / CW_CANONICAL_USDC
|
||||
* CW_ATTACH_VERIFIER_TO_L1=1
|
||||
*/
|
||||
contract DeployCWReserveSettlementStack is Script {
|
||||
function run() external {
|
||||
uint256 privateKey = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.addr(privateKey);
|
||||
|
||||
address l1Bridge = vm.envOr("CW_L1_BRIDGE", address(0x152eD3e9912161b76BDFd368D0C84B7C31C10dE7));
|
||||
address reserveSystem = vm.envOr("CW_RESERVE_SYSTEM", address(0x607e97cD626f209facfE48c1464815DDE15B5093));
|
||||
address canonicalUSDT = vm.envOr("CW_CANONICAL_USDT", address(0x93E66202A11B1772E55407B32B44e5Cd8eda7f22));
|
||||
address canonicalUSDC = vm.envOr("CW_CANONICAL_USDC", address(0xf22258f57794CC8E06237084b353Ab30fFfa640b));
|
||||
bool attachVerifier = vm.envOr("CW_ATTACH_VERIFIER_TO_L1", uint256(0)) == 1;
|
||||
bool skipVerifierDeploy = vm.envOr("CW_SKIP_RESERVE_VERIFIER", uint256(1)) == 1;
|
||||
|
||||
vm.startBroadcast(privateKey);
|
||||
|
||||
address verifierAddr;
|
||||
if (skipVerifierDeploy) {
|
||||
verifierAddr = address(0);
|
||||
} else {
|
||||
CWReserveVerifier verifier = new CWReserveVerifier(admin, l1Bridge, address(0), reserveSystem);
|
||||
verifierAddr = address(verifier);
|
||||
if (attachVerifier) {
|
||||
ICWMultiTokenBridgeL1Admin(l1Bridge).setReserveVerifier(verifierAddr);
|
||||
}
|
||||
verifier.configureToken(canonicalUSDT, address(0), false, false, false);
|
||||
verifier.configureToken(canonicalUSDC, address(0), false, false, false);
|
||||
}
|
||||
|
||||
CWNavOracle navOracle = new CWNavOracle(admin, l1Bridge, reserveSystem);
|
||||
CWRedemptionQueue redemptionQueue = new CWRedemptionQueue(admin);
|
||||
CWStabilityFund stabilityFund = new CWStabilityFund(admin);
|
||||
CWProtocolTreasury treasury = new CWProtocolTreasury(admin, address(0));
|
||||
CWBuybackExecutor buyback = new CWBuybackExecutor(admin, verifierAddr, address(treasury));
|
||||
|
||||
treasury.setBuybackExecutor(address(buyback));
|
||||
|
||||
navOracle.configureToken(canonicalUSDT, address(0));
|
||||
navOracle.configureToken(canonicalUSDC, address(0));
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("CWReserveVerifier:", verifierAddr);
|
||||
console.log("CWNavOracle:", address(navOracle));
|
||||
console.log("CWRedemptionQueue:", address(redemptionQueue));
|
||||
console.log("CWStabilityFund:", address(stabilityFund));
|
||||
console.log("CWProtocolTreasury:", address(treasury));
|
||||
console.log("CWBuybackExecutor:", address(buyback));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import "../../../contracts/bridge/trustless/EnhancedSwapRouterV2.sol";
|
||||
import "../../../contracts/bridge/trustless/RouteTypesV2.sol";
|
||||
|
||||
/// @notice Enable UniV3, Balancer, and Curve routes on live EnhancedSwapRouterV2 (Chain 138).
|
||||
/// Adapters must already be set via initial deploy; this script only enables providers + routes.
|
||||
contract ConfigureEnhancedSwapRouterV2MultiVenue is Script {
|
||||
address constant DEFAULT_ROUTER_V2 = 0xa421706768aEB7fafA2D912C5E10824eF3437ad4;
|
||||
|
||||
address constant CHAIN138_WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
|
||||
address constant CHAIN138_USDT = 0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1;
|
||||
address constant CHAIN138_USDC = 0x71D6687F38b93CCad569Fa6352c876eea967201b;
|
||||
address constant CHAIN138_cUSDT = 0x93E66202A11B1772E55407B32B44e5Cd8eda7f22;
|
||||
address constant CHAIN138_cUSDC = 0xf22258f57794CC8E06237084b353Ab30fFfa640b;
|
||||
|
||||
address constant CHAIN138_DODO_PROVIDER = 0x3f729632E9553EBacCdE2e9b4c8F2B285b014F2e;
|
||||
address constant CHAIN138_POOL_CUSDTCUSDC = 0x9e89bAe009adf128782E19e8341996c596ac40dC;
|
||||
address constant CHAIN138_POOL_CUSDTUSDT = 0x866Cb44b59303d8dc5f4F9E3E7A8e8b0bf238d66;
|
||||
address constant CHAIN138_POOL_CUSDCUSDC = 0xc39B7D0F40838cbFb54649d327f49a6DAC964062;
|
||||
address constant CHAIN138_POOL_WETH_USDT = 0xe227F6C0520c0c6E8786fE56Fa76c4914F861533;
|
||||
address constant CHAIN138_POOL_WETH_USDC = 0xb53A0508940b1Ff90F1AAD4f6cb50a7012Fe5593;
|
||||
|
||||
address constant UNISWAP_V3_ROUTER = 0xde9cD8ee2811E6E64a41D5F68Be315d33995975E;
|
||||
address constant UNISWAP_QUOTER = 0x6abbB1CEb2468e748a03A00CD6aA9BFE893AFa1f;
|
||||
address constant BALANCER_VAULT = 0x96423d7C1727698D8a25EbFB88131e9422d1a3C3;
|
||||
bytes32 constant BALANCER_WETH_USDT_POOL_ID =
|
||||
0x877cd220759e8c94b82f55450c85d382ae06856c426b56d93092a420facbc324;
|
||||
bytes32 constant BALANCER_WETH_USDC_POOL_ID =
|
||||
0xd8dfb18a6baf9b29d8c2dbd74639db87ac558af120df5261dab8e2a5de69013b;
|
||||
address constant CURVE_3POOL = 0xE440Ec15805BE4C7BabCD17A63B8C8A08a492e0f;
|
||||
|
||||
function run() external {
|
||||
require(block.chainid == 138, "ConfigureEnhancedSwapRouterV2MultiVenue: Chain 138 only");
|
||||
|
||||
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
|
||||
address routerAddress = vm.envOr("ENHANCED_SWAP_ROUTER_V2_ADDRESS", DEFAULT_ROUTER_V2);
|
||||
EnhancedSwapRouterV2 router = EnhancedSwapRouterV2(payable(routerAddress));
|
||||
|
||||
uint24 wethUsdtFee = uint24(vm.envOr("UNISWAP_V3_WETH_USDT_FEE", uint256(3000)));
|
||||
uint24 wethUsdcFee = uint24(vm.envOr("UNISWAP_V3_WETH_USDC_FEE", uint256(500)));
|
||||
|
||||
vm.startBroadcast(deployerPrivateKey);
|
||||
|
||||
_setDodoPair(router, CHAIN138_cUSDT, CHAIN138_cUSDC, CHAIN138_DODO_PROVIDER, CHAIN138_POOL_CUSDTCUSDC);
|
||||
_setDodoPair(router, CHAIN138_cUSDT, CHAIN138_USDT, CHAIN138_DODO_PROVIDER, CHAIN138_POOL_CUSDTUSDT);
|
||||
_setDodoPair(router, CHAIN138_cUSDC, CHAIN138_USDC, CHAIN138_DODO_PROVIDER, CHAIN138_POOL_CUSDCUSDC);
|
||||
_setDodoPair(router, CHAIN138_WETH, CHAIN138_USDT, CHAIN138_DODO_PROVIDER, CHAIN138_POOL_WETH_USDT);
|
||||
_setDodoPair(router, CHAIN138_WETH, CHAIN138_USDC, CHAIN138_DODO_PROVIDER, CHAIN138_POOL_WETH_USDC);
|
||||
|
||||
_setUniswapPair(router, CHAIN138_WETH, CHAIN138_USDT, UNISWAP_V3_ROUTER, UNISWAP_QUOTER, wethUsdtFee);
|
||||
_setUniswapPair(router, CHAIN138_WETH, CHAIN138_USDC, UNISWAP_V3_ROUTER, UNISWAP_QUOTER, wethUsdcFee);
|
||||
|
||||
_setBalancerPair(router, CHAIN138_WETH, CHAIN138_USDT, BALANCER_VAULT, BALANCER_WETH_USDT_POOL_ID);
|
||||
_setBalancerPair(router, CHAIN138_WETH, CHAIN138_USDC, BALANCER_VAULT, BALANCER_WETH_USDC_POOL_ID);
|
||||
|
||||
_setCurvePair(router, CHAIN138_USDT, CHAIN138_USDC, CURVE_3POOL, 0, 1, false);
|
||||
|
||||
router.setProviderEnabled(RouteTypesV2.Provider.Dodo, true);
|
||||
router.setProviderEnabled(RouteTypesV2.Provider.UniswapV3, true);
|
||||
router.setProviderEnabled(RouteTypesV2.Provider.Balancer, true);
|
||||
router.setProviderEnabled(RouteTypesV2.Provider.Curve, true);
|
||||
router.setProviderEnabled(RouteTypesV2.Provider.OneInch, false);
|
||||
router.setProviderEnabled(RouteTypesV2.Provider.Partner, false);
|
||||
router.setProviderEnabled(RouteTypesV2.Provider.DodoV3, false);
|
||||
|
||||
RouteTypesV2.Provider[] memory providers = new RouteTypesV2.Provider[](4);
|
||||
providers[0] = RouteTypesV2.Provider.Dodo;
|
||||
providers[1] = RouteTypesV2.Provider.UniswapV3;
|
||||
providers[2] = RouteTypesV2.Provider.Balancer;
|
||||
providers[3] = RouteTypesV2.Provider.Curve;
|
||||
router.setRoutingConfig(0, providers);
|
||||
router.setRoutingConfig(1, providers);
|
||||
router.setRoutingConfig(2, providers);
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("EnhancedSwapRouterV2 multi-venue configured:", routerAddress);
|
||||
}
|
||||
|
||||
function _setDodoPair(EnhancedSwapRouterV2 router, address tokenA, address tokenB, address target, address pool)
|
||||
internal
|
||||
{
|
||||
bytes memory providerData = abi.encode(pool);
|
||||
router.setProviderRoute(tokenA, tokenB, RouteTypesV2.Provider.Dodo, target, providerData, true);
|
||||
router.setProviderRoute(tokenB, tokenA, RouteTypesV2.Provider.Dodo, target, providerData, true);
|
||||
}
|
||||
|
||||
function _setUniswapPair(
|
||||
EnhancedSwapRouterV2 router,
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
address target,
|
||||
address quoter,
|
||||
uint24 fee
|
||||
) internal {
|
||||
bytes memory providerData = abi.encode(bytes(""), fee, quoter, false);
|
||||
router.setProviderRoute(tokenA, tokenB, RouteTypesV2.Provider.UniswapV3, target, providerData, true);
|
||||
router.setProviderRoute(tokenB, tokenA, RouteTypesV2.Provider.UniswapV3, target, providerData, true);
|
||||
}
|
||||
|
||||
function _setBalancerPair(
|
||||
EnhancedSwapRouterV2 router,
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
address target,
|
||||
bytes32 poolId
|
||||
) internal {
|
||||
bytes memory providerData = abi.encode(poolId);
|
||||
router.setProviderRoute(tokenA, tokenB, RouteTypesV2.Provider.Balancer, target, providerData, true);
|
||||
router.setProviderRoute(tokenB, tokenA, RouteTypesV2.Provider.Balancer, target, providerData, true);
|
||||
}
|
||||
|
||||
function _setCurvePair(
|
||||
EnhancedSwapRouterV2 router,
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
address target,
|
||||
int128 i,
|
||||
int128 j,
|
||||
bool useUnderlying
|
||||
) internal {
|
||||
bytes memory providerData = abi.encode(i, j, useUnderlying);
|
||||
router.setProviderRoute(tokenA, tokenB, RouteTypesV2.Provider.Curve, target, providerData, true);
|
||||
router.setProviderRoute(tokenB, tokenA, RouteTypesV2.Provider.Curve, target, providerData, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {AaveUniV2CwStableRebalanceFlashReceiver} from "../../contracts/flash/AaveUniV2CwStableRebalanceFlashReceiver.sol";
|
||||
|
||||
/**
|
||||
* @title DeployAaveUniV2CwStableRebalanceFlashReceiver
|
||||
* @notice Deploy the UniV2 rebalance + remove Aave flash receiver.
|
||||
*
|
||||
* Env:
|
||||
* PRIVATE_KEY
|
||||
* AAVE_POOL_ADDRESS optional; default Aave V3 mainnet Pool
|
||||
* UNIV2_FLASH_REBALANCE_OWNER optional; default deployer
|
||||
*/
|
||||
contract DeployAaveUniV2CwStableRebalanceFlashReceiver is Script {
|
||||
address internal constant DEFAULT_AAVE_POOL_MAINNET = 0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2;
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address pool = vm.envOr("AAVE_POOL_ADDRESS", DEFAULT_AAVE_POOL_MAINNET);
|
||||
address deployer = vm.addr(pk);
|
||||
address owner = vm.envOr("UNIV2_FLASH_REBALANCE_OWNER", deployer);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
AaveUniV2CwStableRebalanceFlashReceiver receiver =
|
||||
new AaveUniV2CwStableRebalanceFlashReceiver(pool, owner);
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("AaveUniV2CwStableRebalanceFlashReceiver", address(receiver));
|
||||
console.log("owner", owner);
|
||||
console.log("aavePool", pool);
|
||||
}
|
||||
}
|
||||
27
script/deploy/bridge/DeployZedxionAdapter.s.sol
Normal file
27
script/deploy/bridge/DeployZedxionAdapter.s.sol
Normal file
@@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import "../../../contracts/bridge/adapters/evm/ZedxionAdapter.sol";
|
||||
|
||||
/**
|
||||
* @notice Deploy ZedxionAdapter on Chain 138.
|
||||
* Env: PRIVATE_KEY, ADMIN (optional), ZEDXION_TRANSPORT (optional — call setZedxionTransport after)
|
||||
*/
|
||||
contract DeployZedxionAdapter is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.envOr("ADMIN", vm.addr(pk));
|
||||
vm.startBroadcast(pk);
|
||||
ZedxionAdapter adapter = new ZedxionAdapter(admin);
|
||||
vm.stopBroadcast();
|
||||
console2.log("ZedxionAdapter", address(adapter));
|
||||
address transport = vm.envOr("ZEDXION_TRANSPORT", address(0));
|
||||
if (transport != address(0)) {
|
||||
vm.startBroadcast(pk);
|
||||
adapter.setZedxionTransport(transport);
|
||||
vm.stopBroadcast();
|
||||
console2.log("ZedxionTransport wired", transport);
|
||||
}
|
||||
}
|
||||
}
|
||||
22
script/deploy/bridge/DeployZedxionCustomBridge.s.sol
Normal file
22
script/deploy/bridge/DeployZedxionCustomBridge.s.sol
Normal file
@@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import "../../../contracts/bridge/ZedxionCustomBridge.sol";
|
||||
|
||||
/**
|
||||
* @notice Deploy ZedxionCustomBridge on Chain 138 and/or ZEDXION (83872).
|
||||
* @dev For CREATE2 same-address deploy, use DeployDeterministicCore pattern with salt keccak256("ZedxionCustomBridge").
|
||||
* Env: PRIVATE_KEY, ADMIN (defaults msg.sender)
|
||||
*/
|
||||
contract DeployZedxionCustomBridge is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.envOr("ADMIN", vm.addr(pk));
|
||||
vm.startBroadcast(pk);
|
||||
ZedxionCustomBridge bridge = new ZedxionCustomBridge(admin);
|
||||
vm.stopBroadcast();
|
||||
console2.log("ZedxionCustomBridge", address(bridge));
|
||||
console2.log("Admin", admin);
|
||||
}
|
||||
}
|
||||
27
script/deploy/rwa/GrantUarRegistrarRWA138.s.sol
Normal file
27
script/deploy/rwa/GrantUarRegistrarRWA138.s.sol
Normal file
@@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import {UniversalAssetRegistry} from "../../../contracts/registry/UniversalAssetRegistry.sol";
|
||||
|
||||
/**
|
||||
* @title GrantUarRegistrarRWA138
|
||||
* @notice Grant REGISTRAR_ROLE on UAR to broadcaster (for RegisterRWAIndicesInUAR138).
|
||||
* @dev Broadcaster must hold DEFAULT_ADMIN_ROLE on UAR.
|
||||
*/
|
||||
contract GrantUarRegistrarRWA138 is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address grantee = vm.envOr("UAR_REGISTRAR_GRANTEE", vm.addr(pk));
|
||||
address uarAddr = vm.envAddress("UNIVERSAL_ASSET_REGISTRY");
|
||||
|
||||
UniversalAssetRegistry uar = UniversalAssetRegistry(uarAddr);
|
||||
bytes32 role = uar.REGISTRAR_ROLE();
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
uar.grantRole(role, grantee);
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("REGISTRAR_ROLE granted to", grantee, "on UAR", uarAddr);
|
||||
}
|
||||
}
|
||||
147
script/deploy/rwa/RedeployLiIndexPublisher138.s.sol
Normal file
147
script/deploy/rwa/RedeployLiIndexPublisher138.s.sol
Normal file
@@ -0,0 +1,147 @@
|
||||
// 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";
|
||||
|
||||
/**
|
||||
* @title RedeployLiIndexPublisher138
|
||||
* @notice Operator recovery when Gnosis Safe co-signer keys are unavailable:
|
||||
* deactivate Li* in registry, redeploy with deployer as INDEX_PUBLISHER, publish index level.
|
||||
*
|
||||
* Env: LI_TICKER (LiXAU|LiPMG|LiBMG1|LiBMG2|LiBMG3), PRIVATE_KEY, RWA_TOKEN_REGISTRY, RWA_TOKEN_FACTORY
|
||||
* REBASE_INDEX_VALUE (optional), OWNER, COMPLIANCE_ADMIN, INDEX_PUBLISHER, RWA_METHODOLOGY_HASH
|
||||
*/
|
||||
contract RedeployLiIndexPublisher138 is Script {
|
||||
struct LiProduct {
|
||||
string indexTicker;
|
||||
string name;
|
||||
string symbol;
|
||||
string assetGroup;
|
||||
string instrumentType;
|
||||
string underlyingAsset;
|
||||
uint256 defaultIndexValue;
|
||||
}
|
||||
|
||||
function run() external {
|
||||
string memory ticker = vm.envString("LI_TICKER");
|
||||
LiProduct memory p = _product(ticker);
|
||||
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address registryAddr = vm.envAddress("RWA_TOKEN_REGISTRY");
|
||||
address factoryAddr = vm.envAddress("RWA_TOKEN_FACTORY");
|
||||
address owner = vm.envOr("OWNER", vm.envOr("OMNL_COMPLIANCE_MULTISIG", deployer));
|
||||
address compliance = vm.envOr("COMPLIANCE_ADMIN", vm.envOr("OMNL_GNOSIS_SAFE_ADMIN", deployer));
|
||||
address publisher = vm.envOr("INDEX_PUBLISHER", deployer);
|
||||
uint256 rebaseValue = vm.envOr("REBASE_INDEX_VALUE", p.defaultIndexValue);
|
||||
bytes32 methodologyHash = vm.parseBytes32(
|
||||
vm.envOr("RWA_METHODOLOGY_HASH", string("0x6b6e599d0ba31d048b49302e263a12f0c59502f67a35100ad5c65b503b1d4b82"))
|
||||
);
|
||||
|
||||
RWATokenRegistry registry = RWATokenRegistry(registryAddr);
|
||||
RWATokenFactory factory = RWATokenFactory(factoryAddr);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
if (registry.isRegistered(p.indexTicker)) {
|
||||
registry.deactivateIndex(p.indexTicker);
|
||||
console.log("Deactivated", p.indexTicker, "in registry");
|
||||
}
|
||||
|
||||
address token = factory.deployRWAIndex(
|
||||
IRWATokenFactory.RWAProductConfig({
|
||||
indexTicker: p.indexTicker,
|
||||
name: p.name,
|
||||
symbol: p.symbol,
|
||||
decimals: 6,
|
||||
assetClass: "Commodities",
|
||||
assetGroup: p.assetGroup,
|
||||
instrumentType: p.instrumentType,
|
||||
underlyingAsset: p.underlyingAsset,
|
||||
gruLayer: "M00",
|
||||
jurisdiction: "International",
|
||||
initialOwner: owner,
|
||||
complianceAdmin: compliance,
|
||||
indexPublisher: publisher,
|
||||
initialIndexValue: p.defaultIndexValue,
|
||||
initialSupply: 0,
|
||||
methodologyDocumentHash: methodologyHash,
|
||||
registerInUniversalAssetRegistry: false
|
||||
})
|
||||
);
|
||||
|
||||
if (rebaseValue != p.defaultIndexValue) {
|
||||
RWAToken(token).updateIndexValue(rebaseValue);
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("Li* redeployed", p.indexTicker, token);
|
||||
console.log("indexValue", RWAToken(token).indexValue());
|
||||
console.log("indexPublisher", publisher);
|
||||
}
|
||||
|
||||
function _product(string memory ticker) internal pure returns (LiProduct memory p) {
|
||||
bytes32 h = keccak256(bytes(ticker));
|
||||
if (h == keccak256("LiXAU")) {
|
||||
return LiProduct({
|
||||
indexTicker: "LiXAU",
|
||||
name: "XAU Liquidity Index (M00)",
|
||||
symbol: "LiXAU",
|
||||
assetGroup: "Precious Metals",
|
||||
instrumentType: "Commodity Index",
|
||||
underlyingAsset: "Gold",
|
||||
defaultIndexValue: 1_000_000
|
||||
});
|
||||
}
|
||||
if (h == keccak256("LiPMG")) {
|
||||
return LiProduct({
|
||||
indexTicker: "LiPMG",
|
||||
name: "Precious Metals Group Index (M00)",
|
||||
symbol: "LiPMG",
|
||||
assetGroup: "Precious Metals",
|
||||
instrumentType: "Basket Index",
|
||||
underlyingAsset: "Precious Metals",
|
||||
defaultIndexValue: 1_000_000
|
||||
});
|
||||
}
|
||||
if (h == keccak256("LiBMG1")) {
|
||||
return LiProduct({
|
||||
indexTicker: "LiBMG1",
|
||||
name: "Base Metals Group Index 1 (M00)",
|
||||
symbol: "LiBMG1",
|
||||
assetGroup: "Industrial Metals",
|
||||
instrumentType: "Basket Index",
|
||||
underlyingAsset: "Base Metals",
|
||||
defaultIndexValue: 1_000_000
|
||||
});
|
||||
}
|
||||
if (h == keccak256("LiBMG2")) {
|
||||
return LiProduct({
|
||||
indexTicker: "LiBMG2",
|
||||
name: "Base Metals Group Index 2 (M00)",
|
||||
symbol: "LiBMG2",
|
||||
assetGroup: "Industrial Metals",
|
||||
instrumentType: "Basket Index",
|
||||
underlyingAsset: "Battery Metals",
|
||||
defaultIndexValue: 1_000_000
|
||||
});
|
||||
}
|
||||
if (h == keccak256("LiBMG3")) {
|
||||
return LiProduct({
|
||||
indexTicker: "LiBMG3",
|
||||
name: "Base Metals Group Index 3 (M00)",
|
||||
symbol: "LiBMG3",
|
||||
assetGroup: "Industrial Metals",
|
||||
instrumentType: "Basket Index",
|
||||
underlyingAsset: "Building Metals",
|
||||
defaultIndexValue: 1_000_000
|
||||
});
|
||||
}
|
||||
revert("RedeployLiIndexPublisher138: unsupported LI_TICKER");
|
||||
}
|
||||
}
|
||||
71
script/deploy/rwa/RedeployLiXauPublisher138.s.sol
Normal file
71
script/deploy/rwa/RedeployLiXauPublisher138.s.sol
Normal file
@@ -0,0 +1,71 @@
|
||||
// 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";
|
||||
|
||||
/**
|
||||
* @title RedeployLiXauPublisher138
|
||||
* @notice Operator recovery when Gnosis Safe co-signer keys are unavailable:
|
||||
* deactivate LiXAU in registry, redeploy with deployer as INDEX_PUBLISHER, publish rebase level.
|
||||
*
|
||||
* Env: PRIVATE_KEY, RWA_TOKEN_REGISTRY, RWA_TOKEN_FACTORY, REBASE_INDEX_VALUE (default 1885856)
|
||||
* OWNER (default OMNL multisig), COMPLIANCE_ADMIN (default Gnosis Safe admin)
|
||||
* INDEX_PUBLISHER (default deployer), RWA_METHODOLOGY_HASH
|
||||
*/
|
||||
contract RedeployLiXauPublisher138 is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address registryAddr = vm.envAddress("RWA_TOKEN_REGISTRY");
|
||||
address factoryAddr = vm.envAddress("RWA_TOKEN_FACTORY");
|
||||
address owner = vm.envOr("OWNER", vm.envOr("OMNL_COMPLIANCE_MULTISIG", deployer));
|
||||
address compliance = vm.envOr("COMPLIANCE_ADMIN", vm.envOr("OMNL_GNOSIS_SAFE_ADMIN", deployer));
|
||||
address publisher = vm.envOr("INDEX_PUBLISHER", deployer);
|
||||
uint256 rebaseValue = vm.envOr("REBASE_INDEX_VALUE", uint256(1_885_856));
|
||||
bytes32 methodologyHash = vm.parseBytes32(vm.envOr("RWA_METHODOLOGY_HASH", string("0x6b6e599d0ba31d048b49302e263a12f0c59502f67a35100ad5c65b503b1d4b82")));
|
||||
|
||||
RWATokenRegistry registry = RWATokenRegistry(registryAddr);
|
||||
RWATokenFactory factory = RWATokenFactory(factoryAddr);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
if (registry.isRegistered("LiXAU")) {
|
||||
registry.deactivateIndex("LiXAU");
|
||||
console.log("Deactivated LiXAU in registry");
|
||||
}
|
||||
|
||||
address token = factory.deployRWAIndex(
|
||||
IRWATokenFactory.RWAProductConfig({
|
||||
indexTicker: "LiXAU",
|
||||
name: "XAU Liquidity Index (M00)",
|
||||
symbol: "LiXAU",
|
||||
decimals: 6,
|
||||
assetClass: "Commodities",
|
||||
assetGroup: "Precious Metals",
|
||||
instrumentType: "Commodity Index",
|
||||
underlyingAsset: "Gold",
|
||||
gruLayer: "M00",
|
||||
jurisdiction: "International",
|
||||
initialOwner: owner,
|
||||
complianceAdmin: compliance,
|
||||
indexPublisher: publisher,
|
||||
initialIndexValue: 1_000_000,
|
||||
initialSupply: 0,
|
||||
methodologyDocumentHash: methodologyHash,
|
||||
registerInUniversalAssetRegistry: false
|
||||
})
|
||||
);
|
||||
|
||||
RWAToken(token).updateIndexValue(rebaseValue);
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("LiXAU redeployed", token);
|
||||
console.log("indexValue", RWAToken(token).indexValue());
|
||||
console.log("indexPublisher", publisher);
|
||||
}
|
||||
}
|
||||
125
script/flash/RunMainnetUniV2CwusdcUsdcFlashRebalanceRemove.s.sol
Normal file
125
script/flash/RunMainnetUniV2CwusdcUsdcFlashRebalanceRemove.s.sol
Normal file
@@ -0,0 +1,125 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import {
|
||||
AaveUniV2CwStableRebalanceFlashReceiver
|
||||
} from "../../contracts/flash/AaveUniV2CwStableRebalanceFlashReceiver.sol";
|
||||
|
||||
/**
|
||||
* @title RunMainnetUniV2CwusdcUsdcFlashRebalanceRemove
|
||||
* @notice Simulate or broadcast flash rebalance + LP remove on mainnet cWUSDC/USDC UniV2.
|
||||
*
|
||||
* Prerequisite: run plan-mainnet-cwusdc-usdc-univ2-flash-rebalance-remove.py and transfer LP
|
||||
* to the receiver (or set UNIV2_FLASH_PULL_LP=1 with prior LP approval to receiver).
|
||||
*
|
||||
* Env:
|
||||
* PRIVATE_KEY
|
||||
* ETHEREUM_MAINNET_RPC
|
||||
* UNIV2_FLASH_REBALANCE_RECEIVER_MAINNET
|
||||
* UNIV2_FLASH_REBALANCE_PLAN_JSON optional path to planner JSON
|
||||
*/
|
||||
contract RunMainnetUniV2CwusdcUsdcFlashRebalanceRemove is Script {
|
||||
address internal constant DEFAULT_PAIR = 0xC28706F899266b36BC43cc072b3a921BDf2C48D9;
|
||||
address internal constant DEFAULT_ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
|
||||
address internal constant DEFAULT_CW = 0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a;
|
||||
address internal constant DEFAULT_USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address receiver = vm.envAddress("UNIV2_FLASH_REBALANCE_RECEIVER_MAINNET");
|
||||
string memory planPath = vm.envOr(
|
||||
"UNIV2_FLASH_REBALANCE_PLAN_JSON",
|
||||
string("reports/status/mainnet-cwusdc-usdc-univ2-flash-rebalance-plan-latest.json")
|
||||
);
|
||||
|
||||
(
|
||||
address pair,
|
||||
address router,
|
||||
address cw,
|
||||
address usdc,
|
||||
address lpHolder,
|
||||
address recipient,
|
||||
uint256 lpAmount,
|
||||
uint256 flashStableIn,
|
||||
uint256 minCwRebalance,
|
||||
uint256 minCwRemove,
|
||||
uint256 minStableRemove,
|
||||
uint256 cwToSell,
|
||||
uint256 minStableRepay
|
||||
) = _loadPlan(planPath);
|
||||
|
||||
pair = pair == address(0) ? DEFAULT_PAIR : pair;
|
||||
router = router == address(0) ? DEFAULT_ROUTER : router;
|
||||
cw = cw == address(0) ? DEFAULT_CW : cw;
|
||||
usdc = usdc == address(0) ? DEFAULT_USDC : usdc;
|
||||
|
||||
console.log("receiver", receiver);
|
||||
console.log("pair", pair);
|
||||
console.log("lpHolder", lpHolder);
|
||||
console.log("lpAmount", lpAmount);
|
||||
console.log("flashStableIn", flashStableIn);
|
||||
console.log("receiverLpBefore", IERC20(pair).balanceOf(receiver));
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
if (vm.envOr("UNIV2_FLASH_PULL_LP", uint256(0)) == 1) {
|
||||
AaveUniV2CwStableRebalanceFlashReceiver(receiver).pullLpFrom(pair, lpHolder, lpAmount);
|
||||
}
|
||||
AaveUniV2CwStableRebalanceFlashReceiver.RebalanceRemoveParams memory p =
|
||||
AaveUniV2CwStableRebalanceFlashReceiver.RebalanceRemoveParams({
|
||||
router: router,
|
||||
pair: pair,
|
||||
cwToken: cw,
|
||||
stableToken: usdc,
|
||||
lpAmount: lpAmount,
|
||||
rebalanceStableIn: flashStableIn,
|
||||
minCwFromRebalance: minCwRebalance,
|
||||
minStableFromRemove: minStableRemove,
|
||||
minCwFromRemove: minCwRemove,
|
||||
cwToSellForRepay: cwToSell,
|
||||
minStableFromRepaySwap: minStableRepay,
|
||||
recipient: recipient
|
||||
});
|
||||
AaveUniV2CwStableRebalanceFlashReceiver(receiver).runRebalanceRemove(usdc, flashStableIn, p);
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("recipientStableAfter", IERC20(usdc).balanceOf(recipient));
|
||||
console.log("recipientCwAfter", IERC20(cw).balanceOf(recipient));
|
||||
}
|
||||
|
||||
function _loadPlan(string memory path)
|
||||
internal
|
||||
view
|
||||
returns (
|
||||
address pair,
|
||||
address router,
|
||||
address cw,
|
||||
address usdc,
|
||||
address lpHolder,
|
||||
address recipient,
|
||||
uint256 lpAmount,
|
||||
uint256 flashStableIn,
|
||||
uint256 minCwRebalance,
|
||||
uint256 minCwRemove,
|
||||
uint256 minStableRemove,
|
||||
uint256 cwToSell,
|
||||
uint256 minStableRepay
|
||||
)
|
||||
{
|
||||
string memory json = vm.readFile(path);
|
||||
pair = vm.parseJsonAddress(json, ".pair");
|
||||
router = vm.parseJsonAddress(json, ".router");
|
||||
cw = vm.parseJsonAddress(json, ".cwToken");
|
||||
usdc = vm.parseJsonAddress(json, ".stableToken");
|
||||
lpHolder = vm.parseJsonAddress(json, ".lpHolder");
|
||||
recipient = vm.parseJsonAddress(json, ".recipient");
|
||||
lpAmount = vm.parseJsonUint(json, ".lpAmountRaw");
|
||||
flashStableIn = vm.parseJsonUint(json, ".flashLoan.stableBorrowRaw");
|
||||
minCwRebalance = vm.parseJsonUint(json, ".rebalanceSwap.minCwOutRaw");
|
||||
minCwRemove = vm.parseJsonUint(json, ".removeLiquidity.minCwOutRaw");
|
||||
minStableRemove = vm.parseJsonUint(json, ".removeLiquidity.minStableOutRaw");
|
||||
cwToSell = vm.parseJsonUint(json, ".repaySwap.cwToSellRaw");
|
||||
minStableRepay = vm.parseJsonUint(json, ".repaySwap.minStableOutRaw");
|
||||
}
|
||||
}
|
||||
101
script/flash/RunManagedMainnetAaveCwusdtUsdtQuotePushCycle.s.sol
Normal file
101
script/flash/RunManagedMainnetAaveCwusdtUsdtQuotePushCycle.s.sol
Normal file
@@ -0,0 +1,101 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {AaveQuotePushFlashReceiver} from "../../contracts/flash/AaveQuotePushFlashReceiver.sol";
|
||||
import {QuotePushTreasuryManager} from "../../contracts/flash/QuotePushTreasuryManager.sol";
|
||||
|
||||
interface IDODOPMMPoolQuoteManagedUsdt {
|
||||
function querySellQuote(address trader, uint256 payQuoteAmount) external view returns (uint256 receiveBaseAmount, uint256 mtFee);
|
||||
}
|
||||
|
||||
/// @notice USDT rail mirror of RunManagedMainnetAaveCwusdcUsdcQuotePushCycle.
|
||||
contract RunManagedMainnetAaveCwusdtUsdtQuotePushCycle is Script {
|
||||
address internal constant DEFAULT_POOL = 0x79156F6B7bf71a1B72D78189B540A89A6C13F6FC;
|
||||
address internal constant DEFAULT_CWUSDT = 0xaF5017d0163ecb99D9B5D94e3b4D7b09Af44D8AE;
|
||||
address internal constant DEFAULT_USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
|
||||
uint256 internal constant DEFENDED_SAFE_CAP_RAW = 2_964_298;
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address receiver = vm.envAddress("AAVE_QUOTE_PUSH_RECEIVER_MAINNET");
|
||||
address managerAddr = vm.envAddress("QUOTE_PUSH_TREASURY_MANAGER_MAINNET");
|
||||
address pool = vm.envOr("POOL_CWUSDT_USDT_MAINNET", DEFAULT_POOL);
|
||||
address integration = vm.envAddress("DODO_PMM_INTEGRATION_MAINNET");
|
||||
address baseToken = vm.envOr("CWUSDT_MAINNET", DEFAULT_CWUSDT);
|
||||
address usdt = vm.envOr("USDT_MAINNET", DEFAULT_USDT);
|
||||
address unwinder = vm.envAddress("QUOTE_PUSH_EXTERNAL_UNWINDER_MAINNET");
|
||||
uint256 amount = vm.envUint("FLASH_QUOTE_AMOUNT_RAW");
|
||||
uint256 localCap = vm.envOr("MAX_FLASH_QUOTE_AMOUNT_RAW", DEFENDED_SAFE_CAP_RAW);
|
||||
bool harvest = vm.envOr("QUOTE_PUSH_TREASURY_HARVEST", uint256(1)) == 1;
|
||||
uint256 gasHoldbackTargetRaw = vm.envOr("QUOTE_PUSH_TREASURY_GAS_HOLDBACK_TARGET_RAW", uint256(0));
|
||||
|
||||
require(pool == DEFAULT_POOL, "defended pool only");
|
||||
require(localCap <= DEFENDED_SAFE_CAP_RAW, "local cap exceeds defended safe cap");
|
||||
require(amount <= localCap, "flash amount exceeds cap");
|
||||
|
||||
QuotePushTreasuryManager manager = QuotePushTreasuryManager(managerAddr);
|
||||
AaveQuotePushFlashReceiver.QuotePushParams memory p =
|
||||
_loadQuotePushParams(receiver, pool, integration, baseToken, unwinder, amount);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
(uint256 harvested, uint256 gasAmount, uint256 recycleAmount) =
|
||||
manager.runManagedCycle(usdt, amount, p, harvest, gasHoldbackTargetRaw);
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("managedCycleHarvestedRaw", harvested);
|
||||
console.log("managedCycleGasDistributionRaw", gasAmount);
|
||||
console.log("managedCycleRecycleDistributionRaw", recycleAmount);
|
||||
}
|
||||
|
||||
function _loadQuotePushParams(
|
||||
address receiver,
|
||||
address pool,
|
||||
address integration,
|
||||
address baseToken,
|
||||
address unwinder,
|
||||
uint256 amount
|
||||
) internal view returns (AaveQuotePushFlashReceiver.QuotePushParams memory p) {
|
||||
uint256 minPmmNum = vm.envOr("MIN_OUT_PMM_NUM", uint256(985));
|
||||
uint256 minPmmDen = vm.envOr("MIN_OUT_PMM_DEN", uint256(1000));
|
||||
uint256 minOutPmm = vm.envOr("MIN_OUT_PMM", uint256(0));
|
||||
if (minOutPmm == 0) {
|
||||
(uint256 baseOut,) = IDODOPMMPoolQuoteManagedUsdt(pool).querySellQuote(receiver, amount);
|
||||
minOutPmm = (baseOut * minPmmNum) / minPmmDen;
|
||||
}
|
||||
uint256 premiumBps = vm.envOr("AAVE_FLASH_PREMIUM_BPS", uint256(5));
|
||||
uint256 buf = vm.envOr("MIN_OUT_UNWIND_BUFFER_RAW", uint256(5000));
|
||||
uint256 premium = (amount * premiumBps) / 10000;
|
||||
uint256 minOutUnwind = vm.envOr("MIN_OUT_UNWIND", amount + premium + buf);
|
||||
uint256 unwindMode = vm.envOr("UNWIND_MODE", uint256(1));
|
||||
bytes memory unwindData;
|
||||
if (unwindMode == 1) {
|
||||
address dodoPool = vm.envOr("UNWIND_DODO_POOL", pool);
|
||||
unwindData = abi.encode(dodoPool);
|
||||
} else {
|
||||
revert("USDT rail: UNWIND_MODE=1 (DODO) required for now");
|
||||
}
|
||||
p = AaveQuotePushFlashReceiver.QuotePushParams({
|
||||
integration: integration,
|
||||
pmmPool: pool,
|
||||
baseToken: baseToken,
|
||||
externalUnwinder: unwinder,
|
||||
minOutPmm: minOutPmm,
|
||||
minOutUnwind: minOutUnwind,
|
||||
unwindData: unwindData,
|
||||
atomicBridge: AaveQuotePushFlashReceiver.AtomicBridgeParams({
|
||||
coordinator: address(0),
|
||||
sourceChain: 0,
|
||||
destinationChain: 0,
|
||||
destinationAsset: address(0),
|
||||
bridgeAmount: 0,
|
||||
minDestinationAmount: 0,
|
||||
destinationRecipient: address(0),
|
||||
destinationDeadline: 0,
|
||||
routeId: bytes32(0),
|
||||
settlementMode: bytes32(0),
|
||||
submitCommitment: false
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
90
script/flash/SeedMainnetCwStablePoolPermanent.s.sol
Normal file
90
script/flash/SeedMainnetCwStablePoolPermanent.s.sol
Normal file
@@ -0,0 +1,90 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
|
||||
interface IDODOPMMIntegrationSeed {
|
||||
function isRegisteredPool(address pool) external view returns (bool);
|
||||
function addLiquidity(address pool, uint256 baseAmount, uint256 quoteAmount)
|
||||
external
|
||||
returns (uint256 baseShare, uint256 quoteShare, uint256 lpShare);
|
||||
}
|
||||
|
||||
interface IDODOPMMPoolSeed {
|
||||
function _BASE_TOKEN_() external view returns (address);
|
||||
function _QUOTE_TOKEN_() external view returns (address);
|
||||
function getVaultReserve() external view returns (uint256 baseReserve, uint256 quoteReserve);
|
||||
}
|
||||
|
||||
/// @notice Permanently seed defended mainnet cWUSDC/USDC or cWUSDT/USDT DODO pools via addLiquidity.
|
||||
/// @dev Uses deployer inventory — not flash (flash must repay same block). Pair with Aave borrow + vault deposit off-chain.
|
||||
contract SeedMainnetCwStablePoolPermanent is Script {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
address internal constant DEFAULT_INTEGRATION = 0xa9F284eD010f4F7d7F8F201742b49b9f58e29b84;
|
||||
address internal constant POOL_CWUSDC_USDC = 0x69776fc607e9edA8042e320e7e43f54d06c68f0E;
|
||||
/// @dev Registered on DODOPMMIntegration.pools(cWUSDT, USDT); 0x99d012… is an unregistered duplicate.
|
||||
address internal constant POOL_CWUSDT_USDT = 0x79156F6B7bf71a1B72D78189B540A89A6C13F6FC;
|
||||
address internal constant CWUSDC = 0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a;
|
||||
address internal constant CWUSDT = 0xaF5017d0163ecb99D9B5D94e3b4D7b09Af44D8AE;
|
||||
address internal constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
|
||||
address internal constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
string memory rail = vm.envOr("CW_STABLE_RAIL", string("USDC"));
|
||||
uint256 baseAmount = vm.envUint("SEED_BASE_AMOUNT_RAW");
|
||||
uint256 quoteAmount = vm.envUint("SEED_QUOTE_AMOUNT_RAW");
|
||||
address integration = vm.envOr("DODO_PMM_INTEGRATION_MAINNET", DEFAULT_INTEGRATION);
|
||||
|
||||
(address pool, address baseToken, address quoteToken) = _resolveRail(rail);
|
||||
|
||||
IDODOPMMPoolSeed poolView = IDODOPMMPoolSeed(pool);
|
||||
require(poolView._BASE_TOKEN_() == baseToken, "base mismatch");
|
||||
require(poolView._QUOTE_TOKEN_() == quoteToken, "quote mismatch");
|
||||
require(IDODOPMMIntegrationSeed(integration).isRegisteredPool(pool), "pool not registered on integration");
|
||||
|
||||
(uint256 baseBefore, uint256 quoteBefore) = poolView.getVaultReserve();
|
||||
console.log("deployer", deployer);
|
||||
console.log("rail", rail);
|
||||
console.log("pool", pool);
|
||||
console.log("baseAmount", baseAmount);
|
||||
console.log("quoteAmount", quoteAmount);
|
||||
console.log("baseReserveBefore", baseBefore);
|
||||
console.log("quoteReserveBefore", quoteBefore);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
IERC20(baseToken).forceApprove(integration, baseAmount);
|
||||
IERC20(quoteToken).forceApprove(integration, quoteAmount);
|
||||
(uint256 baseShare, uint256 quoteShare, uint256 lpShare) =
|
||||
IDODOPMMIntegrationSeed(integration).addLiquidity(pool, baseAmount, quoteAmount);
|
||||
IERC20(baseToken).forceApprove(integration, 0);
|
||||
IERC20(quoteToken).forceApprove(integration, 0);
|
||||
vm.stopBroadcast();
|
||||
|
||||
(uint256 baseAfter, uint256 quoteAfter) = poolView.getVaultReserve();
|
||||
console.log("baseShare", baseShare);
|
||||
console.log("quoteShare", quoteShare);
|
||||
console.log("lpShare", lpShare);
|
||||
console.log("baseReserveAfter", baseAfter);
|
||||
console.log("quoteReserveAfter", quoteAfter);
|
||||
}
|
||||
|
||||
function _resolveRail(string memory rail)
|
||||
internal
|
||||
pure
|
||||
returns (address pool, address baseToken, address quoteToken)
|
||||
{
|
||||
bytes32 key = keccak256(bytes(rail));
|
||||
if (key == keccak256(bytes("USDC"))) {
|
||||
return (POOL_CWUSDC_USDC, CWUSDC, USDC);
|
||||
}
|
||||
if (key == keccak256(bytes("USDT"))) {
|
||||
return (POOL_CWUSDT_USDT, CWUSDT, USDT);
|
||||
}
|
||||
revert("CW_STABLE_RAIL must be USDC or USDT");
|
||||
}
|
||||
}
|
||||
48
script/hybx-omnl/RecoverOMNLReserveVaultSafe.s.sol
Normal file
48
script/hybx-omnl/RecoverOMNLReserveVaultSafe.s.sol
Normal file
@@ -0,0 +1,48 @@
|
||||
// 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 reserve store with deployer bootstrap, enable notary gate, migrate commitment, hand DEFAULT_ADMIN to vault Safe.
|
||||
contract RecoverOMNLReserveVaultSafe is Script {
|
||||
bytes32 private constant DEFAULT_ADMIN_ROLE = 0x00;
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address vaultSafe = vm.envAddress("OMNL_VAULT_SAFE");
|
||||
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"))));
|
||||
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 storeV3 = new ReserveCommitmentStore(deployer);
|
||||
storeV3.configureNotaryGate(notary, true, jurId, matrixId);
|
||||
storeV3.setAttestationThreshold(attTh);
|
||||
if (mirror != address(0)) {
|
||||
storeV3.setMirrorReceiver(mirror);
|
||||
}
|
||||
if (c.R != 0) {
|
||||
storeV3.commitReserve(lineId, c.R, c.validUntil, c.evidenceHash, c.merkleRoot);
|
||||
}
|
||||
storeV3.grantRole(DEFAULT_ADMIN_ROLE, vaultSafe);
|
||||
storeV3.revokeRole(DEFAULT_ADMIN_ROLE, deployer);
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console2.log("ReserveCommitmentStoreV3", address(storeV3));
|
||||
console2.log("vaultSafe", vaultSafe);
|
||||
console2.log("requireNotarizedEvidence", storeV3.requireNotarizedEvidence());
|
||||
console2.log("legacyStore", legacyStore);
|
||||
}
|
||||
}
|
||||
@@ -103,13 +103,14 @@ contract DeployM00DiamondHub138 is Script {
|
||||
}
|
||||
|
||||
function _accessSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](6);
|
||||
s = new bytes4[](7);
|
||||
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;
|
||||
s[2] = AccessFacet.hasRoles.selector;
|
||||
s[3] = AccessFacet.ROLE_UPGRADE_BIT.selector;
|
||||
s[4] = AccessFacet.ROLE_GOVERNANCE_BIT.selector;
|
||||
s[5] = AccessFacet.ROLE_INDEX_BIT.selector;
|
||||
s[6] = AccessFacet.ROLE_MONETARY_BIT.selector;
|
||||
}
|
||||
|
||||
function _bridgeSelectors() internal pure returns (bytes4[] memory s) {
|
||||
@@ -137,15 +138,19 @@ contract DeployM00DiamondHub138 is Script {
|
||||
}
|
||||
|
||||
function _rwaDocSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](2);
|
||||
s = new bytes4[](4);
|
||||
s[0] = RWADocumentFacet.anchorDocument.selector;
|
||||
s[1] = RWADocumentFacet.setPrimaryContentHash.selector;
|
||||
s[2] = RWADocumentFacet.documentCount.selector;
|
||||
s[3] = RWADocumentFacet.getDocument.selector;
|
||||
}
|
||||
|
||||
function _rwaStdSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](3);
|
||||
s = new bytes4[](5);
|
||||
s[0] = RWAStandardsRegistryFacet.enableStandard.selector;
|
||||
s[1] = RWAStandardsRegistryFacet.disableStandard.selector;
|
||||
s[2] = RWAStandardsRegistryFacet.bindAssetStandardFacet.selector;
|
||||
s[3] = RWAStandardsRegistryFacet.isStandardEnabled.selector;
|
||||
s[4] = RWAStandardsRegistryFacet.assetStandardFacet.selector;
|
||||
}
|
||||
}
|
||||
|
||||
32
script/m00-diamond/SeedM00LiIndexWeights138.s.sol
Normal file
32
script/m00-diamond/SeedM00LiIndexWeights138.s.sol
Normal file
@@ -0,0 +1,32 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import {IndexFacet} from "@gru/facets/IndexFacet.sol";
|
||||
import {IERC173} from "@gru/interfaces/IERC173.sol";
|
||||
|
||||
/// @notice Seed unit weights (1e18) for each Li* index on the M00 diamond hub.
|
||||
contract SeedM00LiIndexWeights138 is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address diamond = vm.envAddress("M00_DIAMOND_HUB");
|
||||
uint256 chainId = 138;
|
||||
|
||||
string[5] memory tickers = ["LiXAU", "LiPMG", "LiBMG1", "LiBMG2", "LiBMG3"];
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
for (uint256 i = 0; i < tickers.length; i++) {
|
||||
bytes32 indexId = keccak256(abi.encode(tickers[i], chainId));
|
||||
bytes32[] memory keys = new bytes32[](1);
|
||||
keys[0] = keccak256(abi.encode(tickers[i]));
|
||||
uint256[] memory weights = new uint256[](1);
|
||||
weights[0] = 1e18;
|
||||
IndexFacet(diamond).setWeights(indexId, keys, weights, 1, keccak256("M00_LI_v1"));
|
||||
}
|
||||
address newOwner = vm.envOr("M00_DIAMOND_OWNER", vm.envOr("GOVERNANCE_CONTROLLER", address(0)));
|
||||
if (newOwner != address(0)) {
|
||||
IERC173(diamond).transferOwnership(newOwner);
|
||||
}
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
133
script/m00-diamond/UpgradeM00DiamondHubComplete138.s.sol
Normal file
133
script/m00-diamond/UpgradeM00DiamondHubComplete138.s.sol
Normal file
@@ -0,0 +1,133 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import {IDiamondCut} from "@gru/interfaces/IDiamondCut.sol";
|
||||
import {IndexFacet} from "@gru/facets/IndexFacet.sol";
|
||||
import {MonetaryFacet} from "@gru/facets/MonetaryFacet.sol";
|
||||
import {GovernanceFacet} from "@gru/facets/GovernanceFacet.sol";
|
||||
import {AccessFacet} from "@gru/facets/AccessFacet.sol";
|
||||
import {IAccess} from "@gru/interfaces/IAccess.sol";
|
||||
import {IGovernance} from "@gru/interfaces/IGovernance.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";
|
||||
|
||||
/**
|
||||
* @title UpgradeM00DiamondHubComplete138
|
||||
* @notice Add GRC Index/Monetary/Governance facets, RWA read selectors, AccessFacet.hasRoles; grant GRC roles.
|
||||
*/
|
||||
contract UpgradeM00DiamondHubComplete138 is Script {
|
||||
uint256 internal constant ROLE_ALL_GRC = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3);
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address diamond = vm.envAddress("M00_DIAMOND_HUB");
|
||||
address governance = vm.envOr("GOVERNANCE_CONTROLLER", deployer);
|
||||
address accessFacet = vm.envAddress("M00_ACCESS_FACET");
|
||||
address rwaInst = vm.envAddress("M00_RWA_INSTRUMENT_FACET");
|
||||
address rwaDoc = vm.envAddress("M00_RWA_DOCUMENT_FACET");
|
||||
address rwaStd = vm.envAddress("M00_RWA_STANDARDS_FACET");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
IndexFacet index = new IndexFacet();
|
||||
MonetaryFacet monetary = new MonetaryFacet();
|
||||
GovernanceFacet govFacet = new GovernanceFacet();
|
||||
|
||||
IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](7);
|
||||
cut[0] = _add(address(index), _indexSelectors());
|
||||
cut[1] = _add(address(monetary), _monetarySelectors());
|
||||
cut[2] = _add(address(govFacet), _governanceSelectors());
|
||||
cut[3] = _add(accessFacet, _accessExtraSelectors());
|
||||
cut[4] = _add(rwaInst, _rwaInstViewSelectors());
|
||||
cut[5] = _add(rwaDoc, _rwaDocViewSelectors());
|
||||
cut[6] = _add(rwaStd, _rwaStdViewSelectors());
|
||||
|
||||
IDiamondCut(diamond).diamondCut(cut, address(0), "");
|
||||
|
||||
IAccess(diamond).grantRoles(governance, ROLE_ALL_GRC);
|
||||
if (governance != deployer) {
|
||||
IAccess(diamond).grantRoles(deployer, ROLE_ALL_GRC);
|
||||
}
|
||||
|
||||
IGovernance(diamond).setGovernanceParams(86_400, 5_000);
|
||||
|
||||
console.log("M00Diamond", diamond);
|
||||
console.log("IndexFacet", address(index));
|
||||
console.log("MonetaryFacet", address(monetary));
|
||||
console.log("GovernanceFacet", address(govFacet));
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
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 _indexSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](8);
|
||||
s[0] = IndexFacet.setWeights.selector;
|
||||
s[1] = IndexFacet.getIndex.selector;
|
||||
s[2] = IndexFacet.recalcLiCRI.selector;
|
||||
s[3] = IndexFacet.recalcLiCRIWeighted.selector;
|
||||
s[4] = IndexFacet.setDashboardComposite.selector;
|
||||
s[5] = IndexFacet.getLiCRI.selector;
|
||||
s[6] = IndexFacet.setIndexValue.selector;
|
||||
s[7] = IndexFacet.getIndexValue.selector;
|
||||
}
|
||||
|
||||
function _monetarySelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](6);
|
||||
s[0] = MonetaryFacet.mintM1.selector;
|
||||
s[1] = MonetaryFacet.burnM1.selector;
|
||||
s[2] = MonetaryFacet.issueM0.selector;
|
||||
s[3] = MonetaryFacet.redeemM0.selector;
|
||||
s[4] = MonetaryFacet.setScalarS.selector;
|
||||
s[5] = MonetaryFacet.getLayers.selector;
|
||||
}
|
||||
|
||||
function _governanceSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](9);
|
||||
s[0] = GovernanceFacet.proposeCut.selector;
|
||||
s[1] = GovernanceFacet.queueCut.selector;
|
||||
s[2] = GovernanceFacet.executeCut.selector;
|
||||
s[3] = GovernanceFacet.emergencyBrake.selector;
|
||||
s[4] = GovernanceFacet.timelock.selector;
|
||||
s[5] = GovernanceFacet.quorumBps.selector;
|
||||
s[6] = GovernanceFacet.eta.selector;
|
||||
s[7] = GovernanceFacet.proposer.selector;
|
||||
s[8] = GovernanceFacet.setGovernanceParams.selector;
|
||||
}
|
||||
|
||||
function _accessExtraSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](1);
|
||||
s[0] = AccessFacet.hasRoles.selector;
|
||||
}
|
||||
|
||||
function _rwaInstViewSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](2);
|
||||
s[0] = RWAInstrumentFacet.getIssuanceMode.selector;
|
||||
s[1] = RWAInstrumentFacet.getTokenPointer.selector;
|
||||
}
|
||||
|
||||
function _rwaDocViewSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](2);
|
||||
s[0] = RWADocumentFacet.documentCount.selector;
|
||||
s[1] = RWADocumentFacet.getDocument.selector;
|
||||
}
|
||||
|
||||
function _rwaStdViewSelectors() internal pure returns (bytes4[] memory s) {
|
||||
s = new bytes4[](2);
|
||||
s[0] = RWAStandardsRegistryFacet.isStandardEnabled.selector;
|
||||
s[1] = RWAStandardsRegistryFacet.assetStandardFacet.selector;
|
||||
}
|
||||
}
|
||||
168
script/reserve/WireChain138OraclePegs138.s.sol
Normal file
168
script/reserve/WireChain138OraclePegs138.s.sol
Normal file
@@ -0,0 +1,168 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {Aggregator} from "../../contracts/oracle/Aggregator.sol";
|
||||
|
||||
interface IOraclePriceFeedWire {
|
||||
function aggregators(address asset) external view returns (address);
|
||||
function setAggregator(address asset, address aggregator, uint256 multiplier) external;
|
||||
function updatePriceFeed(address asset) external;
|
||||
function setUpdateInterval(uint256 interval) external;
|
||||
function updateInterval() external view returns (uint256);
|
||||
}
|
||||
|
||||
interface IPriceFeedKeeperWire {
|
||||
function isTracked(address asset) external view returns (bool);
|
||||
function trackAsset(address asset) external;
|
||||
function maxUpdatesPerCall() external view returns (uint256);
|
||||
function setMaxUpdatesPerCall(uint256 max) external;
|
||||
}
|
||||
|
||||
interface IDODOPMMIntegrationWire {
|
||||
function setReserveSystem(address reserveSystem_) external;
|
||||
function reserveSystem() external view returns (address);
|
||||
}
|
||||
|
||||
interface IReserveSystemWire {
|
||||
function updatePriceFeed(address asset, uint256 price, uint256 timestamp) external;
|
||||
}
|
||||
|
||||
interface IAggregatorWire {
|
||||
function addTransmitter(address transmitter) external;
|
||||
function updateAnswer(uint256 answer) external;
|
||||
function isTransmitter(address transmitter) external view returns (bool);
|
||||
function latestRoundData()
|
||||
external
|
||||
view
|
||||
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
|
||||
}
|
||||
|
||||
/// @notice Wire canonical Chain 138 assets to Chainlink-mirrored repo aggregators + keeper + reserve.
|
||||
contract WireChain138OraclePegs138 is Script {
|
||||
uint256 internal constant MULT = 1e10;
|
||||
|
||||
address internal constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
|
||||
address internal constant WETH10 = 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9F;
|
||||
address internal constant LINK = 0xb7721dD53A8c629d9f1Ba31a5819AFe250002b03;
|
||||
address internal constant CUSDT = 0x93E66202A11B1772E55407B32B44e5Cd8eda7f22;
|
||||
address internal constant CUSDC = 0xf22258f57794CC8E06237084b353Ab30fFfa640b;
|
||||
address internal constant CEURC = 0x8085961F9cF02b4d800A3c6d386D31da4B34266a;
|
||||
address internal constant CEURT = 0xdf4b71c61E5912712C1Bdd451416B9aC26949d72;
|
||||
address internal constant CGBPC = 0x003960f16D9d34F2e98d62723B6721Fb92074aD2;
|
||||
address internal constant CGBPT = 0x350f54e4D23795f86A9c03988c7135357CCaD97c;
|
||||
address internal constant CAUDC = 0xD51482e567c03899eecE3CAe8a058161FD56069D;
|
||||
address internal constant CJPYC = 0xEe269e1226a334182aace90056EE4ee5Cc8A6770;
|
||||
address internal constant CCHFC = 0x873990849DDa5117d7C644f0aF24370797C03885;
|
||||
address internal constant CCADC = 0x54dBd40cF05e15906A2C21f600937e96787f5679;
|
||||
address internal constant CXAUC = 0x290E52a8819A4fbD0714E517225429aA2B70EC6b;
|
||||
address internal constant CXAUT = 0x94e408E26c6FD8F4ee00b54dF19082FDA07dC96E;
|
||||
address internal constant CBTC = 0xe94260c555aC1d9D3CC9E1632883452ebDf0082E;
|
||||
|
||||
function run() external {
|
||||
require(block.chainid == 138, "ChainID 138 only");
|
||||
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
|
||||
address opf = vm.envAddress("ORACLE_PRICE_FEED");
|
||||
address keeperAddr = vm.envAddress("PRICE_FEED_KEEPER_ADDRESS");
|
||||
address rs = vm.envAddress("RESERVE_SYSTEM");
|
||||
address ethAgg = vm.envAddress("AGGREGATOR_ADDRESS");
|
||||
address dodo = vm.envAddress("CHAIN_138_DODO_PMM_INTEGRATION");
|
||||
uint256 ethSeed8 = vm.envOr("FEED_ETH_USD_8", uint256(0));
|
||||
|
||||
IOraclePriceFeedWire op = IOraclePriceFeedWire(opf);
|
||||
IPriceFeedKeeperWire keeper = IPriceFeedKeeperWire(keeperAddr);
|
||||
|
||||
console.log("=== Wire Chain 138 oracle pegs ===");
|
||||
console.log("Deployer:", deployer);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
if (op.updateInterval() != 86400) {
|
||||
try op.setUpdateInterval(86400) {} catch {}
|
||||
}
|
||||
|
||||
if (ethSeed8 > 0) {
|
||||
IAggregatorWire eth = IAggregatorWire(ethAgg);
|
||||
if (!eth.isTransmitter(deployer)) {
|
||||
try eth.addTransmitter(deployer) {} catch {}
|
||||
}
|
||||
try eth.updateAnswer(ethSeed8) {} catch {}
|
||||
}
|
||||
|
||||
if (keeper.maxUpdatesPerCall() < 20) {
|
||||
keeper.setMaxUpdatesPerCall(20);
|
||||
}
|
||||
|
||||
address usdAgg = _deployMirror("USD/USD Chainlink mirror", vm.envUint("FEED_USD_USD_8"));
|
||||
address linkAgg = _deployMirror("LINK/USD Chainlink mirror", vm.envUint("FEED_LINK_USD_8"));
|
||||
address btcAgg = _deployMirror("BTC/USD Chainlink mirror", vm.envUint("FEED_BTC_USD_8"));
|
||||
address xauAgg = _deployMirror("XAU/USD Chainlink mirror", vm.envUint("FEED_XAU_USD_8"));
|
||||
address eurAgg = _deployMirror("EUR/USD Chainlink mirror", vm.envUint("FEED_EUR_USD_8"));
|
||||
address gbpAgg = _deployMirror("GBP/USD Chainlink mirror", vm.envUint("FEED_GBP_USD_8"));
|
||||
address audAgg = _deployMirror("AUD/USD Chainlink mirror", vm.envUint("FEED_AUD_USD_8"));
|
||||
address jpyAgg = _deployMirror("JPY/USD Chainlink mirror", vm.envUint("FEED_JPY_USD_8"));
|
||||
address chfAgg = _deployMirror("CHF/USD Chainlink mirror", vm.envUint("FEED_CHF_USD_8"));
|
||||
address cadAgg = _deployMirror("CAD/USD Chainlink mirror", vm.envUint("FEED_CAD_USD_8"));
|
||||
|
||||
_wire(op, keeper, rs, WETH9, ethAgg);
|
||||
_wire(op, keeper, rs, WETH10, ethAgg);
|
||||
_wire(op, keeper, rs, LINK, linkAgg);
|
||||
_wire(op, keeper, rs, CUSDT, usdAgg);
|
||||
_wire(op, keeper, rs, CUSDC, usdAgg);
|
||||
_wire(op, keeper, rs, CEURC, eurAgg);
|
||||
_wire(op, keeper, rs, CEURT, eurAgg);
|
||||
_wire(op, keeper, rs, CGBPC, gbpAgg);
|
||||
_wire(op, keeper, rs, CGBPT, gbpAgg);
|
||||
_wire(op, keeper, rs, CAUDC, audAgg);
|
||||
_wire(op, keeper, rs, CJPYC, jpyAgg);
|
||||
_wire(op, keeper, rs, CCHFC, chfAgg);
|
||||
_wire(op, keeper, rs, CCADC, cadAgg);
|
||||
_wire(op, keeper, rs, CXAUC, xauAgg);
|
||||
_wire(op, keeper, rs, CXAUT, xauAgg);
|
||||
_wire(op, keeper, rs, CBTC, btcAgg);
|
||||
|
||||
IDODOPMMIntegrationWire dodoInt = IDODOPMMIntegrationWire(dodo);
|
||||
if (dodoInt.reserveSystem() != rs) {
|
||||
dodoInt.setReserveSystem(rs);
|
||||
console.log("DODO reserveSystem wired:", rs);
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("=== Done ===");
|
||||
}
|
||||
|
||||
function _deployMirror(string memory description, uint256 price8) internal returns (address) {
|
||||
require(price8 > 0, "missing seed price");
|
||||
Aggregator agg = new Aggregator(description, msg.sender, 3600, 50);
|
||||
agg.addTransmitter(msg.sender);
|
||||
agg.updateAnswer(price8);
|
||||
console.log("Deployed feed:", description);
|
||||
console.log(" aggregator:", address(agg));
|
||||
return address(agg);
|
||||
}
|
||||
|
||||
function _wire(
|
||||
IOraclePriceFeedWire op,
|
||||
IPriceFeedKeeperWire keeper,
|
||||
address rs,
|
||||
address token,
|
||||
address agg
|
||||
) internal {
|
||||
require(agg != address(0), "zero aggregator");
|
||||
if (op.aggregators(token) == address(0)) {
|
||||
op.setAggregator(token, agg, MULT);
|
||||
}
|
||||
if (!keeper.isTracked(token)) {
|
||||
keeper.trackAsset(token);
|
||||
}
|
||||
try op.updatePriceFeed(token) {} catch {
|
||||
(, int256 ans,, uint256 updatedAt,) = IAggregatorWire(agg).latestRoundData();
|
||||
require(ans > 0, "bad agg price");
|
||||
IReserveSystemWire(rs).updatePriceFeed(token, uint256(ans) * MULT, updatedAt);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user