diff --git a/scripts/addresses/1-tmp-assets-collateral.json b/scripts/addresses/1-tmp-assets-collateral.json index 7a276f5fb..32d89934a 100644 --- a/scripts/addresses/1-tmp-assets-collateral.json +++ b/scripts/addresses/1-tmp-assets-collateral.json @@ -60,7 +60,8 @@ "cvxCrvUSDUSDT": "0x69c6597690B8Df61D15F201519C03725bdec40c1", "sfrxETH": "0x4c891fCa6319d492866672E3D2AfdAAA5bDcfF67", "apxETH": "0x05ffDaAA2aF48e1De1CE34d633db018a28e3B3F5", - "sUSDe": "0x35081Ca24319835e5f759163F7e75eaB753e0b7E" + "sUSDe": "0x35081Ca24319835e5f759163F7e75eaB753e0b7E", + "pyUSD": "0xa5cde4fB1132daF8f4a0D3140859271208d944E9" }, "erc20s": { "stkAAVE": "0x4da27a545c0c5B758a6BA100e3a049001de870f5", @@ -121,6 +122,7 @@ "CRV": "0xD533a949740bb3306d119CC777fa900bA034cd52", "CVX": "0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B", "apxETH": "0x9Ba021B0a9b958B5E75cE9f6dff97C7eE52cb3E6", - "sUSDe": "0x9D39A5DE30e57443BfF2A8307A4256c8797A3497" + "sUSDe": "0x9D39A5DE30e57443BfF2A8307A4256c8797A3497", + "pyUSD": "0x6c3ea9036406852006290770bedfcaba0e23a0e8" } } diff --git a/scripts/deploy.ts b/scripts/deploy.ts index 545df26cb..fa2a1988f 100644 --- a/scripts/deploy.ts +++ b/scripts/deploy.ts @@ -88,7 +88,8 @@ async function main() { 'phase2-assets/collaterals/deploy_apxeth.ts', 'phase2-assets/collaterals/deploy_USDe.ts', 'phase2-assets/assets/deploy_crv.ts', - 'phase2-assets/assets/deploy_cvx.ts' + 'phase2-assets/assets/deploy_cvx.ts', + 'phase2-assets/collaterals/deploy_pyusd.ts' ) } else if (chainId == '8453' || chainId == '84531') { // Base L2 chains diff --git a/scripts/deployment/phase2-assets/collaterals/deploy_pyusd.ts b/scripts/deployment/phase2-assets/collaterals/deploy_pyusd.ts new file mode 100644 index 000000000..d4de0c91f --- /dev/null +++ b/scripts/deployment/phase2-assets/collaterals/deploy_pyusd.ts @@ -0,0 +1,85 @@ +import fs from 'fs' +import hre, { ethers } from 'hardhat' +import { getChainId } from '../../../../common/blockchain-utils' +import { arbitrumL2Chains, baseL2Chains, networkConfig } from '../../../../common/configuration' +import { bn, fp } from '../../../../common/numbers' +import { + getDeploymentFile, + getDeploymentFilename, + getAssetCollDeploymentFilename, + IAssetCollDeployments, + fileExists, +} from '../../../deployment/common' +import { priceTimeout } from '../../../deployment/utils' +import { Asset, ICollateral } from '../../../../typechain' +import { + PYUSD_MAX_TRADE_VOLUME, + PYUSD_ORACLE_ERROR, + PYUSD_ORACLE_TIMEOUT, +} from '#/test/plugins/individual-collateral/aave-v3/constants' +import { CollateralStatus } from '#/common/constants' +import { expect } from 'chai' + +async function main() { + // ==== Read Configuration ==== + const [burner] = await hre.ethers.getSigners() + const chainId = await getChainId(hre) + + console.log(`Deploying pyUSD asset to network ${hre.network.name} (${chainId}) + with burner account: ${burner.address}`) + + if (!networkConfig[chainId]) { + throw new Error(`Missing network configuration for ${hre.network.name}`) + } + + // Only exists on Mainnet + if (baseL2Chains.includes(hre.network.name) || arbitrumL2Chains.includes(hre.network.name)) { + throw new Error(`Invalid network ${hre.network.name} - only available on Mainnet`) + } + + // Get phase1 deployment + const phase1File = getDeploymentFilename(chainId) + if (!fileExists(phase1File)) { + throw new Error(`${phase1File} doesn't exist yet. Run phase 1`) + } + // Check previous step completed + const assetCollDeploymentFilename = getAssetCollDeploymentFilename(chainId) + const assetCollDeployments = getDeploymentFile(assetCollDeploymentFilename) + + const deployedCollateral: string[] = [] + + let collateral: ICollateral + + /******** Deploy pyUSD asset **************************/ + const { collateral: pyUsdCollateral } = await hre.run('deploy-fiat-collateral', { + priceTimeout: priceTimeout.toString(), + priceFeed: networkConfig[chainId].chainlinkFeeds.pyUSD, + oracleError: PYUSD_ORACLE_ERROR.toString(), + tokenAddress: networkConfig[chainId].tokens.pyUSD, + maxTradeVolume: PYUSD_MAX_TRADE_VOLUME.toString(), // $500k, + oracleTimeout: PYUSD_ORACLE_TIMEOUT.toString(), + targetName: hre.ethers.utils.formatBytes32String('USD'), + defaultThreshold: fp('0.01').add(PYUSD_ORACLE_ERROR).toString(), + delayUntilDefault: bn('86400').toString(), // 24h + }) + collateral = await ethers.getContractAt('ICollateral', pyUsdCollateral) + await (await collateral.refresh()).wait() + expect(await collateral.status()).to.equal(CollateralStatus.SOUND) + + assetCollDeployments.collateral.pyUSD = pyUsdCollateral + assetCollDeployments.erc20s.pyUSD = networkConfig[chainId].tokens.pyUSD + deployedCollateral.push(pyUsdCollateral.toString()) + + /**************************************************************/ + + fs.writeFileSync(assetCollDeploymentFilename, JSON.stringify(assetCollDeployments, null, 2)) + + console.log(`Deployed pyUSD asset to ${hre.network.name} (${chainId}): + New deployments: ${deployedCollateral} + Deployment file: ${assetCollDeploymentFilename}`) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/verification/collateral-plugins/verify_pyusd.ts b/scripts/verification/collateral-plugins/verify_pyusd.ts new file mode 100644 index 000000000..5383c95ea --- /dev/null +++ b/scripts/verification/collateral-plugins/verify_pyusd.ts @@ -0,0 +1,51 @@ +import hre from 'hardhat' + +import { getChainId } from '../../../common/blockchain-utils' +import { developmentChains, networkConfig } from '../../../common/configuration' +import { getAssetCollDeploymentFilename, getDeploymentFile, getDeploymentFilename, IAssetCollDeployments, IDeployments } from '../../deployment/common' +import { priceTimeout, verifyContract } from '../../deployment/utils' +import { bn, fp } from '../../../common/numbers' +import { PYUSD_MAX_TRADE_VOLUME, PYUSD_ORACLE_ERROR, PYUSD_ORACLE_TIMEOUT } from '#/test/plugins/individual-collateral/aave-v3/constants' + +let deployments: IAssetCollDeployments + +async function main() { + // ********** Read config ********** + const chainId = await getChainId(hre) + if (!networkConfig[chainId]) { + throw new Error(`Missing network configuration for ${hre.network.name}`) + } + + if (developmentChains.includes(hre.network.name)) { + throw new Error(`Cannot verify contracts for development chain ${hre.network.name}`) + } + + deployments = getDeploymentFile(getAssetCollDeploymentFilename(chainId)) + + const collat = await hre.ethers.getContractAt('FiatCollateral', deployments.collateral.pyUSD!) + + /** ******************** Verify pyUSD Asset ****************************************/ + await verifyContract( + chainId, + deployments.collateral.pyUSD, + [ + { + priceTimeout: priceTimeout.toString(), + chainlinkFeed: networkConfig[chainId].chainlinkFeeds.pyUSD, + oracleError: PYUSD_ORACLE_ERROR.toString(), + erc20: networkConfig[chainId].tokens.pyUSD, + maxTradeVolume: PYUSD_MAX_TRADE_VOLUME.toString(), // $500k, + oracleTimeout: PYUSD_ORACLE_TIMEOUT, + targetName: hre.ethers.utils.formatBytes32String('USD'), + defaultThreshold: fp('0.01').add(PYUSD_ORACLE_ERROR).toString(), + delayUntilDefault: bn('86400').toString(), // 24h + }, + ], + 'contracts/plugins/assets/FiatCollateral.sol:FiatCollateral' + ) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/verify_etherscan.ts b/scripts/verify_etherscan.ts index 1aed44c0f..1266c5ce2 100644 --- a/scripts/verify_etherscan.ts +++ b/scripts/verify_etherscan.ts @@ -78,7 +78,8 @@ async function main() { 'collateral-plugins/verify_steakusdc.ts', 'collateral-plugins/verify_re7weth.ts', 'collateral-plugins/verify_apxeth.ts', - 'collateral-plugins/verify_USDe.ts' + 'collateral-plugins/verify_USDe.ts', + 'collateral-plugins/verify_pyusd.ts' ) } else if (chainId == '8453' || chainId == '84531') { // Base L2 chains