From c1e47d5864e411289cf4ad8fdbf9ebba32e31364 Mon Sep 17 00:00:00 2001 From: aalavandhan1984 <6264334+aalavandhan@users.noreply.github.com> Date: Fri, 30 May 2025 12:30:29 -0400 Subject: [PATCH 1/2] upgraded bill broker testnet --- spot-vaults/.openzeppelin/sepolia.json | 319 ++++++++++++++++++ spot-vaults/README.md | 2 +- .../contracts/_test/MockSpotPricer.sol | 44 +++ spot-vaults/package.json | 2 +- spot-vaults/tasks/deploy.ts | 30 ++ spot-vaults/tasks/info.ts | 11 +- spot-vaults/tasks/ops.ts | 116 +++++++ spot-vaults/tasks/scripts/sepolia.sh | 8 + spot-vaults/tasks/upgrade.ts | 4 +- yarn.lock | 63 +++- 10 files changed, 587 insertions(+), 12 deletions(-) create mode 100644 spot-vaults/contracts/_test/MockSpotPricer.sol diff --git a/spot-vaults/.openzeppelin/sepolia.json b/spot-vaults/.openzeppelin/sepolia.json index 6087f3cb..4e464dd5 100644 --- a/spot-vaults/.openzeppelin/sepolia.json +++ b/spot-vaults/.openzeppelin/sepolia.json @@ -326,6 +326,325 @@ }, "namespaces": {} } + }, + "7f703e4a10347cca6e80b8d427a010abcbb83e0b8f3039d52b3a4a4aae5948ff": { + "address": "0x047b82a5D79d9DF62dE4f34CbaBa83F71848a6BF", + "txHash": "0xda1e4afb92b889dce9982b6ff84671a677d7735194299577ca14e1d7a3091cce", + "layout": { + "solcVersion": "0.8.24", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:40" + }, + { + "label": "_balances", + "offset": 0, + "slot": "51", + "type": "t_mapping(t_address,t_uint256)", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:40" + }, + { + "label": "_allowances", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:42" + }, + { + "label": "_totalSupply", + "offset": 0, + "slot": "53", + "type": "t_uint256", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:44" + }, + { + "label": "_name", + "offset": 0, + "slot": "54", + "type": "t_string_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:46" + }, + { + "label": "_symbol", + "offset": 0, + "slot": "55", + "type": "t_string_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:47" + }, + { + "label": "__gap", + "offset": 0, + "slot": "56", + "type": "t_array(t_uint256)45_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:376" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC20BurnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol:51" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_paused", + "offset": 0, + "slot": "201", + "type": "t_bool", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" + }, + { + "label": "_status", + "offset": 0, + "slot": "251", + "type": "t_uint256", + "contract": "ReentrancyGuardUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" + }, + { + "label": "__gap", + "offset": 0, + "slot": "252", + "type": "t_array(t_uint256)49_storage", + "contract": "ReentrancyGuardUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" + }, + { + "label": "perp", + "offset": 0, + "slot": "301", + "type": "t_contract(IPerpetualTranche)2878", + "contract": "BillBroker", + "src": "contracts/BillBroker.sol:94" + }, + { + "label": "usd", + "offset": 0, + "slot": "302", + "type": "t_contract(IERC20Upgradeable)5020", + "contract": "BillBroker", + "src": "contracts/BillBroker.sol:97" + }, + { + "label": "usdUnitAmt", + "offset": 0, + "slot": "303", + "type": "t_uint256", + "contract": "BillBroker", + "src": "contracts/BillBroker.sol:100" + }, + { + "label": "perpUnitAmt", + "offset": 0, + "slot": "304", + "type": "t_uint256", + "contract": "BillBroker", + "src": "contracts/BillBroker.sol:103" + }, + { + "label": "keeper", + "offset": 0, + "slot": "305", + "type": "t_address", + "contract": "BillBroker", + "src": "contracts/BillBroker.sol:108" + }, + { + "label": "oracle", + "offset": 0, + "slot": "306", + "type": "t_contract(IPerpPricer)13600", + "contract": "BillBroker", + "src": "contracts/BillBroker.sol:111" + }, + { + "label": "fees", + "offset": 0, + "slot": "307", + "type": "t_struct(BillBrokerFees)13657_storage", + "contract": "BillBroker", + "src": "contracts/BillBroker.sol:114" + }, + { + "label": "arHardBound", + "offset": 0, + "slot": "314", + "type": "t_struct(Range)13689_storage", + "contract": "BillBroker", + "src": "contracts/BillBroker.sol:117" + }, + { + "label": "arSoftBound", + "offset": 0, + "slot": "316", + "type": "t_struct(Range)13689_storage", + "contract": "BillBroker", + "src": "contracts/BillBroker.sol:121" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)45_storage": { + "label": "uint256[45]", + "numberOfBytes": "1440" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(IERC20Upgradeable)5020": { + "label": "contract IERC20Upgradeable", + "numberOfBytes": "20" + }, + "t_contract(IPerpPricer)13600": { + "label": "contract IPerpPricer", + "numberOfBytes": "20" + }, + "t_contract(IPerpetualTranche)2878": { + "label": "contract IPerpetualTranche", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_uint256)": { + "label": "mapping(address => uint256)", + "numberOfBytes": "32" + }, + "t_string_storage": { + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(BillBrokerFees)13657_storage": { + "label": "struct BillBrokerFees", + "members": [ + { + "label": "mintFeePerc", + "type": "t_uint256", + "offset": 0, + "slot": "0" + }, + { + "label": "burnFeePerc", + "type": "t_uint256", + "offset": 0, + "slot": "1" + }, + { + "label": "perpToUSDSwapFeeFactors", + "type": "t_struct(Range)13689_storage", + "offset": 0, + "slot": "2" + }, + { + "label": "usdToPerpSwapFeeFactors", + "type": "t_struct(Range)13689_storage", + "offset": 0, + "slot": "4" + }, + { + "label": "protocolSwapSharePerc", + "type": "t_uint256", + "offset": 0, + "slot": "6" + } + ], + "numberOfBytes": "224" + }, + "t_struct(Range)13689_storage": { + "label": "struct Range", + "members": [ + { + "label": "lower", + "type": "t_uint256", + "offset": 0, + "slot": "0" + }, + { + "label": "upper", + "type": "t_uint256", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } } } } diff --git a/spot-vaults/README.md b/spot-vaults/README.md index e915bacc..c244e963 100644 --- a/spot-vaults/README.md +++ b/spot-vaults/README.md @@ -12,7 +12,7 @@ The official mainnet addresses are: The official testnet addresses are: - Bill Broker (SPOT-USDC): [0xc3f6D1F1d253EdC8B34D78Bc6cDD2b3eEFAd76BD](https://sepolia.etherscan.io/address/0xc3f6D1F1d253EdC8B34D78Bc6cDD2b3eEFAd76BD) -- SpotAppraiser **(deprecated)**: [0x08c5b39F000705ebeC8427C1d64D6262392944EE](https://sepolia.etherscan.io/address/0x08c5b39F000705ebeC8427C1d64D6262392944EE) +- SpotPricer: [0xc3B2C246b61123E7d18dc8d831A8314Eb038beE5](https://sepolia.etherscan.io/address/0xc3B2C246b61123E7d18dc8d831A8314Eb038beE5) ## Install diff --git a/spot-vaults/contracts/_test/MockSpotPricer.sol b/spot-vaults/contracts/_test/MockSpotPricer.sol new file mode 100644 index 00000000..e263dd77 --- /dev/null +++ b/spot-vaults/contracts/_test/MockSpotPricer.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.24; + +import { Math } from "@openzeppelin/contracts/utils/math/Math.sol"; +import { IPerpetualTranche } from "../_interfaces/external/IPerpetualTranche.sol"; + +/** + * @title MockSpotPricer + * + * @notice SpotPricer for bill broker testnet deployment. + * + */ +contract MockSpotPricer { + using Math for uint256; + uint256 private constant DECIMALS = 18; + uint256 private constant ONE = (10 ** DECIMALS); + + IPerpetualTranche public immutable SPOT; + + constructor(IPerpetualTranche spot) { + SPOT = spot; + } + + function decimals() external pure returns (uint8) { + return uint8(DECIMALS); + } + + function usdPrice() external pure returns (uint256, bool) { + return (ONE, true); + } + + function perpUsdPrice() external returns (uint256, bool) { + return perpFmvUsdPrice(); + } + + function perpFmvUsdPrice() public returns (uint256, bool) { + (uint256 targetPrice, bool targetPriceValid) = amplTargetUsdPrice(); + return (targetPrice.mulDiv(SPOT.getTVL(), SPOT.totalSupply()), targetPriceValid); + } + + function amplTargetUsdPrice() public pure returns (uint256, bool) { + return (ONE.mulDiv(121, 100), true); + } +} diff --git a/spot-vaults/package.json b/spot-vaults/package.json index 12986136..860a7d79 100644 --- a/spot-vaults/package.json +++ b/spot-vaults/package.json @@ -62,7 +62,7 @@ "ethers": "^6.6.0", "ethers-v5": "npm:ethers@^5.7.0", "ganache-cli": "latest", - "hardhat": "^2.22.18", + "hardhat": "^2.24.1", "hardhat-gas-reporter": "latest", "lodash": "^4.17.21", "prettier": "^2.7.1", diff --git a/spot-vaults/tasks/deploy.ts b/spot-vaults/tasks/deploy.ts index 07ae73d6..f7a1e2b8 100644 --- a/spot-vaults/tasks/deploy.ts +++ b/spot-vaults/tasks/deploy.ts @@ -17,6 +17,36 @@ task("deploy:mocks").setAction(async function (args: TaskArguments, hre) { await cpiOracle.mockData("1200000000000000000", true); }); +task("deploy:MockSpotPricer") + .addParam( + "spot", + "the address of the testnet spot token", + 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 { spot } = args; + + const MockSpotPricer = await hre.ethers.getContractFactory("MockSpotPricer"); + const mockSpotPricer = await MockSpotPricer.deploy(spot); + console.log("spotPricer", mockSpotPricer.target); + + if (args.verify) { + await sleep(30); + await hre.run("verify:contract", { + address: mockSpotPricer.target, + constructorArguments: [spot], + }); + } else { + console.log("Skipping verification"); + } + }); + task("deploy:SpotPricer") .addParam( "wethWamplPool", diff --git a/spot-vaults/tasks/info.ts b/spot-vaults/tasks/info.ts index 9cb18ac4..5d976688 100644 --- a/spot-vaults/tasks/info.ts +++ b/spot-vaults/tasks/info.ts @@ -95,8 +95,8 @@ task("info:BillBroker") const oracle = await hre.ethers.getContractAt( "SpotPricer", - // await billBroker.oracle.staticCall(), - "0x0f8f519878c10ce36C6aAF89c1AeefaaDE5D7881", + await billBroker.oracle.staticCall(), + // "0x0f8f519878c10ce36C6aAF89c1AeefaaDE5D7881", ); const oracleDecimals = await oracle.decimals(); console.log("---------------------------------------------------------------"); @@ -104,7 +104,7 @@ task("info:BillBroker") const usdPriceCall = await oracle.usdPrice.staticCall(); console.log("usdPrice:", pp(usdPriceCall[0], oracleDecimals)); console.log("usdPriceValid:", usdPriceCall[1]); - const perpPriceCall = await oracle.perpUsdPrice.staticCall(); + const perpPriceCall = await oracle.perpFmvUsdPrice.staticCall(); console.log("perpPrice:", pp(perpPriceCall[0], oracleDecimals)); console.log("perpPriceValid:", perpPriceCall[1]); console.log("---------------------------------------------------------------"); @@ -169,12 +169,12 @@ task("info:BillBroker") unitPerp * swapAmt, ), usdDecimals, - ) / parseInt(swapAmt), + ) / parseFloat(swapAmt), `usd per perp`, ); console.log( `~Sell price for ${swapAmt} perp: `, - parseInt(swapAmt) / + parseFloat(swapAmt) / pp( await billBroker["computeUSDToPerpSwapAmt(uint256)"].staticCall( unitUsd * swapAmt, @@ -187,7 +187,6 @@ task("info:BillBroker") console.log("---------------------------------------------------------------"); } catch (e) { console.log(e); - console.log("ReserveState: NA"); console.log("---------------------------------------------------------------"); } }); diff --git a/spot-vaults/tasks/ops.ts b/spot-vaults/tasks/ops.ts index 2533f01d..4283edb4 100644 --- a/spot-vaults/tasks/ops.ts +++ b/spot-vaults/tasks/ops.ts @@ -113,6 +113,122 @@ task("ops:deposit", "Deposits perp and usd tokens to mint bb lp tokens") ); }); +task("ops:depositPerp", "Deposits perp tokens to mint bb lp tokens") + .addParam( + "address", + "the address of the bill broker contract", + undefined, + types.string, + false, + ) + .addParam( + "perpAmount", + "the total amount of usd tokens (in float) to deposit", + undefined, + types.string, + false, + ) + .setAction(async function (args: TaskArguments, hre) { + const signer = (await hre.ethers.getSigners())[0]; + const signerAddress = await signer.getAddress(); + console.log("Signer", signerAddress); + + const { address, perpAmount } = args; + const billBroker = await hre.ethers.getContractAt("BillBroker", address); + const perp = await hre.ethers.getContractAt("ERC20", await billBroker.perp()); + const perpFixedPtAmount = ethers.parseUnits(perpAmount, await perp.decimals()); + + console.log( + "Signer perp balance", + ethers.formatUnits(await perp.balanceOf(signerAddress), await perp.decimals()), + ); + + console.log("---------------------------------------------------------------"); + console.log("Execution:"); + console.log("Approving router to spend tokens:"); + if ((await perp.allowance(signerAddress, billBroker.target)) < perpFixedPtAmount) { + const tx = await perp.connect(signer).approve(billBroker.target, perpFixedPtAmount); + await tx.wait(); + console.log("Tx", tx.hash); + } + + console.log("Deposit:"); + const tx = await billBroker.connect(signer).depositPerp(perpFixedPtAmount, 0); + await tx.wait(); + console.log("Tx", tx.hash); + + console.log( + "Signer lp balance", + ethers.formatUnits( + await billBroker.balanceOf(signerAddress), + await billBroker.decimals(), + ), + ); + console.log( + "Signer perp balance", + ethers.formatUnits(await perp.balanceOf(signerAddress), await perp.decimals()), + ); + }); + +task("ops:depositUSD", "Deposits usd tokens to mint bb lp tokens") + .addParam( + "address", + "the address of the bill broker contract", + undefined, + types.string, + false, + ) + .addParam( + "usdAmount", + "the total amount of usd tokens (in float) to deposit", + undefined, + types.string, + false, + ) + .setAction(async function (args: TaskArguments, hre) { + const signer = (await hre.ethers.getSigners())[0]; + const signerAddress = await signer.getAddress(); + console.log("Signer", signerAddress); + + const { address, usdAmount } = args; + const billBroker = await hre.ethers.getContractAt("BillBroker", address); + const usd = await hre.ethers.getContractAt("ERC20", await billBroker.usd()); + const usdFixedPtAmount = ethers.parseUnits(usdAmount, await usd.decimals()); + + console.log( + "Signer usd balance", + ethers.formatUnits(await usd.balanceOf(signerAddress), await usd.decimals()), + ); + + console.log("---------------------------------------------------------------"); + console.log("Execution:"); + console.log("Approving router to spend tokens:"); + if ((await usd.allowance(signerAddress, billBroker.target)) < usdFixedPtAmount) { + const tx = await usd.connect(signer).approve(billBroker.target, usdFixedPtAmount); + await tx.wait(); + console.log("Tx", tx.hash); + } + + console.log("Deposit:"); + const tx = await billBroker + .connect(signer) + .depositUSD(usdFixedPtAmount, hre.ethers.MaxUint256); + await tx.wait(); + console.log("Tx", tx.hash); + + console.log( + "Signer lp balance", + ethers.formatUnits( + await billBroker.balanceOf(signerAddress), + await billBroker.decimals(), + ), + ); + console.log( + "Signer usd balance", + ethers.formatUnits(await usd.balanceOf(signerAddress), await usd.decimals()), + ); + }); + task("ops:redeem") .addParam( "address", diff --git a/spot-vaults/tasks/scripts/sepolia.sh b/spot-vaults/tasks/scripts/sepolia.sh index c2079221..86ac002e 100644 --- a/spot-vaults/tasks/scripts/sepolia.sh +++ b/spot-vaults/tasks/scripts/sepolia.sh @@ -28,6 +28,14 @@ yarn hardhat --network sepolia ops:deposit \ --perp-amount 1000 \ --usd-amount 1000 +yarn hardhat --network sepolia ops:depositPerp \ + --address "0xc3f6D1F1d253EdC8B34D78Bc6cDD2b3eEFAd76BD" \ + --perp-amount 10 + +yarn hardhat --network sepolia ops:depositUSD \ + --address "0xc3f6D1F1d253EdC8B34D78Bc6cDD2b3eEFAd76BD" \ + --usd-amount 10 + yarn hardhat --network sepolia ops:swapUSDForPerps \ --address "0xc3f6D1F1d253EdC8B34D78Bc6cDD2b3eEFAd76BD" \ --usd-amount 10 diff --git a/spot-vaults/tasks/upgrade.ts b/spot-vaults/tasks/upgrade.ts index d47cdd94..9937088c 100644 --- a/spot-vaults/tasks/upgrade.ts +++ b/spot-vaults/tasks/upgrade.ts @@ -105,10 +105,10 @@ task("upgrade:testnet") await getImplementationAddress(hre.ethers.provider, address), ); - const impl = await hre.upgrades.upgradeProxy(address, Factory, { + await hre.upgrades.upgradeProxy(address, Factory, { unsafeAllowRenames: true, }); - await impl.deployed(); + await sleep(30); const newImpl = await getImplementationAddress(hre.ethers.provider, address); console.log("Updated implementation", newImpl); diff --git a/yarn.lock b/yarn.lock index 9e3dcae1..45fbef16 100644 --- a/yarn.lock +++ b/yarn.lock @@ -157,7 +157,7 @@ __metadata: ethers: ^6.6.0 ethers-v5: "npm:ethers@^5.7.0" ganache-cli: latest - hardhat: ^2.22.18 + hardhat: ^2.24.1 hardhat-gas-reporter: latest lodash: ^4.17.21 prettier: ^2.7.1 @@ -7457,7 +7457,7 @@ __metadata: languageName: node linkType: hard -"hardhat@npm:^2.22.18, hardhat@npm:^2.23.0": +"hardhat@npm:^2.23.0": version: 2.24.0 resolution: "hardhat@npm:2.24.0" dependencies: @@ -7516,6 +7516,65 @@ __metadata: languageName: node linkType: hard +"hardhat@npm:^2.24.1": + version: 2.24.1 + resolution: "hardhat@npm:2.24.1" + dependencies: + "@ethereumjs/util": ^9.1.0 + "@ethersproject/abi": ^5.1.2 + "@nomicfoundation/edr": ^0.11.0 + "@nomicfoundation/solidity-analyzer": ^0.1.0 + "@sentry/node": ^5.18.1 + "@types/bn.js": ^5.1.0 + "@types/lru-cache": ^5.1.0 + adm-zip: ^0.4.16 + aggregate-error: ^3.0.0 + ansi-escapes: ^4.3.0 + boxen: ^5.1.2 + chokidar: ^4.0.0 + ci-info: ^2.0.0 + debug: ^4.1.1 + enquirer: ^2.3.0 + env-paths: ^2.2.0 + ethereum-cryptography: ^1.0.3 + find-up: ^5.0.0 + fp-ts: 1.19.3 + fs-extra: ^7.0.1 + immutable: ^4.0.0-rc.12 + io-ts: 1.10.4 + json-stream-stringify: ^3.1.4 + keccak: ^3.0.2 + lodash: ^4.17.11 + micro-eth-signer: ^0.14.0 + mnemonist: ^0.38.0 + mocha: ^10.0.0 + p-map: ^4.0.0 + picocolors: ^1.1.0 + raw-body: ^2.4.1 + resolve: 1.17.0 + semver: ^6.3.0 + solc: 0.8.26 + source-map-support: ^0.5.13 + stacktrace-parser: ^0.1.10 + tinyglobby: ^0.2.6 + tsort: 0.0.1 + undici: ^5.14.0 + uuid: ^8.3.2 + ws: ^7.4.6 + peerDependencies: + ts-node: "*" + typescript: "*" + peerDependenciesMeta: + ts-node: + optional: true + typescript: + optional: true + bin: + hardhat: internal/cli/bootstrap.js + checksum: 98fa6022a25986343318709e2699c0f1b1c466e68fe6074a6e838ddeddb2cb53ccb9d6f572e809513a30eefa82a00fcad2220c5e2c7f9fad4f1436c9755c01d9 + languageName: node + linkType: hard + "has-bigints@npm:^1.0.2": version: 1.1.0 resolution: "has-bigints@npm:1.1.0" From 819a5d682850fe8edfbb1ee2e6de76e206426d0d Mon Sep 17 00:00:00 2001 From: aalavandhan1984 <6264334+aalavandhan@users.noreply.github.com> Date: Fri, 30 May 2025 13:57:57 -0400 Subject: [PATCH 2/2] updated spot and stampl on testnet --- spot-contracts/.openzeppelin/sepolia.json | 1238 +++++++++++++++++++++ spot-contracts/README.md | 2 +- spot-contracts/tasks/helpers.ts | 4 +- spot-contracts/tasks/ops/perp.ts | 32 +- spot-contracts/tasks/ops/tranche.ts | 22 +- spot-contracts/tasks/ops/vaults.ts | 233 +++- spot-contracts/tasks/scripts/sepolia.sh | 15 +- spot-contracts/tasks/upgrade/index.ts | 48 +- 8 files changed, 1495 insertions(+), 99 deletions(-) diff --git a/spot-contracts/.openzeppelin/sepolia.json b/spot-contracts/.openzeppelin/sepolia.json index 1abd075a..f2127177 100644 --- a/spot-contracts/.openzeppelin/sepolia.json +++ b/spot-contracts/.openzeppelin/sepolia.json @@ -24,6 +24,26 @@ "address": "0x3205ade922457db878039fDbF0e5A88872027A67", "txHash": "0x19de9d6b4d49a8bb03deef871232212e6c696942feb6476c98ad7a8017e0975b", "kind": "transparent" + }, + { + "address": "0x09AF412c5c133116582480cBa853e4d8493a5E6C", + "txHash": "0x24ff7a20ff3f4af25d91b9be7c88824a31f6771347d7002f0bb70e80e72639d0", + "kind": "transparent" + }, + { + "address": "0x2123119898bc0f0AA699aEa0F3f75A25523F845A", + "txHash": "0x33fbbf70adea534a61e9caa3e41aa9e5cb4adcb45e00866ab3b8589633b1166c", + "kind": "transparent" + }, + { + "address": "0x72Ff3c3F205c2AC95234199916Bee97c6b973390", + "txHash": "0x98d81c9042663a9a51a36cc8ab4c4ae1c22e63bf065394fb8c31d2eb05880a8c", + "kind": "transparent" + }, + { + "address": "0xd90FcB328D90B778D1f6719d781045bbbac8F251", + "txHash": "0x8b29769272d41c1032345366209cdcddb8abda7b8c66bfba001162c14671855e", + "kind": "transparent" } ], "impls": { @@ -1477,6 +1497,1224 @@ }, "namespaces": {} } + }, + "27615ac3f0c04782221a0e771a009ef027f8d4639b613c0b87c5311ebbfd6094": { + "address": "0x61F2c060FFe532e0dD9717D8aE06c116f6435C73", + "txHash": "0xc75479d79a82fc90b9208104633506887890566162064d5c05c65d4e0cb3c27b", + "layout": { + "solcVersion": "0.8.20", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_balances", + "offset": 0, + "slot": "51", + "type": "t_mapping(t_address,t_uint256)", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:37" + }, + { + "label": "_allowances", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:39" + }, + { + "label": "_totalSupply", + "offset": 0, + "slot": "53", + "type": "t_uint256", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:41" + }, + { + "label": "_name", + "offset": 0, + "slot": "54", + "type": "t_string_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:43" + }, + { + "label": "_symbol", + "offset": 0, + "slot": "55", + "type": "t_string_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:44" + }, + { + "label": "__gap", + "offset": 0, + "slot": "56", + "type": "t_array(t_uint256)45_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:394" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC20BurnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol:51" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_paused", + "offset": 0, + "slot": "201", + "type": "t_bool", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" + }, + { + "label": "_status", + "offset": 0, + "slot": "251", + "type": "t_uint256", + "contract": "ReentrancyGuardUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" + }, + { + "label": "__gap", + "offset": 0, + "slot": "252", + "type": "t_array(t_uint256)49_storage", + "contract": "ReentrancyGuardUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:74" + }, + { + "label": "_decimals", + "offset": 0, + "slot": "301", + "type": "t_uint8", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:130" + }, + { + "label": "keeper", + "offset": 1, + "slot": "301", + "type": "t_address", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:136" + }, + { + "label": "feePolicy", + "offset": 0, + "slot": "302", + "type": "t_contract(IFeePolicy)10399", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:140" + }, + { + "label": "_pricingStrategy_DEPRECATED", + "offset": 0, + "slot": "303", + "type": "t_address", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:146" + }, + { + "label": "_discountStrategy_DEPRECATED", + "offset": 0, + "slot": "304", + "type": "t_address", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:154" + }, + { + "label": "bondIssuer", + "offset": 0, + "slot": "305", + "type": "t_contract(IBondIssuer)10328", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:158" + }, + { + "label": "_depositBond", + "offset": 0, + "slot": "306", + "type": "t_contract(IBondController)10981", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:161" + }, + { + "label": "minTrancheMaturitySec", + "offset": 0, + "slot": "307", + "type": "t_uint256", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:165" + }, + { + "label": "maxTrancheMaturitySec", + "offset": 0, + "slot": "308", + "type": "t_uint256", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:169" + }, + { + "label": "_matureValueTargetPerc_DEPRECATED", + "offset": 0, + "slot": "309", + "type": "t_uint256", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:177" + }, + { + "label": "maxSupply", + "offset": 0, + "slot": "310", + "type": "t_uint256", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:180" + }, + { + "label": "maxDepositTrancheValuePerc", + "offset": 0, + "slot": "311", + "type": "t_uint256", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:184" + }, + { + "label": "_mintedSupplyPerTranche_DEPRECATED", + "offset": 0, + "slot": "312", + "type": "t_mapping(t_contract(ITranche)10993,t_uint256)", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:190" + }, + { + "label": "_appliedDiscounts_DEPRECATED", + "offset": 0, + "slot": "313", + "type": "t_mapping(t_contract(IERC20Upgradeable)1157,t_uint256)", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:197" + }, + { + "label": "_reserves", + "offset": 0, + "slot": "314", + "type": "t_struct(AddressSet)4620_storage", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:203" + }, + { + "label": "_matureTrancheBalance_DEPRECATED", + "offset": 0, + "slot": "316", + "type": "t_uint256", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:209" + }, + { + "label": "vault", + "offset": 0, + "slot": "317", + "type": "t_contract(IRolloverVault)10733", + "contract": "PerpetualTranche", + "src": "contracts/PerpetualTranche.sol:216" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)45_storage": { + "label": "uint256[45]", + "numberOfBytes": "1440" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IBondController)10981": { + "label": "contract IBondController", + "numberOfBytes": "20" + }, + "t_contract(IBondIssuer)10328": { + "label": "contract IBondIssuer", + "numberOfBytes": "20" + }, + "t_contract(IERC20Upgradeable)1157": { + "label": "contract IERC20Upgradeable", + "numberOfBytes": "20" + }, + "t_contract(IFeePolicy)10399": { + "label": "contract IFeePolicy", + "numberOfBytes": "20" + }, + "t_contract(IRolloverVault)10733": { + "label": "contract IRolloverVault", + "numberOfBytes": "20" + }, + "t_contract(ITranche)10993": { + "label": "contract ITranche", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_uint256)": { + "label": "mapping(address => uint256)", + "numberOfBytes": "32" + }, + "t_mapping(t_bytes32,t_uint256)": { + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32" + }, + "t_mapping(t_contract(IERC20Upgradeable)1157,t_uint256)": { + "label": "mapping(contract IERC20Upgradeable => uint256)", + "numberOfBytes": "32" + }, + "t_mapping(t_contract(ITranche)10993,t_uint256)": { + "label": "mapping(contract ITranche => uint256)", + "numberOfBytes": "32" + }, + "t_string_storage": { + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(AddressSet)4620_storage": { + "label": "struct EnumerableSetUpgradeable.AddressSet", + "members": [ + { + "label": "_inner", + "type": "t_struct(Set)4319_storage", + "offset": 0, + "slot": "0" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)4319_storage": { + "label": "struct EnumerableSetUpgradeable.Set", + "members": [ + { + "label": "_values", + "type": "t_array(t_bytes32)dyn_storage", + "offset": 0, + "slot": "0" + }, + { + "label": "_indexes", + "type": "t_mapping(t_bytes32,t_uint256)", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } + }, + "159ae25d796335c7f57c9a92c60aff87c124d8d64e7601e57473c63a4dceb073": { + "address": "0xe6592Efd4dD102C6bAc426046aB3927d8b2439c5", + "txHash": "0x135945e0ee578dd8c9ca9d28f0dbbfa48b020f44859a3c521632845d4fc56778", + "layout": { + "solcVersion": "0.8.20", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_balances", + "offset": 0, + "slot": "51", + "type": "t_mapping(t_address,t_uint256)", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:37" + }, + { + "label": "_allowances", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:39" + }, + { + "label": "_totalSupply", + "offset": 0, + "slot": "53", + "type": "t_uint256", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:41" + }, + { + "label": "_name", + "offset": 0, + "slot": "54", + "type": "t_string_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:43" + }, + { + "label": "_symbol", + "offset": 0, + "slot": "55", + "type": "t_string_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:44" + }, + { + "label": "__gap", + "offset": 0, + "slot": "56", + "type": "t_array(t_uint256)45_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:394" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC20BurnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol:51" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_paused", + "offset": 0, + "slot": "201", + "type": "t_bool", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" + }, + { + "label": "_status", + "offset": 0, + "slot": "251", + "type": "t_uint256", + "contract": "ReentrancyGuardUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" + }, + { + "label": "__gap", + "offset": 0, + "slot": "252", + "type": "t_array(t_uint256)49_storage", + "contract": "ReentrancyGuardUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:74" + }, + { + "label": "underlying", + "offset": 0, + "slot": "301", + "type": "t_contract(IERC20Upgradeable)1157", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:128" + }, + { + "label": "_deployed", + "offset": 0, + "slot": "302", + "type": "t_struct(AddressSet)4620_storage", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:132" + }, + { + "label": "minDeploymentAmt", + "offset": 0, + "slot": "304", + "type": "t_uint256", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:140" + }, + { + "label": "perp", + "offset": 0, + "slot": "305", + "type": "t_contract(IPerpetualTranche)10645", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:143" + }, + { + "label": "feePolicy", + "offset": 0, + "slot": "306", + "type": "t_contract(IFeePolicy)10399", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:149" + }, + { + "label": "keeper", + "offset": 0, + "slot": "307", + "type": "t_address", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:154" + }, + { + "label": "reservedUnderlyingBal", + "offset": 0, + "slot": "308", + "type": "t_uint256", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:165" + }, + { + "label": "reservedUnderlyingPerc", + "offset": 0, + "slot": "309", + "type": "t_uint256", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:169" + }, + { + "label": "lastRebalanceTimestampSec", + "offset": 0, + "slot": "310", + "type": "t_uint256", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:175" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)45_storage": { + "label": "uint256[45]", + "numberOfBytes": "1440" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IERC20Upgradeable)1157": { + "label": "contract IERC20Upgradeable", + "numberOfBytes": "20" + }, + "t_contract(IFeePolicy)10399": { + "label": "contract IFeePolicy", + "numberOfBytes": "20" + }, + "t_contract(IPerpetualTranche)10645": { + "label": "contract IPerpetualTranche", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_uint256)": { + "label": "mapping(address => uint256)", + "numberOfBytes": "32" + }, + "t_mapping(t_bytes32,t_uint256)": { + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32" + }, + "t_string_storage": { + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(AddressSet)4620_storage": { + "label": "struct EnumerableSetUpgradeable.AddressSet", + "members": [ + { + "label": "_inner", + "type": "t_struct(Set)4319_storage", + "offset": 0, + "slot": "0" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)4319_storage": { + "label": "struct EnumerableSetUpgradeable.Set", + "members": [ + { + "label": "_values", + "type": "t_array(t_bytes32)dyn_storage", + "offset": 0, + "slot": "0" + }, + { + "label": "_indexes", + "type": "t_mapping(t_bytes32,t_uint256)", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } + }, + "93bb1496a286db1e420729869f494bd24f9c548e5c6c54d099ba41c65bdf169a": { + "address": "0x63A5FaFC06963067FD55d9dbFE78c12eE5c09393", + "txHash": "0xff5b7f52f08a5754c9aa0f8099140199fc76770a312e60e6758727691c3b8af0", + "layout": { + "solcVersion": "0.8.20", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_balances", + "offset": 0, + "slot": "51", + "type": "t_mapping(t_address,t_uint256)", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:37" + }, + { + "label": "_allowances", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:39" + }, + { + "label": "_totalSupply", + "offset": 0, + "slot": "53", + "type": "t_uint256", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:41" + }, + { + "label": "_name", + "offset": 0, + "slot": "54", + "type": "t_string_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:43" + }, + { + "label": "_symbol", + "offset": 0, + "slot": "55", + "type": "t_string_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:44" + }, + { + "label": "__gap", + "offset": 0, + "slot": "56", + "type": "t_array(t_uint256)45_storage", + "contract": "ERC20Upgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:394" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC20BurnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol:51" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_paused", + "offset": 0, + "slot": "201", + "type": "t_bool", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" + }, + { + "label": "_status", + "offset": 0, + "slot": "251", + "type": "t_uint256", + "contract": "ReentrancyGuardUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" + }, + { + "label": "__gap", + "offset": 0, + "slot": "252", + "type": "t_array(t_uint256)49_storage", + "contract": "ReentrancyGuardUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:74" + }, + { + "label": "underlying", + "offset": 0, + "slot": "301", + "type": "t_contract(IERC20Upgradeable)1157", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:128" + }, + { + "label": "_deployed", + "offset": 0, + "slot": "302", + "type": "t_struct(AddressSet)4620_storage", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:132" + }, + { + "label": "minDeploymentAmt", + "offset": 0, + "slot": "304", + "type": "t_uint256", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:140" + }, + { + "label": "perp", + "offset": 0, + "slot": "305", + "type": "t_contract(IPerpetualTranche)10645", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:143" + }, + { + "label": "feePolicy", + "offset": 0, + "slot": "306", + "type": "t_contract(IFeePolicy)10399", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:149" + }, + { + "label": "keeper", + "offset": 0, + "slot": "307", + "type": "t_address", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:154" + }, + { + "label": "reservedUnderlyingBal", + "offset": 0, + "slot": "308", + "type": "t_uint256", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:165" + }, + { + "label": "reservedUnderlyingPerc", + "offset": 0, + "slot": "309", + "type": "t_uint256", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:169" + }, + { + "label": "lastRebalanceTimestampSec", + "offset": 0, + "slot": "310", + "type": "t_uint256", + "contract": "RolloverVault", + "src": "contracts/RolloverVault.sol:175" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)45_storage": { + "label": "uint256[45]", + "numberOfBytes": "1440" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IERC20Upgradeable)1157": { + "label": "contract IERC20Upgradeable", + "numberOfBytes": "20" + }, + "t_contract(IFeePolicy)10399": { + "label": "contract IFeePolicy", + "numberOfBytes": "20" + }, + "t_contract(IPerpetualTranche)10645": { + "label": "contract IPerpetualTranche", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_uint256)": { + "label": "mapping(address => uint256)", + "numberOfBytes": "32" + }, + "t_mapping(t_bytes32,t_uint256)": { + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32" + }, + "t_string_storage": { + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(AddressSet)4620_storage": { + "label": "struct EnumerableSetUpgradeable.AddressSet", + "members": [ + { + "label": "_inner", + "type": "t_struct(Set)4319_storage", + "offset": 0, + "slot": "0" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)4319_storage": { + "label": "struct EnumerableSetUpgradeable.Set", + "members": [ + { + "label": "_values", + "type": "t_array(t_bytes32)dyn_storage", + "offset": 0, + "slot": "0" + }, + { + "label": "_indexes", + "type": "t_mapping(t_bytes32,t_uint256)", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } + }, + "1fcc171b5bad80186617af35ff9be783276f937125cee7b0ecef70251af3f553": { + "address": "0xF42789840614C533c88B1789796D5429719017D6", + "txHash": "0xf5c2dded17b38e7ab8289f62b347267411255a0463916b75c645abbdacda6aab", + "layout": { + "solcVersion": "0.8.20", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "targetSystemRatio", + "offset": 0, + "slot": "101", + "type": "t_uint256", + "contract": "FeePolicy", + "src": "contracts/FeePolicy.sol:69" + }, + { + "label": "equilibriumDR", + "offset": 0, + "slot": "102", + "type": "t_struct(Range)3847_storage", + "contract": "FeePolicy", + "src": "contracts/FeePolicy.sol:74" + }, + { + "label": "feeFnDRDown", + "offset": 0, + "slot": "104", + "type": "t_struct(Line)3857_storage", + "contract": "FeePolicy", + "src": "contracts/FeePolicy.sol:80" + }, + { + "label": "feeFnDRUp", + "offset": 0, + "slot": "108", + "type": "t_struct(Line)3857_storage", + "contract": "FeePolicy", + "src": "contracts/FeePolicy.sol:83" + }, + { + "label": "perpDebasementLag", + "offset": 0, + "slot": "112", + "type": "t_uint256", + "contract": "FeePolicy", + "src": "contracts/FeePolicy.sol:89" + }, + { + "label": "perpEnrichmentLag", + "offset": 0, + "slot": "113", + "type": "t_uint256", + "contract": "FeePolicy", + "src": "contracts/FeePolicy.sol:92" + }, + { + "label": "perpDebasementPercLimits", + "offset": 0, + "slot": "114", + "type": "t_struct(Range)3847_storage", + "contract": "FeePolicy", + "src": "contracts/FeePolicy.sol:95" + }, + { + "label": "perpEnrichmentPercLimits", + "offset": 0, + "slot": "116", + "type": "t_struct(Range)3847_storage", + "contract": "FeePolicy", + "src": "contracts/FeePolicy.sol:98" + }, + { + "label": "rebalanceFreqSec", + "offset": 0, + "slot": "118", + "type": "t_uint256", + "contract": "FeePolicy", + "src": "contracts/FeePolicy.sol:101" + }, + { + "label": "protocolSharePerc", + "offset": 0, + "slot": "119", + "type": "t_uint256", + "contract": "FeePolicy", + "src": "contracts/FeePolicy.sol:104" + }, + { + "label": "protocolFeeCollector", + "offset": 0, + "slot": "120", + "type": "t_address", + "contract": "FeePolicy", + "src": "contracts/FeePolicy.sol:107" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_struct(Line)3857_storage": { + "label": "struct Line", + "members": [ + { + "label": "x1", + "type": "t_uint256", + "offset": 0, + "slot": "0" + }, + { + "label": "y1", + "type": "t_uint256", + "offset": 0, + "slot": "1" + }, + { + "label": "x2", + "type": "t_uint256", + "offset": 0, + "slot": "2" + }, + { + "label": "y2", + "type": "t_uint256", + "offset": 0, + "slot": "3" + } + ], + "numberOfBytes": "128" + }, + "t_struct(Range)3847_storage": { + "label": "struct Range", + "members": [ + { + "label": "lower", + "type": "t_uint256", + "offset": 0, + "slot": "0" + }, + { + "label": "upper", + "type": "t_uint256", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } } } } diff --git a/spot-contracts/README.md b/spot-contracts/README.md index dc7845f7..3ca2370a 100644 --- a/spot-contracts/README.md +++ b/spot-contracts/README.md @@ -32,7 +32,7 @@ There is a testnet deployment on Sepolia. - Bond issuer: [0x3838C8d4D092d40Cb27DD22Dafc6E1A81ea2DB60](https://sepolia.etherscan.io//address/0x3838C8d4D092d40Cb27DD22Dafc6E1A81ea2DB60) - Router: [0xE5b53ee8182086790C1ab79cbf801F0c5EE241BF](https://sepolia.etherscan.io//address/0xE5b53ee8182086790C1ab79cbf801F0c5EE241BF) - RolloverVault: [0x107614c6602A8e602952Da107B8fE62b5Ab13b04](https://sepolia.etherscan.io//address/0x107614c6602A8e602952Da107B8fE62b5Ab13b04) -- FeePolicy: [0x2DdF288F26490D1147296cC0FA2B3c4da5E15f10](https://sepolia.etherscan.io//address/0x2DdF288F26490D1147296cC0FA2B3c4da5E15f10) +- FeePolicy: [0xd90FcB328D90B778D1f6719d781045bbbac8F251](https://sepolia.etherscan.io//address/0xd90FcB328D90B778D1f6719d781045bbbac8F251) ## Contribute diff --git a/spot-contracts/tasks/helpers.ts b/spot-contracts/tasks/helpers.ts index 793cb9b0..4599b10b 100644 --- a/spot-contracts/tasks/helpers.ts +++ b/spot-contracts/tasks/helpers.ts @@ -9,9 +9,7 @@ export async function getContractFactoryFromExternalArtifacts(ethers: any, name: return ethers.getContractFactoryFromArtifact(artifact); } -export async function sleep(sleepSec: number) { - await new Promise(resolve => setTimeout(resolve, sleepSec)); -} +export const sleep = seconds => new Promise(resolve => setTimeout(resolve, seconds * 1000)); interface ContractInput { internalType: string; diff --git a/spot-contracts/tasks/ops/perp.ts b/spot-contracts/tasks/ops/perp.ts index f9a85970..249f4215 100644 --- a/spot-contracts/tasks/ops/perp.ts +++ b/spot-contracts/tasks/ops/perp.ts @@ -28,7 +28,7 @@ task("ops:perp:info") console.log("BondIssuer:", bondIssuer.target); console.log("bondFactory:", await bondIssuer.bondFactory()); console.log("collateral:", await bondIssuer.collateral()); - console.log("issuedCount:", hre.ethers.formatUnits(await bondIssuer.issuedCount()), 0); + console.log("issuedCount:", hre.ethers.formatUnits(await bondIssuer.issuedCount(), 0)); console.log("maxMaturityDuration:", hre.ethers.formatUnits(await bondIssuer.maxMaturityDuration(), 0)); console.log("minIssueTimeIntervalSec:", hre.ethers.formatUnits(await bondIssuer.minIssueTimeIntervalSec(), 0)); console.log("issueWindowOffsetSec:", hre.ethers.formatUnits(await bondIssuer.issueWindowOffsetSec(), 0)); @@ -47,13 +47,6 @@ task("ops:perp:info") console.log("---------------------------------------------------------------"); console.log("feePolicy:", feePolicy.target); console.log("owner", await feePolicy.owner()); - console.log("perpMintFeePerc:", hre.ethers.formatUnits(await feePolicy.perpMintFeePerc(), percDecimals)); - console.log("perpBurnFeePerc:", hre.ethers.formatUnits(await feePolicy.perpBurnFeePerc(), percDecimals)); - const r = await feePolicy.perpRolloverFee(); - console.log("minRolloverFeePerc:", hre.ethers.formatUnits(r.minRolloverFeePerc, percDecimals)); - console.log("perpDebasementSlope:", hre.ethers.formatUnits(r.perpDebasementSlope, percDecimals)); - console.log("perpEnrichmentSlope:", hre.ethers.formatUnits(r.perpEnrichmentSlope, percDecimals)); - console.log("---------------------------------------------------------------"); console.log("PerpetualTranche:", perp.target); console.log("proxyAdmin:", proxyAdminAddress); @@ -84,7 +77,7 @@ task("ops:perp:info") const tokenAddress = await perp.getReserveAt.staticCall(i); const balance = await perp.getReserveTokenBalance.staticCall(tokenAddress); const value = await perp.getReserveTokenValue.staticCall(tokenAddress); - const price = balance > 0n ? (value * balance * 1000) / 10n ** perpDecimals / 10n ** percDecimals : 0n; + const price = balance > 0n ? (value * 1000n) / balance : 0n; data.push({ token: tokenAddress, balance: hre.ethers.formatUnits(balance, await perp.decimals()), @@ -213,7 +206,7 @@ task("ops:perp:trancheAndDeposit") console.log("Preview mint:", collateralAmount); const totalMintAmt = await perp.computeMintAmt.staticCall(depositTranches[0].token, depositTranches[0].amount); console.log("mintAmt", hre.ethers.formatUnits(totalMintAmt, await perp.decimals())); - if (totalMintAmt.eq("0")) { + if (totalMintAmt <= 0n) { throw Error("No perp minted"); } @@ -225,7 +218,7 @@ task("ops:perp:trancheAndDeposit") console.log("Approving router to spend tokens:"); const allowance = await collateralToken.allowance(signerAddress, router.target); - if (allowance.lt(fixedPtCollateralAmount)) { + if (allowance < fixedPtCollateralAmount) { const tx1 = await collateralToken.connect(signer).approve(router.target, fixedPtCollateralAmount); await tx1.wait(); console.log("Tx", tx1.hash); @@ -243,13 +236,11 @@ task("ops:perp:trancheAndDeposit") task("ops:perp:redeem") .addParam("perpAddress", "the address of the perp contract", undefined, types.string, false) - .addParam("routerAddress", "the address of the router contract", undefined, types.string, false) .addParam("amount", "the total amount of perp tokens (in float) to redeem", undefined, types.string, false) .addParam("fromIdx", "the index of sender", 0, types.int) .setAction(async function (args: TaskArguments, hre) { - const { perpAddress, routerAddress, amount } = args; + const { perpAddress, amount } = args; - const router = await hre.ethers.getContractAt("RouterV2", routerAddress); const perp = await hre.ethers.getContractAt("PerpetualTranche", perpAddress); const fixedPtAmount = hre.ethers.parseUnits(amount, await perp.decimals()); @@ -272,17 +263,10 @@ task("ops:perp:redeem") const signerAddress = await signer.getAddress(); console.log("Signer", signerAddress); - console.log("Approving router to spend tokens:"); - if ((await perp.allowance(signerAddress, router.target)).lt(fixedPtAmount)) { - const tx1 = await perp.connect(signer).approve(router.target, fixedPtAmount); - await tx1.wait(); - console.log("Tx", tx1.hash); - } - console.log("Redeem:"); - const tx2 = await perp.connect(signer).redeem(fixedPtAmount); - await tx2.wait(); - console.log("Tx", tx2.hash); + const tx = await perp.connect(signer).redeem(fixedPtAmount); + await tx.wait(); + console.log("Tx", tx.hash); console.log("Signer balance", hre.ethers.formatUnits(await perp.balanceOf(signerAddress), await perp.decimals())); }); diff --git a/spot-contracts/tasks/ops/tranche.ts b/spot-contracts/tasks/ops/tranche.ts index 0db1d67f..121d03ef 100644 --- a/spot-contracts/tasks/ops/tranche.ts +++ b/spot-contracts/tasks/ops/tranche.ts @@ -1,7 +1,7 @@ import fs from "fs"; import { task, types } from "hardhat/config"; import { TaskArguments, HardhatRuntimeEnvironment } from "hardhat/types"; -import { constants, Contract, BigNumber, Signer } from "ethers"; +import { Contract, BigNumber, Signer, MaxUint256 } from "ethers"; import { generateGnosisSafeBatchFile, ProposedTransaction } from "../helpers"; async function matureBond(bond: Contract, signer: Signer) { @@ -38,17 +38,17 @@ function computeProportionalBalances(balances: BigNumber[], ratios: BigNumber[]) } const redeemableAmts: BigNumber[] = []; - let min = BigNumber.from(constants.MaxUint256); - for (let i = 0; i < balances.length && min.gt("0"); i++) { - const b = balances[i].sub(balances[i].mod(ratios[i])); - const d = b.mul("1000").div(ratios[i]); - if (d.lt(min)) { + let min = MaxUint256; + for (let i = 0; i < balances.length && min > 0n; i++) { + const b = balances[i] - (balances[i] % ratios[i]); + const d = (b * 1000n) / ratios[i]; + if (d < min) { min = d; } } for (let i = 0; i < balances.length; i++) { - redeemableAmts[i] = ratios[i].mul(min).div("1000"); + redeemableAmts[i] = (ratios[i] * min) / 1000n; } return redeemableAmts; } @@ -102,7 +102,7 @@ task("ops:redeemTranches") if (isMature) { for (let j = 0; j < bt.length; j++) { const b = await bt[j][0].balanceOf(signerAddress); - if (b.gt(0)) { + if (b > 0n) { console.log("Redeeming mature tranche", bt[j][0].target); const tx = await bond.connect(signer).redeemMature(bt[j][0].target, b); await tx.wait(); @@ -111,7 +111,7 @@ task("ops:redeemTranches") } } else { const redemptionAmounts = await computeRedeemableTrancheAmounts(bt, signerAddress); - if (redemptionAmounts[0].gt("0")) { + if (redemptionAmounts[0] > 0n) { console.log( "Redeeming immature bond", redemptionAmounts.map(a => a.toString()), @@ -144,7 +144,7 @@ task("ops:preview_tx:redeemTranches") if (isMature) { for (let j = 0; j < bt.length; j++) { const b = await bt[j][0].balanceOf(walletAddress); - if (b.gt(0)) { + if (b > 0n) { txs.push({ contract: bond, method: "redeemMature", @@ -154,7 +154,7 @@ task("ops:preview_tx:redeemTranches") } } else { const redemptionAmounts = await computeRedeemableTrancheAmounts(bt, walletAddress); - if (redemptionAmounts[0].gt("0")) { + if (redemptionAmounts[0] > 0n) { txs.push({ contract: bond, method: "redeem", diff --git a/spot-contracts/tasks/ops/vaults.ts b/spot-contracts/tasks/ops/vaults.ts index 4c547e8b..181b6567 100644 --- a/spot-contracts/tasks/ops/vaults.ts +++ b/spot-contracts/tasks/ops/vaults.ts @@ -30,6 +30,7 @@ task("ops:vault:info") console.log("RolloverVault:", vault.target); console.log("proxyAdmin:", proxyAdminAddress); console.log("implementation:", implAddress); + console.log("feePolicy:", feePolicy.target); console.log("owner:", await vault.owner()); console.log("paused:", await vault.paused()); console.log("perp:", perp.target); @@ -77,43 +78,23 @@ task("ops:vault:info") const vaultTVL = await vault.getTVL.staticCall(); const seniorTR = await perp.getDepositTrancheRatio.staticCall(); const juniorTR = 1000n - seniorTR; - const subscriptionRatio = (vaultTVL * seniorTR * feeOne) / perpTVL / juniorTR; - const targetSubscriptionRatio = await feePolicy.targetSubscriptionRatio(); - const expectedVaultTVL = (targetSubscriptionRatio * perpTVL * juniorTR) / seniorTR / feeOne; - const deviationRatio = await feePolicy["computeDeviationRatio((uint256,uint256))"]([perpTVL, vaultTVL, seniorTR]); + const systemRatio = (vaultTVL * feeOne) / perpTVL; + const targetSystemRatio = await feePolicy.targetSystemRatio(); + const expectedVaultTVL = (targetSystemRatio * perpTVL) / feeOne; + const deviationRatio = await feePolicy["computeDeviationRatio((uint256,uint256))"]([perpTVL, vaultTVL]); console.log("perpTVL:", hre.ethers.formatUnits(perpTVL, underlyingDecimals)); console.log("vaultTVL:", hre.ethers.formatUnits(vaultTVL, underlyingDecimals)); console.log("expectedVaultTVL:", hre.ethers.formatUnits(expectedVaultTVL, underlyingDecimals)); console.log("seniorTR:", hre.ethers.formatUnits(seniorTR, 3)); console.log("juniorTR:", hre.ethers.formatUnits(juniorTR, 3)); - console.log("subscriptionRatio:", hre.ethers.formatUnits(subscriptionRatio, feeDecimals)); - console.log("targetSubscriptionRatio:", hre.ethers.formatUnits(targetSubscriptionRatio, feeDecimals)); + console.log("systemRatio:", hre.ethers.formatUnits(systemRatio, feeDecimals)); + console.log("targetSystemRatio:", hre.ethers.formatUnits(targetSystemRatio, feeDecimals)); console.log("targetDeviationRatio:", hre.ethers.formatUnits(feeOne, feeDecimals)); - - const drHardBound = await feePolicy.drHardBound(); - console.log("deviationRatioBoundLower:", hre.ethers.formatUnits(drHardBound.lower, feeDecimals)); - console.log("deviationRatioBoundUpper:", hre.ethers.formatUnits(drHardBound.upper, feeDecimals)); console.log("deviationRatio:", hre.ethers.formatUnits(deviationRatio, feeDecimals)); console.log("---------------------------------------------------------------"); console.log("feePolicy:", feePolicy.target); console.log("owner", await feePolicy.owner()); - console.log("computeVaultMintFeePerc:", hre.ethers.formatUnits(await feePolicy.computeVaultMintFeePerc(), 8)); - console.log("computeVaultBurnFeePerc:", hre.ethers.formatUnits(await feePolicy.computeVaultBurnFeePerc(), 8)); - console.log( - "computeUnderlyingToPerpVaultSwapFeePerc:", - hre.ethers.formatUnits( - await feePolicy.computeUnderlyingToPerpVaultSwapFeePerc(deviationRatio, deviationRatio), - 8, - ), - ); - console.log( - "computePerpToUnderlyingVaultSwapFeePerc:", - hre.ethers.formatUnits( - await feePolicy.computePerpToUnderlyingVaultSwapFeePerc(deviationRatio, deviationRatio), - 8, - ), - ); console.log("---------------------------------------------------------------"); console.log("Swap slippage"); try { @@ -168,8 +149,9 @@ task("ops:vault:deposit") console.log("---------------------------------------------------------------"); console.log("Execution:"); - console.log("Approving router to spend tokens:"); - if ((await underlying.allowance(signerAddress, vault.target)).lt(fixedPtAmount)) { + console.log("Approving vault to spend tokens:"); + const allowance = await underlying.allowance(signerAddress, vault.target); + if (allowance < fixedPtAmount) { const tx1 = await underlying.connect(signer).approve(vault.target, fixedPtAmount); await tx1.wait(); console.log("Tx", tx1.hash); @@ -235,6 +217,170 @@ task("ops:vault:redeem") ); }); +task("ops:vault:mint2") + .addParam("vaultAddress", "the address of the vault contract", undefined, types.string, false) + .addParam( + "underlyingAmount", + "the total amount of underlying tokens (in float) to deposit", + undefined, + types.string, + false, + ) + .addParam("fromIdx", "the index of sender", 0, types.int) + .setAction(async function (args: TaskArguments, hre) { + const { vaultAddress, underlyingAmount } = args; + + const vault = await hre.ethers.getContractAt("RolloverVault", vaultAddress); + const perp = await hre.ethers.getContractAt("PerpetualTranche", await vault.perp()); + const underlying = await hre.ethers.getContractAt("MockERC20", await vault.underlying()); + const fixedPtAmount = hre.ethers.parseUnits(underlyingAmount, await underlying.decimals()); + + const signer = (await hre.ethers.getSigners())[args.fromIdx]; + const signerAddress = await signer.getAddress(); + console.log("Signer", signerAddress); + + console.log( + "Signer perp balance", + hre.ethers.formatUnits(await perp.balanceOf(signerAddress), await perp.decimals()), + ); + console.log( + "Signer note balance", + hre.ethers.formatUnits(await vault.balanceOf(signerAddress), await vault.decimals()), + ); + console.log( + "Signer underlying balance", + hre.ethers.formatUnits(await underlying.balanceOf(signerAddress), await underlying.decimals()), + ); + + console.log("---------------------------------------------------------------"); + console.log("Execution:"); + console.log("Approving vault to spend tokens:"); + const allowance = await underlying.allowance(signerAddress, vault.target); + if (allowance < fixedPtAmount) { + const tx1 = await underlying.connect(signer).approve(vault.target, fixedPtAmount); + await tx1.wait(); + console.log("Tx", tx1.hash); + } + + console.log("Mint2:"); + const tx3 = await vault.connect(signer).mint2(fixedPtAmount); + await tx3.wait(); + console.log("Tx", tx3.hash); + + console.log( + "Signer perp balance", + hre.ethers.formatUnits(await perp.balanceOf(signerAddress), await perp.decimals()), + ); + console.log( + "Signer note balance", + hre.ethers.formatUnits(await vault.balanceOf(signerAddress), await vault.decimals()), + ); + console.log( + "Signer underlying balance", + hre.ethers.formatUnits(await underlying.balanceOf(signerAddress), await underlying.decimals()), + ); + }); + +task("ops:vault:redeem2") + .addParam("vaultAddress", "the address of the vault contract", undefined, types.string, false) + .addParam("perpAmount", "the total amount of perp tokens (in float) to redeem", undefined, types.string, false) + .addParam("noteAmount", "the total amount of vault notes (in float) to redeem", undefined, types.string, false) + .addParam("fromIdx", "the index of sender", 0, types.int) + .setAction(async function (args: TaskArguments, hre) { + const { vaultAddress, perpAmount, noteAmount } = args; + + const vault = await hre.ethers.getContractAt("RolloverVault", vaultAddress); + const perp = await hre.ethers.getContractAt("PerpetualTranche", await vault.perp()); + const underlying = await hre.ethers.getContractAt("MockERC20", await vault.underlying()); + const underlyingDecimals = await underlying.decimals(); + const fixedPtPerpAmount = hre.ethers.parseUnits(perpAmount, await perp.decimals()); + const fixedPtNoteAmount = hre.ethers.parseUnits(noteAmount, await vault.decimals()); + + const signer = (await hre.ethers.getSigners())[args.fromIdx]; + const signerAddress = await signer.getAddress(); + console.log("Signer", signerAddress); + console.log( + "Signer perp balance", + hre.ethers.formatUnits(await perp.balanceOf(signerAddress), await perp.decimals()), + ); + console.log( + "Signer note balance", + hre.ethers.formatUnits(await vault.balanceOf(signerAddress), await vault.decimals()), + ); + console.log( + "Signer underlying balance", + hre.ethers.formatUnits(await underlying.balanceOf(signerAddress), await underlying.decimals()), + ); + + console.log("---------------------------------------------------------------"); + console.log("Approving vault to spend perp tokens:", perpAmount); + const allowance = await perp.allowance(signerAddress, vault.target); + if (allowance < fixedPtPerpAmount) { + const tx = await perp.connect(signer).approve(vault.target, fixedPtPerpAmount); + await tx.wait(); + console.log("Tx", tx.hash); + } + + console.log("---------------------------------------------------------------"); + console.log("Preview redeem:", perpAmount, noteAmount); + const redemptions = await vault.redeem2.staticCall(fixedPtPerpAmount, fixedPtNoteAmount); + console.log( + "Redeeming:", + hre.ethers.formatUnits(redemptions[0], await perp.decimals()), + hre.ethers.formatUnits(redemptions[1], await vault.decimals()), + ); + const redemptionData = []; + for (let i = 0; i < redemptions[2].length; i++) { + const token = await hre.ethers.getContractAt("MockERC20", redemptions[2][i].token); + redemptionData.push({ + asset: await token.symbol(), + amount: hre.ethers.formatUnits(redemptions[2][i].amount, underlyingDecimals), + }); + } + console.table(redemptionData); + + console.log("---------------------------------------------------------------"); + console.log("Execution:"); + console.log("Redeem:"); + const tx = await vault.connect(signer).redeem2(fixedPtPerpAmount, fixedPtNoteAmount); + await tx.wait(); + console.log("Tx", tx.hash); + + console.log("---------------------------------------------------------------"); + console.log( + "Signer perp balance", + hre.ethers.formatUnits(await perp.balanceOf(signerAddress), await perp.decimals()), + ); + console.log( + "Signer note balance", + hre.ethers.formatUnits(await vault.balanceOf(signerAddress), await vault.decimals()), + ); + console.log( + "Signer underlying balance", + hre.ethers.formatUnits(await underlying.balanceOf(signerAddress), await underlying.decimals()), + ); + }); + +task("ops:vault:rebalance") + .addParam("vaultAddress", "the address of the vault contract", undefined, types.string, false) + .addParam("fromIdx", "the index of sender", 0, types.int) + .setAction(async function (args: TaskArguments, hre) { + const { vaultAddress } = args; + + const vault = await hre.ethers.getContractAt("RolloverVault", vaultAddress); + + console.log("---------------------------------------------------------------"); + console.log("Execution:"); + const signer = (await hre.ethers.getSigners())[args.fromIdx]; + const signerAddress = await signer.getAddress(); + console.log("Signer", signerAddress); + + console.log("rebalance:"); + const tx = await vault.connect(signer).rebalance(); + await tx.wait(); + console.log("Tx", tx.hash); + }); + task("ops:vault:recoverAndRedeploy") .addParam("vaultAddress", "the address of the vault contract", undefined, types.string, false) .addParam("fromIdx", "the index of sender", 0, types.int) @@ -295,27 +441,6 @@ task("ops:vault:recover") console.log("Tx", tx.hash); }); -task("ops:fee:setSwapFees", "Updates swap fees in fee policy") - .addParam("address", "the fee policy contract", undefined, types.string, false) - .addParam("feePerc", "the percentage to be set as the swap fee", undefined, types.string, false) - .setAction(async function (args: TaskArguments, hre) { - const { address, feePerc } = args; - const signer = (await hre.ethers.getSigners())[0]; - const signerAddress = await signer.getAddress(); - console.log("Signer", signerAddress); - const feePolicy = await hre.ethers.getContractAt("FeePolicy", address); - console.log(`Updating both swap fees to ${feePerc}`); - const feeAmtFixedPt = hre.ethers.parseUnits(feePerc, await feePolicy.decimals()); - - const tx1 = await feePolicy.updateVaultUnderlyingToPerpSwapFeePerc(feeAmtFixedPt); - console.log(tx1.hash); - await tx1.wait(); - - const tx2 = await feePolicy.updateVaultPerpToUnderlyingSwapFeePerc(feeAmtFixedPt); - console.log(tx2.hash); - await tx2.wait(); - }); - task("ops:vault:swapUnderlyingForPerps") .addParam("vaultAddress", "the address of the vault contract", undefined, types.string, false) .addParam( @@ -349,8 +474,9 @@ task("ops:vault:swapUnderlyingForPerps") console.log("---------------------------------------------------------------"); console.log("Execution:"); - console.log("Approving router to spend tokens:"); - if ((await underlying.allowance(signerAddress, vault.target)).lt(fixedPtAmount)) { + console.log("Approving vault to spend tokens:"); + const allowance = await underlying.allowance(signerAddress, vault.target); + if (allowance < fixedPtAmount) { const tx1 = await underlying.connect(signer).approve(vault.target, fixedPtAmount); await tx1.wait(); console.log("Tx", tx1.hash); @@ -398,8 +524,9 @@ task("ops:vault:swapPerpsForUnderlying") console.log("---------------------------------------------------------------"); console.log("Execution:"); - console.log("Approving router to spend tokens:"); - if ((await perp.allowance(signerAddress, vault.target)).lt(fixedPtAmount)) { + console.log("Approving vault to spend tokens:"); + const allowance = await perp.allowance(signerAddress, vault.target); + if (allowance < fixedPtAmount) { const tx1 = await perp.connect(signer).approve(vault.target, fixedPtAmount); await tx1.wait(); console.log("Tx", tx1.hash); diff --git a/spot-contracts/tasks/scripts/sepolia.sh b/spot-contracts/tasks/scripts/sepolia.sh index 97f54a10..0b34d34d 100644 --- a/spot-contracts/tasks/scripts/sepolia.sh +++ b/spot-contracts/tasks/scripts/sepolia.sh @@ -29,15 +29,13 @@ yarn hardhat --network sepolia ops:perp:updateTolerableTrancheMaturity \ --minimum 600 \ --maximum 3600 -yarn hardhat --network sepolia ops:fee:setSwapFees \ - --address "0x2DdF288F26490D1147296cC0FA2B3c4da5E15f10" \ - --fee-perc "0.05" - ######################################################################## ## OPS yarn hardhat --network sepolia ops:perp:info 0xdcCef9065876fD654bAddeBAa778FDA43E0bfC1F yarn hardhat --network sepolia ops:vault:info 0x107614c6602A8e602952Da107B8fE62b5Ab13b04 yarn hardhat --network sepolia ops:perp:updateState 0xdcCef9065876fD654bAddeBAa778FDA43E0bfC1F +yarn hardhat --network sepolia ops:vault:rebalance \ + --vault-address 0x107614c6602A8e602952Da107B8fE62b5Ab13b04 yarn hardhat --network sepolia ops:vault:recoverAndRedeploy \ --vault-address 0x107614c6602A8e602952Da107B8fE62b5Ab13b04 yarn hardhat --network sepolia ops:vault:deploy \ @@ -56,7 +54,6 @@ yarn hardhat --network sepolia ops:perp:trancheAndDeposit \ --collateral-amount 250 yarn hardhat --network sepolia ops:perp:redeem \ - --router-address 0x5B59915E5754C62C40Ba5e7467382ced958F8559 \ --perp-address 0xdcCef9065876fD654bAddeBAa778FDA43E0bfC1F \ --amount 10 @@ -69,6 +66,14 @@ yarn hardhat --network sepolia ops:vault:redeem \ --vault-address 0x107614c6602A8e602952Da107B8fE62b5Ab13b04 \ --amount "0.001" +yarn hardhat --network sepolia ops:vault:mint2 \ + --vault-address 0x107614c6602A8e602952Da107B8fE62b5Ab13b04 \ + --underlying-amount 250 + +yarn hardhat --network sepolia ops:vault:redeem2 \ + --vault-address 0x107614c6602A8e602952Da107B8fE62b5Ab13b04 \ + --perp-amount 250 --note-amount 1 + yarn hardhat --network sepolia ops:vault:swapUnderlyingForPerps \ --vault-address 0x107614c6602A8e602952Da107B8fE62b5Ab13b04 \ --underlying-amount 10 diff --git a/spot-contracts/tasks/upgrade/index.ts b/spot-contracts/tasks/upgrade/index.ts index 88d7ac4f..34b717bd 100644 --- a/spot-contracts/tasks/upgrade/index.ts +++ b/spot-contracts/tasks/upgrade/index.ts @@ -66,10 +66,10 @@ task("upgrade:testnet") console.log("Proxy", address); console.log("Current implementation", await getImplementationAddress(hre.ethers.provider, address)); - const impl = await hre.upgrades.upgradeProxy(address, Factory, { + await hre.upgrades.upgradeProxy(address, Factory, { unsafeAllowRenames: true, }); - await impl.deployed(); + await sleep(30); const newImpl = await getImplementationAddress(hre.ethers.provider, address); console.log("Updated implementation", newImpl); @@ -78,3 +78,47 @@ task("upgrade:testnet") address: newImpl, }); }); + +task("upgrade:testnet:RolloverVault") + .addPositionalParam("address", "the address of the deployed proxy contract", undefined, types.string, false) + .addParam("trancheManagerAddress", "the address of the linked tranche manager", "0x", types.string) + .addParam("fromIdx", "the index of sender", 0, types.int) + .setAction(async function (args: TaskArguments, hre) { + const signer = (await hre.ethers.getSigners())[args.fromIdx]; + const signerAddress = await signer.getAddress(); + console.log("Signer", signerAddress); + + let trancheManagerAddress = args.trancheManagerAddress; + if (trancheManagerAddress === "0x") { + const TrancheManager = await hre.ethers.getContractFactory("TrancheManager"); + const trancheManager = await TrancheManager.deploy(); + trancheManagerAddress = trancheManager.target; + console.log("Deploying linked library TrancheManager", trancheManagerAddress); + } + const Factory = await hre.ethers.getContractFactory("RolloverVault", { + libraries: { + TrancheManager: trancheManagerAddress, + }, + }); + + const { address } = args; + console.log("Proxy", address); + console.log("Current implementation", await getImplementationAddress(hre.ethers.provider, address)); + + await hre.upgrades.upgradeProxy(address, Factory, { + unsafeAllowRenames: true, + unsafeAllowLinkedLibraries: true, + }); + await sleep(30); + const newImpl = await getImplementationAddress(hre.ethers.provider, address); + console.log("Updated implementation", newImpl); + + await sleep(30); + await hre.run("verify:contract", { + address: trancheManagerAddress, + }); + await sleep(30); + await hre.run("verify:contract", { + address: newImpl, + }); + });