chore: .gitignore and README updates
Made-with: Cursor
This commit is contained in:
@@ -12,9 +12,9 @@ import {CompliantWrappedToken} from "../../contracts/tokens/CompliantWrappedToke
|
||||
* Env:
|
||||
* PRIVATE_KEY (required)
|
||||
* CW_BRIDGE_ADDRESS (required) — address that can mint/burn (e.g. CCIP receiver or custom bridge)
|
||||
* CW_STRICT_MODE=1 (optional) — revoke deployer MINTER/BURNER after bridge grant
|
||||
* CW_STRICT_MODE=0 (optional override) — by default deployer MINTER/BURNER are revoked after bridge grant
|
||||
* CW_GOVERNANCE_ADMIN=0x... (optional) — grant DEFAULT_ADMIN_ROLE to governance; if strict, revoke deployer admin when governance is set
|
||||
* CW_FREEZE_OPERATIONAL_ROLES=1 (optional) — freeze future MINTER/BURNER changes after setup
|
||||
* CW_FREEZE_OPERATIONAL_ROLES=0 (optional override) — by default freeze future MINTER/BURNER changes after setup
|
||||
* DEPLOY_CWUSDT=1, DEPLOY_CWUSDC=1, DEPLOY_CWUSDW=1, DEPLOY_CWEURC=1, ... (default all 1; set 0 to skip a token)
|
||||
*/
|
||||
contract DeployCWTokens is Script {
|
||||
@@ -24,8 +24,8 @@ contract DeployCWTokens is Script {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address bridge = vm.envAddress("CW_BRIDGE_ADDRESS");
|
||||
bool strictMode = vm.envOr("CW_STRICT_MODE", uint256(0)) == 1;
|
||||
bool freezeOperationalRoles = vm.envOr("CW_FREEZE_OPERATIONAL_ROLES", uint256(0)) == 1;
|
||||
bool strictMode = vm.envOr("CW_STRICT_MODE", uint256(1)) == 1;
|
||||
bool freezeOperationalRoles = vm.envOr("CW_FREEZE_OPERATIONAL_ROLES", uint256(1)) == 1;
|
||||
address governanceAdmin = vm.envOr("CW_GOVERNANCE_ADMIN", address(0));
|
||||
require(bridge != address(0), "CW_BRIDGE_ADDRESS required");
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@ import {CompliantWrappedToken} from "../../contracts/tokens/CompliantWrappedToke
|
||||
* CW_TOKEN_NAME (required)
|
||||
* CW_TOKEN_SYMBOL (required)
|
||||
* CW_TOKEN_DECIMALS (optional, default 6)
|
||||
* CW_STRICT_MODE=0 (optional override) — by default deployer MINTER/BURNER are revoked after bridge grant
|
||||
* CW_GOVERNANCE_ADMIN=0x... (optional) — grant DEFAULT_ADMIN_ROLE to governance; if strict, revoke deployer admin when governance is set
|
||||
* CW_FREEZE_OPERATIONAL_ROLES=0 (optional override) — by default freeze future MINTER/BURNER changes after setup
|
||||
*/
|
||||
contract DeploySingleCWToken is Script {
|
||||
function run() external {
|
||||
@@ -23,6 +26,9 @@ contract DeploySingleCWToken is Script {
|
||||
string memory tokenName = vm.envString("CW_TOKEN_NAME");
|
||||
string memory tokenSymbol = vm.envString("CW_TOKEN_SYMBOL");
|
||||
uint8 decimals_ = uint8(vm.envOr("CW_TOKEN_DECIMALS", uint256(6)));
|
||||
bool strictMode = vm.envOr("CW_STRICT_MODE", uint256(1)) == 1;
|
||||
bool freezeOperationalRoles = vm.envOr("CW_FREEZE_OPERATIONAL_ROLES", uint256(1)) == 1;
|
||||
address governanceAdmin = vm.envOr("CW_GOVERNANCE_ADMIN", address(0));
|
||||
|
||||
require(bridge != address(0), "CW_BRIDGE_ADDRESS required");
|
||||
require(bytes(tokenName).length != 0, "CW_TOKEN_NAME required");
|
||||
@@ -34,10 +40,32 @@ contract DeploySingleCWToken is Script {
|
||||
token.grantRole(token.MINTER_ROLE(), bridge);
|
||||
token.grantRole(token.BURNER_ROLE(), bridge);
|
||||
|
||||
if (strictMode) {
|
||||
token.revokeRole(token.MINTER_ROLE(), admin);
|
||||
token.revokeRole(token.BURNER_ROLE(), admin);
|
||||
}
|
||||
|
||||
if (governanceAdmin != address(0) && governanceAdmin != admin) {
|
||||
token.grantRole(token.DEFAULT_ADMIN_ROLE(), governanceAdmin);
|
||||
}
|
||||
|
||||
if (freezeOperationalRoles) {
|
||||
token.freezeOperationalRoles();
|
||||
}
|
||||
|
||||
if (strictMode && governanceAdmin != address(0) && governanceAdmin != admin) {
|
||||
token.revokeRole(token.DEFAULT_ADMIN_ROLE(), admin);
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log(tokenSymbol, address(token));
|
||||
console.log(" bridge", bridge);
|
||||
console.log(" strictMode", strictMode);
|
||||
console.log(" governanceAdmin", governanceAdmin);
|
||||
console.log(" operationalRolesFrozen", token.operationalRolesFrozen());
|
||||
console.log(" deployerHasMinter", token.hasRole(token.MINTER_ROLE(), admin));
|
||||
console.log(" deployerHasBurner", token.hasRole(token.BURNER_ROLE(), admin));
|
||||
console.log(" bridgeHasMinter", token.hasRole(token.MINTER_ROLE(), bridge));
|
||||
console.log(" bridgeHasBurner", token.hasRole(token.BURNER_ROLE(), bridge));
|
||||
}
|
||||
|
||||
@@ -7,9 +7,10 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
/**
|
||||
* @title AddLiquidityPMMPoolsChain138
|
||||
* @notice Add liquidity to the three DODO PMM pools on Chain 138 (cUSDT/cUSDC, cUSDT/USDT, cUSDC/USDC).
|
||||
* @notice Add liquidity to the canonical DODO PMM pools on Chain 138, including the stable/WETH lanes.
|
||||
* @dev Env: PRIVATE_KEY, RPC_URL_138, DODO_PMM_INTEGRATION_ADDRESS (or DODO_PMM_INTEGRATION),
|
||||
* POOL_CUSDTCUSDC, POOL_CUSDTUSDT, POOL_CUSDCUSDC,
|
||||
* optional POOL_CUSDTWETH, POOL_CUSDCWETH, POOL_CEURTWETH,
|
||||
* ADD_LIQUIDITY_BASE_AMOUNT, ADD_LIQUIDITY_QUOTE_AMOUNT (e.g. 1000000e6 for 1M units, 6 decimals).
|
||||
* Optional: ADD_LIQUIDITY_CUSDTCUSDC_BASE, ADD_LIQUIDITY_CUSDTCUSDC_QUOTE, etc. for per-pool amounts.
|
||||
* Optional: NEXT_NONCE — set to pending nonce (e.g. after mints) to avoid -32001 "Nonce too low" on broadcast.
|
||||
@@ -31,6 +32,9 @@ contract AddLiquidityPMMPoolsChain138 is Script {
|
||||
address poolCusdtCusdc = vm.envOr("POOL_CUSDTCUSDC", address(0));
|
||||
address poolCusdtUsdt = vm.envOr("POOL_CUSDTUSDT", address(0));
|
||||
address poolCusdcUsdc = vm.envOr("POOL_CUSDCUSDC", address(0));
|
||||
address poolCusdtWeth = vm.envOr("POOL_CUSDTWETH", address(0));
|
||||
address poolCusdcWeth = vm.envOr("POOL_CUSDCWETH", address(0));
|
||||
address poolCeurtWeth = vm.envOr("POOL_CEURTWETH", address(0));
|
||||
|
||||
uint256 defaultBase = vm.envOr("ADD_LIQUIDITY_BASE_AMOUNT", uint256(0));
|
||||
uint256 defaultQuote = vm.envOr("ADD_LIQUIDITY_QUOTE_AMOUNT", uint256(0));
|
||||
@@ -40,6 +44,8 @@ contract AddLiquidityPMMPoolsChain138 is Script {
|
||||
address cusdc = integration.compliantUSDC();
|
||||
address usdt = integration.officialUSDT();
|
||||
address usdc = integration.officialUSDC();
|
||||
address ceurt = vm.envOr("CEURT_ADDRESS_138", address(0xdf4b71c61E5912712C1Bdd451416B9aC26949d72));
|
||||
address weth = vm.envOr("WETH9_ADDRESS_138", vm.envOr("WETH_ADDRESS_138", address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)));
|
||||
|
||||
// On Chain 138, cUSDT/USDT and cUSDC/USDC should point at live local mirror quote tokens.
|
||||
// If the configured quote-side addresses have no code on 138, skip those pools to avoid "call to non-contract".
|
||||
@@ -73,6 +79,30 @@ contract AddLiquidityPMMPoolsChain138 is Script {
|
||||
console.log("Added liquidity to cUSDC/USDC pool:", poolCusdcUsdc);
|
||||
}
|
||||
}
|
||||
if (poolCusdtWeth != address(0) && (defaultBase > 0 || defaultQuote > 0)) {
|
||||
uint256 b = vm.envOr("ADD_LIQUIDITY_CUSDTWETH_BASE", defaultBase);
|
||||
uint256 q = vm.envOr("ADD_LIQUIDITY_CUSDTWETH_QUOTE", defaultQuote);
|
||||
if (b > 0 && q > 0) {
|
||||
_approveAndAdd(integration, cusdt, weth, poolCusdtWeth, b, q);
|
||||
console.log("Added liquidity to cUSDT/WETH pool:", poolCusdtWeth);
|
||||
}
|
||||
}
|
||||
if (poolCusdcWeth != address(0) && (defaultBase > 0 || defaultQuote > 0)) {
|
||||
uint256 b = vm.envOr("ADD_LIQUIDITY_CUSDCWETH_BASE", defaultBase);
|
||||
uint256 q = vm.envOr("ADD_LIQUIDITY_CUSDCWETH_QUOTE", defaultQuote);
|
||||
if (b > 0 && q > 0) {
|
||||
_approveAndAdd(integration, cusdc, weth, poolCusdcWeth, b, q);
|
||||
console.log("Added liquidity to cUSDC/WETH pool:", poolCusdcWeth);
|
||||
}
|
||||
}
|
||||
if (poolCeurtWeth != address(0) && (defaultBase > 0 || defaultQuote > 0)) {
|
||||
uint256 b = vm.envOr("ADD_LIQUIDITY_CEURTWETH_BASE", defaultBase);
|
||||
uint256 q = vm.envOr("ADD_LIQUIDITY_CEURTWETH_QUOTE", defaultQuote);
|
||||
if (b > 0 && q > 0) {
|
||||
_approveAndAdd(integration, ceurt, weth, poolCeurtWeth, b, q);
|
||||
console.log("Added liquidity to cEURT/WETH pool:", poolCeurtWeth);
|
||||
}
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@ interface IDODOPMMPoolQuote {
|
||||
* FLASH_QUOTE_AMOUNT_RAW gross USDC borrowed / pushed (6 decimals raw)
|
||||
*
|
||||
* Optional:
|
||||
* POOL_CWUSDC_USDC_MAINNET default 0x69776fc607e9edA8042e320e7e43f54d06c68f0E
|
||||
* CWUSDC_MAINNET default canonical cWUSDC
|
||||
* USDC_MAINNET default official USDC
|
||||
* MAX_FLASH_QUOTE_AMOUNT_RAW optional tighter local cap; must not exceed the defended-lane safe cap
|
||||
* MIN_OUT_PMM if unset, derived from querySellQuote(receiver, amount) * MIN_OUT_PMM_NUM / MIN_OUT_PMM_DEN (defaults 985/1000)
|
||||
* MIN_OUT_PMM_NUM / MIN_OUT_PMM_DEN
|
||||
* MIN_OUT_UNWIND if unset, amount + ceil(amount * AAVE_FLASH_PREMIUM_BPS / 10000) + MIN_OUT_UNWIND_BUFFER_RAW
|
||||
@@ -50,6 +50,7 @@ contract RunMainnetAaveCwusdcUsdcQuotePushOnce is Script {
|
||||
address internal constant DEFAULT_POOL = 0x69776fc607e9edA8042e320e7e43f54d06c68f0E;
|
||||
address internal constant DEFAULT_CWUSDC = 0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a;
|
||||
address internal constant DEFAULT_USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
|
||||
uint256 internal constant DEFENDED_SAFE_CAP_RAW = 2_964_298;
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
@@ -60,6 +61,9 @@ contract RunMainnetAaveCwusdcUsdcQuotePushOnce is Script {
|
||||
address usdc = vm.envOr("USDC_MAINNET", DEFAULT_USDC);
|
||||
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);
|
||||
|
||||
_validateDefendedLane(pool, amount, localCap);
|
||||
|
||||
uint256 minPmmNum = vm.envOr("MIN_OUT_PMM_NUM", uint256(985));
|
||||
uint256 minPmmDen = vm.envOr("MIN_OUT_PMM_DEN", uint256(1000));
|
||||
@@ -150,4 +154,10 @@ contract RunMainnetAaveCwusdcUsdcQuotePushOnce is Script {
|
||||
AaveQuotePushFlashReceiver(receiver).flashQuotePush(usdc, amount, p);
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
function _validateDefendedLane(address pool, uint256 amount, uint256 localCap) internal pure {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ contract RunManagedMainnetAaveCwusdcUsdcQuotePushCycle is Script {
|
||||
address internal constant DEFAULT_POOL = 0x69776fc607e9edA8042e320e7e43f54d06c68f0E;
|
||||
address internal constant DEFAULT_CWUSDC = 0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a;
|
||||
address internal constant DEFAULT_USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
|
||||
uint256 internal constant DEFENDED_SAFE_CAP_RAW = 2_964_298;
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
@@ -42,9 +43,12 @@ contract RunManagedMainnetAaveCwusdcUsdcQuotePushCycle is Script {
|
||||
address usdc = vm.envOr("USDC_MAINNET", DEFAULT_USDC);
|
||||
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));
|
||||
|
||||
_validateDefendedLane(pool, amount, localCap);
|
||||
|
||||
QuotePushTreasuryManager manager = QuotePushTreasuryManager(managerAddr);
|
||||
AaveQuotePushFlashReceiver.QuotePushParams memory p =
|
||||
_loadQuotePushParams(receiver, pool, integration, baseToken, unwinder, amount);
|
||||
@@ -70,6 +74,12 @@ contract RunManagedMainnetAaveCwusdcUsdcQuotePushCycle is Script {
|
||||
console.log("receiverSweepableAfter", manager.receiverSweepableQuote());
|
||||
}
|
||||
|
||||
function _validateDefendedLane(address pool, uint256 amount, uint256 localCap) internal pure {
|
||||
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");
|
||||
}
|
||||
|
||||
function _loadQuotePushParams(
|
||||
address receiver,
|
||||
address pool,
|
||||
|
||||
@@ -95,6 +95,14 @@ contract ImportProviderPoolsToIntegration is Script {
|
||||
_importIfNeeded(json, providerSource, integration, explicitBase, explicitQuote, lpFeeRate, initialPrice, kFactor, enableTwap);
|
||||
}
|
||||
|
||||
for (uint256 i = 0; json.keyExists(string.concat(".plannedPairs[", vm.toString(i), "]")); i++) {
|
||||
string memory baseKey = string.concat(".plannedPairs[", vm.toString(i), "].baseSymbol");
|
||||
string memory quoteKey = string.concat(".plannedPairs[", vm.toString(i), "].quoteSymbol");
|
||||
string memory plannedBase = json.readString(baseKey);
|
||||
string memory plannedQuote = json.readString(quoteKey);
|
||||
_importIfNeeded(json, providerSource, integration, plannedBase, plannedQuote, lpFeeRate, initialPrice, kFactor, enableTwap);
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user