diff --git a/spot-vaults/README.md b/spot-vaults/README.md index 16c86577..e915bacc 100644 --- a/spot-vaults/README.md +++ b/spot-vaults/README.md @@ -5,15 +5,14 @@ This repository is a collection of vault strategies leveraging the SPOT system. The official mainnet addresses are: - Bill Broker (SPOT-USDC): [0xA088Aef966CAD7fE0B38e28c2E07590127Ab4ccB](https://etherscan.io/address/0xA088Aef966CAD7fE0B38e28c2E07590127Ab4ccB) -- WethWamplManager: [0x6785fa26191eb531c54fd093931f395c4b01b583](https://etherscan.io/address/0x6785fa26191eb531c54fd093931f395c4b01b583) -- UsdcSpotManager: [0x780eB92040bf24cd9BF993505390e88E8ED59935](https://etherscan.io/address/0x780eB92040bf24cd9BF993505390e88E8ED59935) -- SpotAppraiser: [0x965FBFebDA76d9AA11642C1d0074CdF02e546F3c](https://etherscan.io/address/0x965FBFebDA76d9AA11642C1d0074CdF02e546F3c) Used by the Bill Broker -- SpotCDRPricer: [0xa76df05BAb61444fa2C1c5c1e14A3aD912A00EbA](https://etherscan.io/address/0xa76df05BAb61444fa2C1c5c1e14A3aD912A00EbA) Used by the Charm USDC/SPOT auto manager +- WethWamplManager: [0x574fca658b4B59E965C0e5f74761AE0Ac41DA6a7](https://etherscan.io/address/0x574fca658b4B59E965C0e5f74761AE0Ac41DA6a7) +- UsdcSpotManager: [0x2f67158859Fe0f69f5773570eC60444Fe0c1693c](https://etherscan.io/address/0x2f67158859Fe0f69f5773570eC60444Fe0c1693c) +- SpotPricer: [0x0f8f519878c10ce36C6aAF89c1AeefaaDE5D7881](https://etherscan.io/address/0x0f8f519878c10ce36C6aAF89c1AeefaaDE5D7881) The official testnet addresses are: - Bill Broker (SPOT-USDC): [0xc3f6D1F1d253EdC8B34D78Bc6cDD2b3eEFAd76BD](https://sepolia.etherscan.io/address/0xc3f6D1F1d253EdC8B34D78Bc6cDD2b3eEFAd76BD) -- SpotAppraiser: [0x08c5b39F000705ebeC8427C1d64D6262392944EE](https://sepolia.etherscan.io/address/0x08c5b39F000705ebeC8427C1d64D6262392944EE) +- SpotAppraiser **(deprecated)**: [0x08c5b39F000705ebeC8427C1d64D6262392944EE](https://sepolia.etherscan.io/address/0x08c5b39F000705ebeC8427C1d64D6262392944EE) ## Install diff --git a/spot-vaults/tasks/deploy.ts b/spot-vaults/tasks/deploy.ts index 1c609061..07ae73d6 100644 --- a/spot-vaults/tasks/deploy.ts +++ b/spot-vaults/tasks/deploy.ts @@ -17,52 +17,44 @@ task("deploy:mocks").setAction(async function (args: TaskArguments, hre) { await cpiOracle.mockData("1200000000000000000", true); }); -task("deploy:SpotAppraiser") - .addParam("perp", "the address of the perp token", undefined, types.string, false) - .addParam("usdOracle", "the address of the usd oracle", undefined, types.string, false) - .addParam("cpiOracle", "the address of the usd oracle", undefined, types.string, false) - .addParam("verify", "flag to set false for local deployments", true, types.boolean) - .setAction(async function (args: TaskArguments, hre) { - const deployer = (await hre.ethers.getSigners())[0]; - console.log("Signer", await deployer.getAddress()); - - const { perp, usdOracle, cpiOracle } = args; - - const SpotAppraiser = await hre.ethers.getContractFactory("SpotAppraiser"); - const spotAppraiser = await SpotAppraiser.deploy(perp, usdOracle, cpiOracle); - console.log("spotAppraiser", spotAppraiser.target); - - if (args.verify) { - await sleep(30); - await hre.run("verify:contract", { - address: spotAppraiser.target, - constructorArguments: [perp, usdOracle, cpiOracle], - }); - } else { - console.log("Skipping verification"); - } - }); - -task("deploy:SpotCDRPricer") - .addParam("perp", "the address of the perp token", undefined, types.string, false) +task("deploy:SpotPricer") + .addParam( + "wethWamplPool", + "the address of the weth-wampl univ3 pool", + undefined, + types.string, + false, + ) + .addParam( + "usdcSpotPool", + "the address of the usdc-spot univ3 pool", + undefined, + types.string, + false, + ) + .addParam("ethOracle", "the address of the eth oracle", undefined, types.string, false) .addParam("usdOracle", "the address of the usd oracle", undefined, types.string, false) - .addParam("cpiOracle", "the address of the usd oracle", undefined, types.string, false) .addParam("verify", "flag to set false for local deployments", true, types.boolean) .setAction(async function (args: TaskArguments, hre) { const deployer = (await hre.ethers.getSigners())[0]; console.log("Signer", await deployer.getAddress()); - const { perp, usdOracle, cpiOracle } = args; + const { wethWamplPool, usdcSpotPool, ethOracle, usdOracle } = args; - const SpotCDRPricer = await hre.ethers.getContractFactory("SpotCDRPricer"); - const spotCDRPricer = await SpotCDRPricer.deploy(perp, usdOracle, cpiOracle); - console.log("spotCDRPricer", spotCDRPricer.target); + const SpotPricer = await hre.ethers.getContractFactory("SpotPricer"); + const spotPricer = await SpotPricer.deploy( + wethWamplPool, + usdcSpotPool, + ethOracle, + usdOracle, + ); + console.log("spotPricer", spotPricer.target); if (args.verify) { await sleep(30); await hre.run("verify:contract", { - address: spotCDRPricer.target, - constructorArguments: [perp, usdOracle, cpiOracle], + address: spotPricer.target, + constructorArguments: [wethWamplPool, usdcSpotPool, ethOracle, usdOracle], }); } else { console.log("Skipping verification"); @@ -86,23 +78,17 @@ task("deploy:BillBroker") ) .addParam("usd", "the address of the usd token", undefined, types.string, false) .addParam("perp", "the address of the perp token", undefined, types.string, false) - .addParam( - "pricingStrategy", - "the address of the pricing strategy", - undefined, - types.string, - false, - ) + .addParam("oracle", "the address of the oracle", undefined, types.string, false) .addParam("verify", "flag to set false for local deployments", true, types.boolean) .setAction(async function (args: TaskArguments, hre) { const deployer = (await hre.ethers.getSigners())[0]; console.log("Signer", await deployer.getAddress()); - const { name, symbol, usd, perp, pricingStrategy } = args; + const { name, symbol, usd, perp, oracle } = args; const BillBroker = await hre.ethers.getContractFactory("BillBroker"); const billBroker = await hre.upgrades.deployProxy( BillBroker.connect(deployer), - [name, symbol, usd, perp, pricingStrategy], + [name, symbol, usd, perp, oracle], { initializer: "init(string,string,address,address,address)", }, @@ -119,69 +105,32 @@ task("deploy:BillBroker") } }); -task("deploy:WethWamplManager") - .addParam( - "vault", - "the address of the weth-wampl charm vault", - undefined, - types.string, - false, - ) - .addParam("cpiOracle", "the address of the usd oracle", undefined, types.string, false) - .addParam("ethOracle", "the address of the eth oracle", undefined, types.string, false) - .addParam("verify", "flag to set false for local deployments", true, types.boolean) - .setAction(async function (args: TaskArguments, hre) { - const deployer = (await hre.ethers.getSigners())[0]; - console.log("Signer", await deployer.getAddress()); - - const { vault, cpiOracle, ethOracle } = args; - - const WethWamplManager = await hre.ethers.getContractFactory("WethWamplManager"); - const manager = await WethWamplManager.deploy(vault, cpiOracle, ethOracle); - console.log("wethWamplManager", manager.target); - - if (args.verify) { - await sleep(30); - await hre.run("verify:contract", { - address: manager.target, - constructorArguments: [vault, cpiOracle, ethOracle], - }); - } else { - console.log("Skipping verification"); - } - }); - -task("deploy:UsdcSpotManager") - .addParam( - "vault", - "the address of the usdc-spot charm vault", - undefined, - types.string, - false, - ) +task("deploy:CharmManager") .addParam( - "spotAppraiser", - "the address of the spot appraiser", + "manager", + "the contract reference of the manager to be deployed", undefined, types.string, false, ) + .addParam("vault", "the address of the charm vault", undefined, types.string, false) + .addParam("oracle", "the address of the meta oracle", undefined, types.string, false) .addParam("verify", "flag to set false for local deployments", true, types.boolean) .setAction(async function (args: TaskArguments, hre) { const deployer = (await hre.ethers.getSigners())[0]; console.log("Signer", await deployer.getAddress()); - const { vault, spotAppraiser } = args; + const { manager, vault, oracle } = args; - const UsdcSpotManager = await hre.ethers.getContractFactory("UsdcSpotManager"); - const manager = await UsdcSpotManager.deploy(vault, spotAppraiser); - console.log("usdcSpotManager", manager.target); + const Factory = await hre.ethers.getContractFactory(manager); + const mgr = await Factory.deploy(vault, oracle); + console.log(manager, mgr.target); if (args.verify) { await sleep(30); await hre.run("verify:contract", { - address: manager.target, - constructorArguments: [vault, spotAppraiser], + address: mgr.target, + constructorArguments: [vault, oracle], }); } else { console.log("Skipping verification"); diff --git a/spot-vaults/tasks/info.ts b/spot-vaults/tasks/info.ts index 326c6e76..9cb18ac4 100644 --- a/spot-vaults/tasks/info.ts +++ b/spot-vaults/tasks/info.ts @@ -7,6 +7,68 @@ function pp(val, decimals) { return parseFloat(ethers.formatUnits(val, decimals)); } +task("info:MetaOracle") + .addPositionalParam( + "address", + "the address of the meta oracle contract", + undefined, + types.string, + false, + ) + .setAction(async function (args: TaskArguments, hre) { + const { address } = args; + + const oracle = await hre.ethers.getContractAt("IMetaOracle", address); + const oracleDecimals = await oracle.decimals(); + console.log("---------------------------------------------------------------"); + console.log("MetaOracle:", oracle.target); + + console.log("---------------------------------------------------------------"); + const usdcPriceData = await oracle.usdcPrice.staticCall(); + console.log("usdcPrice:", pp(usdcPriceData[0], oracleDecimals)); + + const ethPriceData = await oracle.ethUsdPrice.staticCall(); + console.log("ethPrice:", pp(ethPriceData[0], oracleDecimals)); + + const wamplPriceData = await oracle.wamplUsdPrice.staticCall(); + console.log("wamplPrice:", pp(wamplPriceData[0], oracleDecimals)); + + console.log("---------------------------------------------------------------"); + + const amplPriceData = await oracle.amplUsdPrice.staticCall(); + console.log("amplPrice:", pp(amplPriceData[0], oracleDecimals)); + + const amplTargetPriceData = await oracle.amplTargetUsdPrice.staticCall(); + console.log("amplTargetPrice:", pp(amplTargetPriceData[0], oracleDecimals)); + + const amplDeviationData = await oracle.amplPriceDeviation.staticCall(); + console.log("amplDeviation:", pp(amplDeviationData[0], oracleDecimals)); + + console.log("---------------------------------------------------------------"); + + const spotPriceData = await oracle.spotUsdPrice.staticCall(); + console.log("spotPrice:", pp(spotPriceData[0], oracleDecimals)); + + const spotFmvPriceData = await oracle.spotFmvUsdPrice.staticCall(); + console.log("spotFmvPrice:", pp(spotFmvPriceData[0], oracleDecimals)); + + const spotDeviationData = await oracle.spotPriceDeviation.staticCall(); + console.log("spotDeviation:", pp(spotDeviationData[0], oracleDecimals)); + + console.log("---------------------------------------------------------------"); + + const spotDeviation = pp(spotDeviationData[0], oracleDecimals); + const amplDeviation = pp(amplDeviationData[0], oracleDecimals); + const relativeDeviation = spotDeviation / amplDeviation; + + console.log("relativeDeviation:", relativeDeviation); + console.log("noArbZone:", relativeDeviation > 0.9 && relativeDeviation < 1.025); + console.log("flashMintZone:", relativeDeviation >= 1.025); + console.log("flashRedeemZone:", relativeDeviation <= 0.9); + + console.log("---------------------------------------------------------------"); + }); + task("info:BillBroker") .addPositionalParam( "address", @@ -31,21 +93,20 @@ task("info:BillBroker") const unitUsd = await billBroker.usdUnitAmt(); const unitPerp = await billBroker.perpUnitAmt(); - const pricingStrategy = await hre.ethers.getContractAt( - "SpotAppraiser", - await billBroker.pricingStrategy.staticCall(), + const oracle = await hre.ethers.getContractAt( + "SpotPricer", + // await billBroker.oracle.staticCall(), + "0x0f8f519878c10ce36C6aAF89c1AeefaaDE5D7881", ); - const pricingStrategyDecimals = await pricingStrategy.decimals(); + const oracleDecimals = await oracle.decimals(); console.log("---------------------------------------------------------------"); - console.log("pricingStrategy:", pricingStrategy.target); - console.log("owner:", await pricingStrategy.owner()); - const usdPriceCall = await pricingStrategy.usdPrice.staticCall(); - console.log("usdPrice:", pp(usdPriceCall[0], pricingStrategyDecimals)); + console.log("oracle:", oracle.target); + const usdPriceCall = await oracle.usdPrice.staticCall(); + console.log("usdPrice:", pp(usdPriceCall[0], oracleDecimals)); console.log("usdPriceValid:", usdPriceCall[1]); - const perpPriceCall = await pricingStrategy.perpPrice.staticCall(); - console.log("perpPrice:", pp(perpPriceCall[0], pricingStrategyDecimals)); + const perpPriceCall = await oracle.perpUsdPrice.staticCall(); + console.log("perpPrice:", pp(perpPriceCall[0], oracleDecimals)); console.log("perpPriceValid:", perpPriceCall[1]); - console.log("isSpotHealthy:", await pricingStrategy.isSPOTHealthy.staticCall()); console.log("---------------------------------------------------------------"); console.log("BillBroker:", billBroker.target); console.log("owner:", await billBroker.owner()); @@ -143,24 +204,15 @@ task("info:WethWamplManager") const { address } = args; const manager = await hre.ethers.getContractAt("WethWamplManager", address); + const oracle = await hre.ethers.getContractAt("IMetaOracle", await manager.oracle()); const managerDecimals = await manager.decimals(); console.log("---------------------------------------------------------------"); console.log("WethWamplManager:", manager.target); console.log("owner:", await manager.owner()); - console.log("cpiOracle:", await manager.cpiOracle()); - console.log("ethOracle:", await manager.ethOracle()); + console.log("oracle:", oracle.target); console.log("---------------------------------------------------------------"); - const ethPriceData = await manager.getEthUSDPrice(); - console.log("ethPrice:", pp(ethPriceData[0], managerDecimals)); - - const wamplPrice = await manager.getWamplUSDPrice(ethPriceData[0]); - console.log("wamplPrice:", pp(wamplPrice, managerDecimals)); - - const amplPrice = await manager.getAmplUSDPrice(ethPriceData[0]); - console.log("amplPrice:", pp(amplPrice, managerDecimals)); - - const r = await manager.computeDeviationFactor.staticCall(); + const r = await oracle.amplPriceDeviation.staticCall(); const deviation = r[0]; console.log("dataValid:", r[1]); console.log("isOverweightWampl:", await manager.isOverweightWampl()); @@ -193,22 +245,25 @@ task("info:UsdcSpotManager") const { address } = args; const manager = await hre.ethers.getContractAt("UsdcSpotManager", address); + const oracle = await hre.ethers.getContractAt("IMetaOracle", await manager.oracle()); const managerDecimals = await manager.decimals(); console.log("---------------------------------------------------------------"); console.log("UsdcSpotManager:", manager.target); console.log("owner:", await manager.owner()); + console.log("oracle:", oracle.target); console.log("---------------------------------------------------------------"); - const spotPrice = await manager.getSpotUSDPrice(); - console.log("spotPrice:", pp(spotPrice, managerDecimals)); - - const r = await manager.computeDeviationFactor.staticCall(); + const r = await oracle.spotPriceDeviation.staticCall(); const deviation = r[0]; console.log("dataValid:", r[1]); console.log("isOverweightSpot:", await manager.isOverweightSpot()); - console.log("prevDeviation:", pp(await manager.prevDeviation(), managerDecimals)); + console.log("prevWithinActiveZone:", await manager.prevWithinActiveZone()); + console.log("withinActiveZone:", await manager.activeZone(deviation)); console.log("deviation:", pp(deviation, managerDecimals)); - + console.log( + "fullRangePerc:", + pp(await manager.activeFullRangePerc(), managerDecimals), + ); let rebalanceActive = true; try { await manager.rebalance.staticCall(); diff --git a/spot-vaults/tasks/scripts/mainnet.sh b/spot-vaults/tasks/scripts/mainnet.sh index bc4b46b0..9b0eb47f 100644 --- a/spot-vaults/tasks/scripts/mainnet.sh +++ b/spot-vaults/tasks/scripts/mainnet.sh @@ -1,40 +1,45 @@ ######################################################################## ## DEPLOYMENT -yarn hardhat --network mainnet deploy:SpotAppraiser \ - --perp "0xC1f33e0cf7e40a67375007104B929E49a581bafE" \ - --usd-oracle "0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6" \ - --cpi-oracle "0x2A18bfb505b49AED12F19F271cC1183F98ff4f71" +yarn hardhat --network mainnet deploy:SpotPricer \ + --weth-wampl-pool "0x0c2b6bf7322a3cceb47c7ba74f2c75a19f530f11" \ + --usdc-spot-pool "0x898adc9aa0c23dce3fed6456c34dbe2b57784325" \ + --eth-oracle "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419" \ + --usd-oracle "0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6" yarn hardhat --network mainnet deploy:BillBroker \ --name "Bill Broker USDC-SPOT LP" \ --symbol "BB-USDC-SPOT" \ --usd "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" \ --perp "0xC1f33e0cf7e40a67375007104B929E49a581bafE" \ - --pricing-strategy "0x965FBFebDA76d9AA11642C1d0074CdF02e546F3c" + --oracle "0x0f8f519878c10ce36C6aAF89c1AeefaaDE5D7881" -yarn hardhat --network mainnet transferOwnership "0x965FBFebDA76d9AA11642C1d0074CdF02e546F3c" \ - --new-owner-address "0x57981B1EaFe4b18EC97f8B10859B40207b364662" +yarn hardhat --network mainnet deploy:CharmManager \ + --manager "WethWamplManager" \ + --vault "0x9658B5bdCad59Dd0b7b936d955E5dF81eA2B4DcB" \ + --oracle "0x0f8f519878c10ce36C6aAF89c1AeefaaDE5D7881" + +yarn hardhat --network mainnet deploy:CharmManager \ + --manager "UsdcSpotManager" \ + --vault "0x2dcaff0f75765d7867887fc402b71c841b3a4bfb" \ + --oracle "0x0f8f519878c10ce36C6aAF89c1AeefaaDE5D7881" yarn hardhat --network mainnet transferOwnership "0xA088Aef966CAD7fE0B38e28c2E07590127Ab4ccB" \ --new-owner-address "0x57981B1EaFe4b18EC97f8B10859B40207b364662" -yarn hardhat --network mainnet transferOwnership "0xF6E42F7a83fCfB1Bd28aC209fD4a849f54bD1044" \ +yarn hardhat --network mainnet transferOwnership "0x574fca658b4B59E965C0e5f74761AE0Ac41DA6a7" \ --new-owner-address "0x57981B1EaFe4b18EC97f8B10859B40207b364662" -yarn hardhat --network mainnet deploy:WethWamplManager \ - --vault "0x9658B5bdCad59Dd0b7b936d955E5dF81eA2B4DcB" \ - --cpi-oracle "0x2A18bfb505b49AED12F19F271cC1183F98ff4f71" \ - --eth-oracle "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419" - -yarn hardhat --network mainnet transferOwnership "0x803094e6427c0bd10398236433F6c18B7aBf98ab" \ +yarn hardhat --network mainnet transferOwnership "0x2f67158859Fe0f69f5773570eC60444Fe0c1693c" \ --new-owner-address "0x57981B1EaFe4b18EC97f8B10859B40207b364662" ######################################################################## ## INFO +yarn hardhat --network mainnet info:MetaOracle "0x0f8f519878c10ce36C6aAF89c1AeefaaDE5D7881" yarn hardhat --network mainnet info:BillBroker "0xA088Aef966CAD7fE0B38e28c2E07590127Ab4ccB" -yarn hardhat --network mainnet info:WethWamplManager "0x803094e6427c0bd10398236433F6c18B7aBf98ab" +yarn hardhat --network mainnet info:WethWamplManager "0x574fca658b4B59E965C0e5f74761AE0Ac41DA6a7" +yarn hardhat --network mainnet info:UsdcSpotManager "0x2f67158859Fe0f69f5773570eC60444Fe0c1693c" ######################################################################## ## OPS @@ -54,4 +59,10 @@ yarn hardhat --network mainnet ops:swapPerpsForUSD \ yarn hardhat --network mainnet ops:redeem \ --address "0xA088Aef966CAD7fE0B38e28c2E07590127Ab4ccB" \ - --amount 1000 \ No newline at end of file + --amount 1000 + +######################################################################## +## Upgrade + +yarn hardhat --network mainnet validate_upgrade BillBroker "0xA088Aef966CAD7fE0B38e28c2E07590127Ab4ccB" +yarn hardhat --network mainnet prepare_upgrade BillBroker "0xA088Aef966CAD7fE0B38e28c2E07590127Ab4ccB" \ No newline at end of file