diff --git a/scripts/addresses/1-tmp-assets-collateral.json b/scripts/addresses/1-tmp-assets-collateral.json index 3ff88b29a..503ea9fb9 100644 --- a/scripts/addresses/1-tmp-assets-collateral.json +++ b/scripts/addresses/1-tmp-assets-collateral.json @@ -61,7 +61,8 @@ "sfrxETH": "0x4c891fCa6319d492866672E3D2AfdAAA5bDcfF67", "ETHx": "0x73a36258E6A48D0095D1997Fec7F51e191B4Ec81", "apxETH": "0x05ffDaAA2aF48e1De1CE34d633db018a28e3B3F5", - "sUSDe": "0x35081Ca24319835e5f759163F7e75eaB753e0b7E" + "sUSDe": "0x35081Ca24319835e5f759163F7e75eaB753e0b7E", + "pyUSD": "0xa5cde4fB1132daF8f4a0D3140859271208d944E9" }, "erc20s": { "stkAAVE": "0x4da27a545c0c5B758a6BA100e3a049001de870f5", @@ -123,6 +124,7 @@ "CVX": "0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B", "ETHx": "0xA35b1B31Ce002FBF2058D22F30f95D405200A15b", "apxETH": "0x9Ba021B0a9b958B5E75cE9f6dff97C7eE52cb3E6", - "sUSDe": "0x9D39A5DE30e57443BfF2A8307A4256c8797A3497" + "sUSDe": "0x9D39A5DE30e57443BfF2A8307A4256c8797A3497", + "pyUSD": "0x6c3ea9036406852006290770bedfcaba0e23a0e8" } } diff --git a/scripts/deploy.ts b/scripts/deploy.ts index cc2a51418..a1347953a 100644 --- a/scripts/deploy.ts +++ b/scripts/deploy.ts @@ -89,7 +89,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 55023fd71..a448a9ee8 100644 --- a/scripts/verify_etherscan.ts +++ b/scripts/verify_etherscan.ts @@ -79,7 +79,8 @@ async function main() { 'collateral-plugins/verify_re7weth.ts', 'collateral-plugins/verify_ethx.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