UNPKG

@perifinance/peri-finance

Version:

The smart contracts which make up the Peri Finance system. (pynths.com)

1,077 lines (1,016 loc) 35.4 kB
'use strict'; const w3utils = require('web3-utils'); const abiDecoder = require('abi-decoder'); // load the data in explicitly (not programmatically) so webpack knows what to bundle const data = { kovan: require('./publish/deployed/kovan'), rinkeby: require('./publish/deployed/rinkeby'), ropsten: require('./publish/deployed/ropsten'), mainnet: require('./publish/deployed/mainnet'), goerli: require('./publish/deployed/goerli'), // 'goerli-ovm': require('./publish/deployed/goerli-ovm'), // 'kovan-ovm': require('./publish/deployed/kovan-ovm'), // 'mainnet-ovm': require('./publish/deployed/mainnet-ovm'), polygon: require('./publish/deployed/polygon'), mumbai: require('./publish/deployed/mumbai'), bsctest: require('./publish/deployed/bsctest'), bsc: require('./publish/deployed/bsc'), shibuya: require('./publish/deployed/shibuya'), 'moonbase-alphanet': require('./publish/deployed/moonbase-alphanet'), moonriver: require('./publish/deployed/moonriver'), 'base-sepolia': require('./publish/deployed/base-sepolia'), base: require('./publish/deployed/base'), moonbeam: require('./publish/deployed/moonbeam'), sepolia: require('./publish/deployed/sepolia'), }; const assets = require('./publish/assets.json'); const ovmIgnored = require('./publish/ovm-ignore.json'); const nonUpgradeable = require('./publish/non-upgradeable.json'); const releases = require('./publish/releases.json'); const networks = [ 'local', 'kovan', 'rinkeby', 'ropsten', 'mainnet', 'goerli', 'polygon', 'mumbai', 'bsctest', 'bsc', 'shibuya', 'moonbase-alphanet', 'moonriver', 'moonbeam', 'base-sepolia', 'base', 'sepolia', ]; const chainIdMapping = Object.entries({ 1: { network: 'mainnet', }, 3: { network: 'ropsten', }, 4: { network: 'rinkeby', }, 5: { network: 'goerli', }, 42: { network: 'kovan', }, 84532: { network: 'base-sepolia', }, // Hardhat fork of mainnet: https://hardhat.org/config/#hardhat-network 1337: { network: 'polygon', fork: true, }, 31337: { network: 'local', }, /* // OVM networks: see https://github.com/ethereum-optimism/regenesis/ 10: { network: 'mainnet', useOvm: true, }, 69: { network: 'kovan', useOvm: true, }, '-1': { // no chain ID for this currently network: 'goerli', useOvm: true, }, */ // now append any defaults 137: { network: 'polygon', }, 80001: { network: 'mumbai', }, 97: { network: 'bsctest', }, 56: { network: 'bsc', }, 81: { network: 'shibuya', }, 1287: { network: 'moonbase-alphanet', }, 1284: { network: 'moonbeam', }, 1285: { network: 'moonriver', }, 8453: { network: 'base', }, 11155111: { network: 'sepolia', }, }).reduce((memo, [id, body]) => { memo[id] = Object.assign({ useOvm: false, fork: false }, body); return memo; }, {}); const getNetworkFromId = ({ id }) => chainIdMapping[id]; const networkToChainId = Object.entries(chainIdMapping).reduce( (memo, [id, { network, useOvm, fork }]) => { memo[network + (useOvm ? '-ovm' : '') + (fork ? '-fork' : '')] = id; return memo; }, {} ); const constants = { BUILD_FOLDER: 'build', CONTRACTS_FOLDER: 'contracts', COMPILED_FOLDER: 'compiled', FLATTENED_FOLDER: 'flattened', AST_FOLDER: 'ast', CONFIG_FILENAME: 'config.json', PARAMS_FILENAME: 'params.json', PYNTHS_FILENAME: 'pynths.json', STAKING_REWARDS_FILENAME: 'rewards.json', SHORTING_REWARDS_FILENAME: 'shorting-rewards.json', OWNER_ACTIONS_FILENAME: 'owner-actions.json', DEPLOYMENT_FILENAME: 'deployment.json', VERSIONS_FILENAME: 'versions.json', FEEDS_FILENAME: 'feeds.json', AST_FILENAME: 'asts.json', ZERO_ADDRESS: '0x' + '0'.repeat(40), OVM_MAX_GAS_LIMIT: '8999999', // inflationStartTimestampInSecs: 1626480000, // Saturday, July 17, 2021 9:00:00 AM GMT+09:00 inflationStartTimestampInSecs: 1625875200, // Saturday, July 10, 2021 9:00:00 AM GMT+09:00 }; const knownAccounts = { mainnet: [ // { // name: 'binance', // Binance 8 Wallet // address: '0xF977814e90dA44bFA03b6295A0616a897441aceC', // }, // { // name: 'renBTCWallet', // KeeperDAO wallet (has renBTC and ETH) // address: '0x35ffd6e268610e764ff6944d07760d0efe5e40e5', // }, // { // name: 'loansAccount', // address: '0x62f7A1F94aba23eD2dD108F8D23Aa3e7d452565B', // }, ], rinkeby: [], ropsten: [], goerli: [], kovan: [], mumbai: [], polygon: [], bsctest: [], bsc: [], 'moonbase-alphanet': [], moonriver: [], moonbeam: [], 'base-sepolia': [], base: [], sepolia: [], }; // The solidity defaults are managed here in the same format they will be stored, hence all // numbers are converted to strings and those with 18 decimals are also converted to wei amounts const defaults = { WAITING_PERIOD_SECS: (60 * 5).toString(), // 5 mins PRICE_DEVIATION_THRESHOLD_FACTOR: w3utils.toWei('3'), TRADING_REWARDS_ENABLED: false, ISSUANCE_RATIO: w3utils .toBN(1) .mul(w3utils.toBN(1e18)) .div(w3utils.toBN(4)) .toString(), // 1/4 = 0.25 MAX_EXTERNAL_TOKEN_QUOTA: w3utils .toBN(5) .mul(w3utils.toBN(1e17)) .toString(), FEE_PERIOD_DURATION: (60 * 60 * (24 * 7 - 3)).toString(), // 1 week - 3 hours TARGET_THRESHOLD: '1', // 1% target threshold (it will be converted to a decimal when set) LIQUIDATION_DELAY: (60 * 60 * 24 * 1).toString(), // 1 days LIQUIDATION_RATIO: w3utils.toWei('0.666666666666666666'), // 150% cratio LIQUIDATION_RATIOS: { P: w3utils.toWei('0.666666666666666666'), C: w3utils.toWei('0.8'), I: w3utils.toWei('0.833333333333333333'), }, LIQUIDATION_PENALTY: w3utils.toWei('0.1'), // 10% penalty RATE_STALE_PERIOD: (3600 * 25).toString(), // 25 hours EXCHANGE_FEE_RATES: { forex: w3utils.toWei('0.003'), commodity: w3utils.toWei('0.003'), equities: w3utils.toWei('0.003'), crypto: w3utils.toWei('0.003'), index: w3utils.toWei('0.003'), }, MINIMUM_STAKE_TIME: (3600 * 24).toString(), // 1 days DEBT_SNAPSHOT_STALE_TIME: (43800).toString(), // 12 hour heartbeat + 10 minutes mining time // DEBT_SNAPSHOT_STALE_TIME: (3600 * 25 + 600).toString(), // 25 hour heartbeat + 10 minutes mining time SYNC_STALE_THRESHOLD: w3utils .toBN(1) .mul(w3utils.toBN(1e18)) .div(w3utils.toBN(20)) .toString(), // 1/20 5% BRIDGE_CLAIM_GAS_COST: w3utils.toWei(`7095534.6`, 'gwei'), BRIDGE_TRANSFER_GAS_COST: w3utils.toWei(`8867349.3`, 'gwei'), INITIAL_ISSUANCE: 0, // w3utils.toWei(`${2e6}`), LAST_MINT_EVENT: 1713052800, // Sun Apr 14 2024 00:00:00 GMT+0000 INFLATION_WEEK_COUNTER: 144, // 140, EXTERNAL_TOKEN_ISSUANCE_RATIO: { USDC: w3utils.toWei('1'), USDT: w3utils.toWei('1'), DAI: w3utils.toWei('1'), PAXG: w3utils.toWei('0.75'), XAUT: w3utils.toWei('0.75'), }, AGGREGATOR_WARNING_FLAGS: { mainnet: '0x4A5b9B4aD08616D11F3A402FF7cBEAcB732a76C6', kovan: '0x6292aa9a6650ae14fbf974e5029f36f95a1848fd', }, RENBTC_ERC20_ADDRESSES: { mainnet: '0xEB4C2781e4ebA804CE9a9803C67d0893436bB27D', kovan: '0x9B2fE385cEDea62D839E4dE89B0A23EF4eacC717', goerli: constants.ZERO_ADDRESS, rinkeby: '0xEDC0C23864B041607D624E2d9a67916B6cf40F7a', ropsten: constants.ZERO_ADDRESS, mumbai: constants.ZERO_ADDRESS, polygon: constants.ZERO_ADDRESS, bsc: constants.ZERO_ADDRESS, bsctest: constants.ZERO_ADDRESS, shibuya: constants.ZERO_ADDRESS, 'moonbase-alphanet': constants.ZERO_ADDRESS, moonriver: constants.ZERO_ADDRESS, moonbeam: constants.ZERO_ADDRESS, 'base-sepolia': constants.ZERO_ADDRESS, base: constants.ZERO_ADDRESS, sepolia: constants.ZERO_ADDRESS, // local : '0xEB4C2781e4ebA804CE9a9803C67d0893436bB27D', <-- fork }, USDC_ERC20_ADDRESSES: { mainnet: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', kovan: '0x98da9a82224E7A5896D6227382F7a52c82082146', goerli: '0x15040a4bDE0731664373Fb46Ce233262A644DFcd', rinkeby: '0x6bA629E9df8dC7f4039e0FfD1Ff8FF08b609d11C', ropsten: '0x7A7Ed4851B607811C10E51b5538203599437AAD3', mumbai: '0xcE954FC4c52A9E6e25306912A36eC59293da41E3', polygon: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174', // 6 decimals bsc: '0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d', // 18 decimals bsctest: '0x8EDc640693b518c8d531A8516A5C0Ae98b641a03', shibuya: '0xa6bEF2115B3a9EF9E00EF8162a24f866F9F50118', 'moonbase-alphanet': '0xDF17D7AaCC4cE7f675d3600A07b3CEA843F3669f', moonriver: '0xE3F5a90F9cb311505cd691a46596599aA1A0AD7D', // 6 decimals moonbeam: '0x818ec0A7Fe18Ff94269904fCED6AE3DaE6d6dC0b', // 6 decimals 'base-sepolia': '0xfec043ba43c733069cbc2243b36bc4fa33afcc28', base: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', // 6 decimals sepolia: '0x38d4e2EefDD05970f7d198F74E25D94e70D049D5', // 6 decimals // local : '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', <-- fork }, DAI_ERC20_ADDRESSES: { mainnet: '0x6b175474e89094c44da98b954eedeac495271d0f', kovan: '0x39247f428F3A4ceAf40D4ED66809d02Ad016d3af', goerli: '0x7A95dE39F23e3Cf5B49dA829DA0fE39DaE39e4e8', rinkeby: '0x1d9602B83f02d57f35fA1767D2beecEB5FecDfa5', ropsten: '0xc3a0926dbBfFBDdD86BdbE2b0c115b6E5aAEDeE4', mumbai: '0xAcC78d249781EDb5feB50027971EF4D60f144325', polygon: '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063', bsc: '0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3', bsctest: '0x52306d4521eFF70Ba555A578a66705b3352e8B3a', shibuya: '0xf9f6A3D3ED2b12483e271D92F68FcbC716BEba9F', 'moonbase-alphanet': '0x33B86de94702C5Ff1ECba36D38Ea2Fc238894315', moonriver: '0x80A16016cC4A2E6a2CACA8a4a498b1699fF0f844', moonbeam: '0x06e605775296e851FF43b4dAa541Bb0984E9D6fD', 'base-sepolia': '0x1AdC5b1bca919F59a00FC0fE8646C9e9C41338Eb', base: '0x50c5725949a6f0c72e6c4a641f24049a917db0cb', sepolia: '0x4ABf615437fb7eCE1b6702E57B23a7547F945545', // local : '0x6b175474e89094c44da98b954eedeac495271d0f', <-- fork }, USDT_ERC20_ADDRESSES: { mainnet: '0xdac17f958d2ee523a2206206994597c13d831ec7', // 6 decimals kovan: constants.ZERO_ADDRESS, goerli: constants.ZERO_ADDRESS, rinkeby: constants.ZERO_ADDRESS, ropsten: constants.ZERO_ADDRESS, mumbai: '0xbf56f5Af97F6818f451F92ca917D8eeb87BbEc7c', // 6 decimals polygon: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', // 6 decimals bsc: '0x55d398326f99059ff775485246999027b3197955', // 18 decimals bsctest: constants.ZERO_ADDRESS, shibuya: constants.ZERO_ADDRESS, 'moonbase-alphanet': '0x321449E0Be9798881e11925666aBaA324162930B', // 6 decimals moonbeam: '0xeFAeeE334F0Fd1712f9a8cc375f427D9Cdd40d73', // 6 decimals moonriver: '0xB44a9B6905aF7c801311e8F4E76932ee959c663C', // 6 decimals sepolia: '0x2436953d15Ae8b9119c787e1d50e393aFEe3426A', // 6 decimals }, XAUT_ERC20_ADDRESSES: { mainnet: '0x68749665FF8D2d112Fa859AA293F07A622782F38', // 6 decimals kovan: constants.ZERO_ADDRESS, goerli: constants.ZERO_ADDRESS, rinkeby: constants.ZERO_ADDRESS, ropsten: constants.ZERO_ADDRESS, mumbai: '0xc20c3c3Ff7C418C6372287106b1668ae40c1bC39', // 6 decimals polygon: constants.ZERO_ADDRESS, bsc: constants.ZERO_ADDRESS, bsctest: constants.ZERO_ADDRESS, shibuya: constants.ZERO_ADDRESS, 'moonbase-alphanet': '0xFA85FfEf4186339892557bb80E4F9C5F3E4df97f', // 6 decimals sepolia: '0x16B7Cf4F16608D76aEAD2b7b10f85090EfC7B746', }, // USDbC_ERC20_ADDRESSES: { // base: '0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA', // 'base-sepolia': '0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA', // }, PAXG_ERC20_ADDRESSES: { mainnet: '0x45804880De22913dAFE09f4980848ECE6EcbAf78', // 18 decimals kovan: constants.ZERO_ADDRESS, goerli: constants.ZERO_ADDRESS, rinkeby: constants.ZERO_ADDRESS, ropsten: constants.ZERO_ADDRESS, mumbai: '0x644eAb1a0Ed9E034ad9eDFe75dbE67D614Fb7e7f', // 18 decimals polygon: '0x553d3D295e0f695B9228246232eDF400ed3560B5', bsc: '0x7950865a9140cB519342433146Ed5b40c6F210f7', // 18 decimals bsctest: '0xd3145aB4D7271740C1d4BdB0deD5CDEE0d08ee10', // 18 decimals shibuya: constants.ZERO_ADDRESS, 'moonbase-alphanet': '0xE00A06E4938c015ba83F3AcB7B3499B36cf58502', // 18 decimals sepolia: '0x0567327A31A812344B71e6f95a64626EB72c1B22', }, MINTER_ROLE_ADDRESS: { mainnet: '0x9923263fA127b3d1484cFD649df8f1831c2A74e4', kovan: constants.ZERO_ADDRESS, goerli: '0x37c3bfC05d5ebF9EBb3FF80ce0bd0133Bf221BC8', rinkeby: constants.ZERO_ADDRESS, ropsten: constants.ZERO_ADDRESS, mumbai: constants.ZERO_ADDRESS, polygon: constants.ZERO_ADDRESS, bsc: constants.ZERO_ADDRESS, bsctest: constants.ZERO_ADDRESS, shibuya: constants.ZERO_ADDRESS, 'moonbase-alphanet': constants.ZERO_ADDRESS, moonriver: constants.ZERO_ADDRESS, moonbeam: constants.ZERO_ADDRESS, 'base-sepolia': constants.ZERO_ADDRESS, base: constants.ZERO_ADDRESS, sepolia: constants.ZERO_ADDRESS, local: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', }, DEBT_MANAGER_ADDRESS: { mainnet: '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', kovan: '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', goerli: '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', rinkeby: '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', ropsten: '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', mumbai: '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', polygon: '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', bsc: '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', bsctest: '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', shibuya: '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', 'moonbase-alphanet': '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', moonriver: '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', moonbeam: '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', 'base-sepolia': '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', base: '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', sepolia: '0x08a76Fb0B5511b0a10DC4141C4DAD6E2471803ba', local: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', }, INFLATION_MINTER_ADDRESS: { mainnet: '0x727bd962784C27C269E8287F9202312208B83FA7', kovan: '0x727bd962784C27C269E8287F9202312208B83FA7', goerli: '0x727bd962784C27C269E8287F9202312208B83FA7', rinkeby: '0x727bd962784C27C269E8287F9202312208B83FA7', ropsten: '0x727bd962784C27C269E8287F9202312208B83FA7', mumbai: '0x727bd962784C27C269E8287F9202312208B83FA7', polygon: '0x727bd962784C27C269E8287F9202312208B83FA7', bsc: '0x727bd962784C27C269E8287F9202312208B83FA7', bsctest: '0x727bd962784C27C269E8287F9202312208B83FA7', shibuya: '0x727bd962784C27C269E8287F9202312208B83FA7', 'moonbase-alphanet': '0x727bd962784C27C269E8287F9202312208B83FA7', moonriver: '0x727bd962784C27C269E8287F9202312208B83FA7', moonbeam: '0x727bd962784C27C269E8287F9202312208B83FA7', 'base-sepolia': '0x727bd962784C27C269E8287F9202312208B83FA7', base: '0x727bd962784C27C269E8287F9202312208B83FA7', sepolia: '0x727bd962784C27C269E8287F9202312208B83FA7', local: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', }, ORACLE_ADDRESS: { mainnet: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', kovan: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', goerli: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', rinkeby: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', ropsten: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', mumbai: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', polygon: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', bsc: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', bsctest: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', shibuya: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', 'moonbase-alphanet': '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', moonriver: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', moonbeam: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', 'base-sepolia': '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', base: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', sepolia: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', local: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', }, CHILD_CHAIN_MANAGER_ADDRESS: { mainnet: constants.ZERO_ADDRESS, kovan: constants.ZERO_ADDRESS, goerli: constants.ZERO_ADDRESS, rinkeby: constants.ZERO_ADDRESS, ropsten: constants.ZERO_ADDRESS, mumbai: '0x981Ca3e19AB02f758f252611bb5881AA4ECEDB3B', polygon: '0x981Ca3e19AB02f758f252611bb5881AA4ECEDB3B', bsc: constants.ZERO_ADDRESS, bsctest: constants.ZERO_ADDRESS, 'moonbase-alphanet': constants.ZERO_ADDRESS, moonriver: constants.ZERO_ADDRESS, moonbeam: constants.ZERO_ADDRESS, 'base-sepolia': '0x981Ca3e19AB02f758f252611bb5881AA4ECEDB3B', base: '0x981Ca3e19AB02f758f252611bb5881AA4ECEDB3B', sepolia: constants.ZERO_ADDRESS, }, BRIDGE_ROLES: { mainnet: [{ roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }], kovan: [{ roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }], ropsten: [{ roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }], rinkeby: [{ roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }], bsc: [{ roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }], bsctest: [{ roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }], mumbai: [{ roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }], polygon: [{ roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }], goerli: [{ roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }], local: [{ roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }], 'moonbase-alphanet': [ { roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }, ], moonriver: [{ roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }], moonbeam: [{ roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }], 'base-sepolia': [ { roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }, ], base: [{ roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }], sepolia: [{ roleKey: 'Validator', address: '0xa4f99e30E0Ce73174f7CF13E8eeBA040ed10faf5' }], }, BRIDGE_NETWORK_STATUS: { mainnet: [ { network: 'bsc', isOpened: true }, { network: 'polygon', isOpened: true }, { network: 'moonriver', isOpened: true }, { network: 'moonbeam', isOpened: true }, { network: 'base', isOpened: true }, ], bsc: [ { network: 'mainnet', isOpened: true }, { network: 'polygon', isOpened: true }, { network: 'moonriver', isOpened: true }, { network: 'moonbeam', isOpened: true }, { network: 'base', isOpened: true }, ], polygon: [ { network: 'mainnet', isOpened: true }, { network: 'bsc', isOpened: true }, { network: 'moonriver', isOpened: true }, { network: 'moonbeam', isOpened: true }, { network: 'base', isOpened: true }, ], moonriver: [ { network: 'mainnet', isOpened: true }, { network: 'bsc', isOpened: true }, { network: 'polygon', isOpened: true }, { network: 'moonbeam', isOpened: true }, { network: 'base', isOpened: true }, ], moonbeam: [ { network: 'mainnet', isOpened: true }, { network: 'bsc', isOpened: true }, { network: 'polygon', isOpened: true }, { network: 'moonriver', isOpened: true }, { network: 'base', isOpened: true }, ], base: [ { network: 'mainnet', isOpened: true }, { network: 'bsc', isOpened: true }, { network: 'polygon', isOpened: true }, { network: 'moonriver', isOpened: true }, { network: 'moonbeam', isOpened: true }, ], sepolia: [ { network: 'base-sepolia', isOpened: true }, { network: 'bsctest', isOpened: true }, { network: 'mumbai', isOpened: true }, { network: 'moonbase-alphanet', isOpened: true }, ], kovan: [ { network: 'bsctest', isOpened: true }, { network: 'mumbai', isOpened: true }, { network: 'moonbase-alphanet', isOpened: true }, ], rinkeby: [{ network: 'moonbase-alphanet', isOpened: true }], ropsten: [{ network: 'moonbase-alphanet', isOpened: true }], bsctest: [ { network: 'sepolia', isOpened: true }, { network: 'mumbai', isOpened: true }, { network: 'moonbase-alphanet', isOpened: true }, { network: 'base-sepolia', isOpened: true }, ], mumbai: [ { network: 'bsctest', isOpened: true }, { network: 'sepolia', isOpened: true }, { network: 'moonbase-alphanet', isOpened: true }, { network: 'base-sepolia', isOpened: true }, ], goerli: [{ network: 'moonbase-alphanet', isOpened: true }], 'moonbase-alphanet': [ { network: 'bsctest', isOpened: true }, { network: 'sepolia', isOpened: true }, { network: 'mumbai', isOpened: true }, { network: 'base-sepolia', isOpened: true }, ], 'base-sepolia': [ { network: 'moonbase-alphanet', isOpened: true }, { network: 'mumbai', isOpened: true }, { network: 'bsctest', isOpened: true }, { network: 'sepolia', isOpened: true }, ], local: [ { network: 'mumbai', isOpened: true }, { network: 'bsctest', isOpened: true }, { network: 'sepolia', isOpened: true }, { network: 'moonbase-alphanet', isOpened: true }, ], }, CROSS_DOMAIN_DEPOSIT_GAS_LIMIT: `${3e6}`, CROSS_DOMAIN_ESCROW_GAS_LIMIT: `${8e6}`, CROSS_DOMAIN_REWARD_GAS_LIMIT: `${3e6}`, CROSS_DOMAIN_WITHDRAWAL_GAS_LIMIT: `${3e6}`, COLLATERAL_MANAGER: { PYNTHS: ['pUSD', 'pBTC', 'pETH'], SHORTS: [ { long: 'pBTC', short: 'iBTC' }, { long: 'pETH', short: 'iETH' }, ], MAX_DEBT: w3utils.toWei('50000000'), // 50 million pUSD BASE_BORROW_RATE: Math.round((0.005 * 1e18) / 31556926).toString(), // 31556926 is CollateralManager seconds per year BASE_SHORT_RATE: Math.round((0.005 * 1e18) / 31556926).toString(), }, COLLATERAL_ETH: { PYNTHS: ['pUSD', 'pETH'], MIN_CRATIO: w3utils.toWei('1.3'), MIN_COLLATERAL: w3utils.toWei('2'), ISSUE_FEE_RATE: w3utils.toWei('0.001'), }, COLLATERAL_RENBTC: { PYNTHS: ['pUSD', 'pBTC'], MIN_CRATIO: w3utils.toWei('1.3'), MIN_COLLATERAL: w3utils.toWei('0.05'), ISSUE_FEE_RATE: w3utils.toWei('0.001'), }, COLLATERAL_SHORT: { PYNTHS: ['pBTC', 'pETH'], MIN_CRATIO: w3utils.toWei('1.2'), MIN_COLLATERAL: w3utils.toWei('1000'), ISSUE_FEE_RATE: w3utils.toWei('0.005'), INTERACTION_DELAY: '3600', // 1 hour in secs }, }; /** * Converts a string into a hex representation of bytes32, with right padding */ const toBytes32 = key => w3utils.rightPad(w3utils.asciiToHex(key), 64); const fromBytes32 = key => w3utils.hexToAscii(key); const getFolderNameForNetwork = ({ network, useOvm = false }) => { if (network.includes('ovm')) { return network; } return useOvm ? `${network}-ovm` : network; }; const getPathToNetwork = ({ network = 'mainnet', file = '', useOvm = false, path } = {}) => path.join(__dirname, 'publish', 'deployed', getFolderNameForNetwork({ network, useOvm }), file); // Pass in fs and path to avoid webpack wrapping those const loadDeploymentFile = ({ network, path, fs, deploymentPath, useOvm = false }) => { if (!deploymentPath && network !== 'local' && (!path || !fs)) { return data[getFolderNameForNetwork({ network, useOvm })].deployment; } const pathToDeployment = deploymentPath ? path.join(deploymentPath, constants.DEPLOYMENT_FILENAME) : getPathToNetwork({ network, useOvm, path, file: constants.DEPLOYMENT_FILENAME }); if (!fs.existsSync(pathToDeployment)) { throw Error(`Cannot find deployment for network: ${network}.`); } return JSON.parse(fs.readFileSync(pathToDeployment)); }; /** * Retrieve the list of targets for the network - returning the name, address, source file and link to etherscan */ const getTarget = ({ network = 'mainnet', useOvm = false, contract, path, fs, deploymentPath, } = {}) => { const deployment = loadDeploymentFile({ network, useOvm, path, fs, deploymentPath }); if (contract) return deployment.targets[contract]; else return deployment.targets; }; /** * Retrieve the list of solidity sources for the network - returning the abi and bytecode */ const getSource = ({ network = 'mainnet', useOvm = false, contract, path, fs, deploymentPath, } = {}) => { const deployment = loadDeploymentFile({ network, useOvm, path, fs, deploymentPath }); if (contract) return deployment.sources[contract]; else return deployment.sources; }; /** * Retrieve the ASTs for the source contracts */ const getAST = ({ source, path, fs, match = /^contracts\// } = {}) => { let fullAST; if (path && fs) { const pathToAST = path.resolve( __dirname, constants.BUILD_FOLDER, constants.AST_FOLDER, constants.AST_FILENAME ); if (!fs.existsSync(pathToAST)) { throw Error('Cannot find AST'); } fullAST = JSON.parse(fs.readFileSync(pathToAST)); } else { // Note: The below cannot be required as the build folder is not stored // in code (only in the published module). // The solution involves tracking these after each commit in another file // somewhere persisted in the codebase - JJM // data.ast = require('./build/ast/asts.json'), if (!data.ast) { throw Error('AST currently not supported in browser mode'); } fullAST = data.ast; } // remove anything not matching the pattern const ast = Object.entries(fullAST) .filter(([astEntryKey]) => match.test(astEntryKey)) .reduce((memo, [key, val]) => { memo[key] = val; return memo; }, {}); if (source && source in ast) { return ast[source]; } else if (source) { // try to find the source without a path const [key, entry] = Object.entries(ast).find(([astEntryKey]) => astEntryKey.includes('/' + source)) || []; if (!key || !entry) { throw Error(`Cannot find AST entry for source: ${source}`); } return { [key]: entry }; } else { return ast; } }; const getFeeds = ({ network, path, fs, deploymentPath, useOvm = false } = {}) => { let feeds; if (!deploymentPath && network !== 'local' && (!path || !fs)) { feeds = data[getFolderNameForNetwork({ network, useOvm })].feeds; } else { const pathToFeeds = deploymentPath ? path.join(deploymentPath, constants.FEEDS_FILENAME) : getPathToNetwork({ network, path, useOvm, file: constants.FEEDS_FILENAME, }); if (!fs.existsSync(pathToFeeds)) { throw Error(`Cannot find feeds file.`); } feeds = JSON.parse(fs.readFileSync(pathToFeeds)); } const pynths = getPynths({ network, useOvm, path, fs, deploymentPath, skipPopulate: true }); // now mix in the asset data return Object.entries(feeds).reduce((memo, [asset, entry]) => { memo[asset] = Object.assign( // standalone feeds are those without a pynth using them // Note: ETH still used as a rate for Depot, can remove the below once the Depot uses pETH rate or is // removed from the system { standalone: !pynths.find(pynth => pynth.asset === asset) || asset === 'ETH' }, assets[asset], entry ); return memo; }, {}); }; /** * Retrieve ths list of pynths for the network - returning their names, assets underlying, category, sign, description, and * optional index and inverse properties */ const getPynths = ({ network = 'mainnet', path, fs, deploymentPath, useOvm = false, skipPopulate = false, } = {}) => { let pynths; if (!deploymentPath && network !== 'local' && (!path || !fs)) { pynths = data[getFolderNameForNetwork({ network, useOvm })].pynths; } else { const pathToPynthList = deploymentPath ? path.join(deploymentPath, constants.PYNTHS_FILENAME) : getPathToNetwork({ network, useOvm, path, file: constants.PYNTHS_FILENAME }); if (!fs.existsSync(pathToPynthList)) { throw Error(`Cannot find pynth list.`); } pynths = JSON.parse(fs.readFileSync(pathToPynthList)); } if (skipPopulate) { return pynths; } const feeds = getFeeds({ network, useOvm, path, fs, deploymentPath }); // copy all necessary index parameters from the longs to the corresponding shorts return pynths.map(pynth => { // mixin the asset details pynth = Object.assign({}, assets[pynth.asset], pynth); if (feeds[pynth.asset]) { const { feed } = feeds[pynth.asset]; pynth = Object.assign({ feed }, pynth); } if (pynth.inverted) { pynth.description = `Inverse ${pynth.description}`; } // replace an index placeholder with the index details if (typeof pynth.index === 'string') { const { index } = pynths.find(({ name }) => name === pynth.index) || {}; if (!index) { throw Error( `While processing ${pynth.name}, it's index mapping "${pynth.index}" cannot be found - this is an error in the deployment config and should be fixed` ); } pynth = Object.assign({}, pynth, { index }); } if (pynth.index) { pynth.index = pynth.index.map(indexEntry => { return Object.assign({}, assets[indexEntry.asset], indexEntry); }); } return pynth; }); }; /** * Retrieve the list of staking rewards for the network - returning this names, stakingToken, and rewardToken */ const getStakingRewards = ({ network = 'mainnet', useOvm = false, path, fs, deploymentPath, } = {}) => { if (!deploymentPath && network !== 'local' && (!path || !fs)) { return data[getFolderNameForNetwork({ network, useOvm })].rewards; } const pathToStakingRewardsList = deploymentPath ? path.join(deploymentPath, constants.STAKING_REWARDS_FILENAME) : getPathToNetwork({ network, path, useOvm, file: constants.STAKING_REWARDS_FILENAME, }); if (!fs.existsSync(pathToStakingRewardsList)) { return []; } return JSON.parse(fs.readFileSync(pathToStakingRewardsList)); }; /** * Retrieve the list of shorting rewards for the network - returning the names and rewardTokens */ const getShortingRewards = ({ network = 'mainnet', useOvm = false, path, fs, deploymentPath, } = {}) => { if (!deploymentPath && network !== 'local' && (!path || !fs)) { return data[getFolderNameForNetwork({ network, useOvm })]['shorting-rewards']; } const pathToShortingRewardsList = deploymentPath ? path.join(deploymentPath, constants.SHORTING_REWARDS_FILENAME) : getPathToNetwork({ network, path, useOvm, file: constants.SHORTING_REWARDS_FILENAME, }); if (!fs.existsSync(pathToShortingRewardsList)) { return []; } return JSON.parse(fs.readFileSync(pathToShortingRewardsList)); }; /** * Retrieve the list of system user addresses */ const getUsers = ({ network = 'mainnet', user, useOvm = false } = {}) => { const testnetOwner = '0x166220468aff631290b7E1Ddff7F45b052De8324'; const base = { owner: testnetOwner, deployer: testnetOwner, marketClosure: testnetOwner, oracle: '0x055ca0b950E129fF387dE1dbF53CaBcb434A64be', fee: '0xfeEFEEfeefEeFeefEEFEEfEeFeefEEFeeFEEFEeF', zero: '0x' + '0'.repeat(40), }; const map = { mainnet: Object.assign({}, base, { owner: '0xcFE81E615C4409FfeDD36faa99e88059cAab9267', deployer: '0xcFE81E615C4409FfeDD36faa99e88059cAab9267', }), kovan: Object.assign({}, base), // 'kovan-ovm': Object.assign({}, base), // 'mainnet-ovm': Object.assign({}, base, { // owner: '0xcFE81E615C4409FfeDD36faa99e88059cAab9267', // }), rinkeby: Object.assign({}, base), ropsten: Object.assign({}, base), goerli: Object.assign({}, base), // 'goerli-ovm': Object.assign({}, base), local: Object.assign({}, base, { // Deterministic account #0 when using `npx hardhat node` owner: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', }), mumbai: Object.assign({}, base), moonriver: Object.assign({}, base), polygon: Object.assign({}, base, { owner: '0xcFE81E615C4409FfeDD36faa99e88059cAab9267', deployer: '0xcFE81E615C4409FfeDD36faa99e88059cAab9267', }), bsc: Object.assign({}, base, { owner: '0xcFE81E615C4409FfeDD36faa99e88059cAab9267', deployer: '0xcFE81E615C4409FfeDD36faa99e88059cAab9267', }), }; const users = Object.entries( map[getFolderNameForNetwork({ network, useOvm })] ).map(([key, value]) => ({ name: key, address: value })); return user ? users.find(({ name }) => name === user) : users; }; const getVersions = ({ network = 'mainnet', path, fs, deploymentPath, useOvm, byContract = false, } = {}) => { let versions; if (!deploymentPath && network !== 'local' && (!path || !fs)) { versions = data[getFolderNameForNetwork({ network, useOvm })].versions; } else { const pathToVersions = deploymentPath ? path.join(deploymentPath, constants.VERSIONS_FILENAME) : getPathToNetwork({ network, useOvm, path, file: constants.VERSIONS_FILENAME }); if (!fs.existsSync(pathToVersions)) { throw Error(`Cannot find versions for network.`); } versions = JSON.parse(fs.readFileSync(pathToVersions)); } if (byContract) { // compile from the contract perspective return Object.values(versions).reduce( (memo, { tag, release, date, commit, block, contracts }) => { for (const [contract, contractEntry] of Object.entries(contracts)) { memo[contract] = memo[contract] || []; memo[contract].push(Object.assign({ tag, release, date, commit, block }, contractEntry)); } return memo; }, {} ); } return versions; }; const getSuspensionReasons = ({ code = undefined } = {}) => { const suspensionReasonMap = { 1: 'System Upgrade', 2: 'Market Closure', 4: 'iPynth Reprice', 55: 'Circuit Breaker (Phase one)', // https://sips.peri.finance/SIPS/sip-55 65: 'Decentralized Circuit Breaker (Phase two)', // https://sips.peri.finance/SIPS/sip-65 99999: 'Emergency', }; return code ? suspensionReasonMap[code] : suspensionReasonMap; }; /** * Retrieve the list of tokens used in the Peri Finance protocol */ const getTokens = ({ network = 'mainnet', path, fs, useOvm = false } = {}) => { const pynths = getPynths({ network, useOvm, path, fs }); const targets = getTarget({ network, useOvm, path, fs }); const feeds = getFeeds({ network, useOvm, path, fs }); return [ Object.assign( { symbol: 'PERI', asset: 'PERI', name: 'PeriFinance', address: targets.ProxyERC20.address, decimals: 18, }, feeds['PERI'].feed ? { feed: feeds['PERI'].feed } : {} ), ].concat( pynths .filter(({ category }) => category !== 'internal') .map(pynth => ({ symbol: pynth.name, asset: pynth.asset, name: pynth.description, address: (targets[`Proxy${pynth.name === 'pUSD' ? 'ERC20pUSD' : pynth.name}`] || {}) .address, index: pynth.index, inverted: pynth.inverted, decimals: 18, feed: pynth.feed, })) .sort((a, b) => (a.symbol > b.symbol ? 1 : -1)) ); }; const decode = ({ network = 'mainnet', fs, path, data, target, useOvm = false } = {}) => { const sources = getSource({ network, path, fs, useOvm }); for (const { abi } of Object.values(sources)) { abiDecoder.addABI(abi); } const targets = getTarget({ network, path, fs, useOvm }); let contract; if (target) { contract = Object.values(targets).filter( ({ address }) => address.toLowerCase() === target.toLowerCase() )[0].name; } return { method: abiDecoder.decodeMethod(data), contract }; }; const wrap = ({ network, deploymentPath, fs, path, useOvm = false }) => [ 'decode', 'getAST', 'getPathToNetwork', 'getSource', 'getStakingRewards', 'getShortingRewards', 'getFeeds', 'getPynths', 'getTarget', 'getTokens', 'getUsers', 'getVersions', ].reduce((memo, fnc) => { memo[fnc] = (prop = {}) => module.exports[fnc](Object.assign({ network, deploymentPath, fs, path, useOvm }, prop)); return memo; }, {}); module.exports = { chainIdMapping, constants, decode, defaults, getAST, getNetworkFromId, getPathToNetwork, getSource, getStakingRewards, getShortingRewards, getSuspensionReasons, getFeeds, getPynths, getTarget, getTokens, getUsers, getVersions, networks, networkToChainId, toBytes32, fromBytes32, wrap, ovmIgnored, nonUpgradeable, releases, knownAccounts, };