diff --git a/core/helpers/auctionSimulators.ts b/core/helpers/auctionSimulators.ts index 5813a2fdc..3f9cfa121 100644 --- a/core/helpers/auctionSimulators.ts +++ b/core/helpers/auctionSimulators.ts @@ -2,7 +2,7 @@ import getContract, { getContractAddressByName } from '../src/contracts'; import { TEST_NETWORK } from '../helpers/constants'; import BigNumber from '../src/bignumber'; import { DAI_NUMBER_OF_DIGITS, MKR_NUMBER_OF_DIGITS, RAD_NUMBER_OF_DIGITS } from '../src/constants/UNITS'; -import { overwriteUintMapping, overwriteUintValue } from './hardhat'; +import { overwriteUintMapping, overwriteUintValue } from './hardhat/slotOverwrite'; export const causeDebt = async ( debtAmountDai: BigNumber = new BigNumber(10), diff --git a/core/helpers/hardhat.ts b/core/helpers/hardhat.ts deleted file mode 100644 index 2032d0b84..000000000 --- a/core/helpers/hardhat.ts +++ /dev/null @@ -1,148 +0,0 @@ -import hre from 'hardhat'; -import { ethers } from 'ethers'; -import getContract, { getContractAddressByName } from '../src/contracts'; -import BigNumber from '../src/bignumber'; -import { EthereumProvider } from 'hardhat/types'; -import { formatToHex, formatToHexWithoutPad } from './format'; -import { pad32, concat, stripZeros } from './hex'; -import { setupRpcUrlAndGetNetworks } from '../src/rpc'; -import { createWalletFromPrivateKey } from '../src/signer'; -import { - HARDHAT_PRIVATE_KEY, - LOCAL_RPC_URL, - TEST_NETWORK, - REMOTE_RPC_URL, - HARDHAT_PUBLIC_KEY, -} from '../helpers/constants'; -import getProvider from '../src/provider'; -import { DAI_NUMBER_OF_DIGITS, MKR_NUMBER_OF_DIGITS, WAD_NUMBER_OF_DIGITS } from '../src/constants/UNITS'; -import { CollateralType } from '../src/types'; - -export const generateMappingSlotAddress = (mappingStartSlot: string, key: string) => { - return stripZeros(ethers.utils.keccak256(concat(pad32(key), pad32(mappingStartSlot)))); -}; - -export const overwriteUintValueInAddress = async ( - address: string, - slotAddress: string, - newValue: BigNumber, - provider: EthereumProvider = hre.network.provider -) => { - const hexValue = formatToHex(newValue, 32); - const storageToWrite = [address, slotAddress, hexValue]; - await provider.send('hardhat_setStorageAt', storageToWrite); -}; - -export const overwriteUintValue = async ( - contractName: string, - slotAddress: string, - newValue: BigNumber, - provider: EthereumProvider = hre.network.provider -) => { - const contractAddress = await getContractAddressByName(TEST_NETWORK, contractName); - await overwriteUintValueInAddress(contractAddress, slotAddress, newValue, provider); -}; - -export const overwriteUintMapping = async ( - contractName: string, - mappingSlotAddress: string, - mappingKey: string, - newValue: BigNumber, - provider: EthereumProvider = hre.network.provider -) => { - const slotAddress = generateMappingSlotAddress(mappingSlotAddress, mappingKey); - await overwriteUintValue(contractName, slotAddress, newValue, provider); -}; - -export const overwriteUintTable = async ( - contractName: string, - mappingSlotAddress: string, - tableRowKey: string, - tableColumnKey: string, - newValue: BigNumber, - provider: EthereumProvider = hre.network.provider -) => { - const rowAddress = generateMappingSlotAddress(mappingSlotAddress, tableRowKey); - await overwriteUintMapping(contractName, rowAddress, tableColumnKey, newValue, provider); -}; - -export const resetNetwork = async ( - blockNumber: number | undefined = undefined, - rpcUrl: string | undefined = REMOTE_RPC_URL, - provider: EthereumProvider = hre.network.provider -) => { - if (!rpcUrl && !REMOTE_RPC_URL) { - throw Error('Environment varialbe REMOTE_RPC_URL was not provided'); - } - if (blockNumber) { - console.info(`Forking at the block "${blockNumber}"`); - } else { - console.info('Forking at the latest block'); - } - await provider.request({ - method: 'hardhat_reset', - params: [ - { - forking: { - jsonRpcUrl: rpcUrl, - blockNumber: blockNumber, - }, - }, - ], - }); -}; - -export const createWalletForRpc = async (walletPrivateKey: string = HARDHAT_PRIVATE_KEY) => { - await setupRpcUrlAndGetNetworks(LOCAL_RPC_URL); - console.info(`New RPC endpoint has started on ${LOCAL_RPC_URL}`); - const walletAddress = await createWalletFromPrivateKey(walletPrivateKey, TEST_NETWORK); - console.info(`Using wallet with:\n\t - public key: ${walletAddress}\n\t - private key: ${walletPrivateKey}`); - return hre.network.provider; -}; - -export const warpTime = async function (blocks = 20000, secondsBetweenBlocks = 270) { - const provider = await getProvider(TEST_NETWORK); - await provider.send('hardhat_mine', [formatToHexWithoutPad(blocks), formatToHexWithoutPad(secondsBetweenBlocks)]); - return blocks * secondsBetweenBlocks; -}; - -export const resetNetworkAndSetupWallet = async function ( - blockNumber?: number, - walletPrivateKey: string = HARDHAT_PRIVATE_KEY -) { - await resetNetwork(blockNumber); - const provider = await createWalletForRpc(walletPrivateKey); - return provider; -}; - -export const addDaiToBalance = async ( - daiAmount: BigNumber = new BigNumber(100000), - walletAddress: string = HARDHAT_PUBLIC_KEY -) => { - const daiContract = await getContract(TEST_NETWORK, 'MCD_DAI', false); - await overwriteUintMapping('MCD_DAI', '0x2', walletAddress, daiAmount.shiftedBy(DAI_NUMBER_OF_DIGITS)); - const daiBalanceHex = await daiContract.balanceOf(walletAddress); - const daiBalance = new BigNumber(daiBalanceHex._hex).shiftedBy(-DAI_NUMBER_OF_DIGITS); - console.info(`New DAI balance: ${daiBalance}`); -}; - -export const addMkrToBalance = async ( - mkrAmount: BigNumber = new BigNumber(100000), - walletAddress: string = HARDHAT_PUBLIC_KEY -) => { - const mkrContract = await getContract(TEST_NETWORK, 'MCD_GOV', false); - await overwriteUintMapping('MCD_GOV', '0x1', walletAddress, mkrAmount.shiftedBy(MKR_NUMBER_OF_DIGITS)); - const mkrBalanceHex = await mkrContract.balanceOf(walletAddress); - const mkrBalance = new BigNumber(mkrBalanceHex._hex).shiftedBy(-MKR_NUMBER_OF_DIGITS); - console.info(`New MKR balance: ${mkrBalance}`); -}; - -export const setCollateralInVat = async ( - collateralType: CollateralType, - collateralAmount: BigNumber, - provider?: EthereumProvider -) => { - const value = collateralAmount.shiftedBy(WAD_NUMBER_OF_DIGITS); - const collateralTypeHex = ethers.utils.formatBytes32String(collateralType); - await overwriteUintTable('MCD_VAT', '0x4', collateralTypeHex, HARDHAT_PUBLIC_KEY, value, provider); -}; diff --git a/core/helpers/hardhat/balance.ts b/core/helpers/hardhat/balance.ts new file mode 100644 index 000000000..a239138ae --- /dev/null +++ b/core/helpers/hardhat/balance.ts @@ -0,0 +1,40 @@ +import { ethers } from 'ethers'; +import getContract from '../../src/contracts'; +import BigNumber from '../../src/bignumber'; +import { EthereumProvider } from 'hardhat/types'; +import { TEST_NETWORK, HARDHAT_PUBLIC_KEY } from '../../helpers/constants'; +import { DAI_NUMBER_OF_DIGITS, MKR_NUMBER_OF_DIGITS, WAD_NUMBER_OF_DIGITS } from '../../src/constants/UNITS'; +import { CollateralType } from '../../src/types'; +import { overwriteUintMapping, overwriteUintTable } from '../hardhat/slotOverwrite'; + +export const addDaiToBalance = async ( + daiAmount: BigNumber = new BigNumber(100000), + walletAddress: string = HARDHAT_PUBLIC_KEY +) => { + const daiContract = await getContract(TEST_NETWORK, 'MCD_DAI', false); + await overwriteUintMapping('MCD_DAI', '0x2', walletAddress, daiAmount.shiftedBy(DAI_NUMBER_OF_DIGITS)); + const daiBalanceHex = await daiContract.balanceOf(walletAddress); + const daiBalance = new BigNumber(daiBalanceHex._hex).shiftedBy(-DAI_NUMBER_OF_DIGITS); + console.info(`New DAI balance: ${daiBalance}`); +}; + +export const addMkrToBalance = async ( + mkrAmount: BigNumber = new BigNumber(100000), + walletAddress: string = HARDHAT_PUBLIC_KEY +) => { + const mkrContract = await getContract(TEST_NETWORK, 'MCD_GOV', false); + await overwriteUintMapping('MCD_GOV', '0x1', walletAddress, mkrAmount.shiftedBy(MKR_NUMBER_OF_DIGITS)); + const mkrBalanceHex = await mkrContract.balanceOf(walletAddress); + const mkrBalance = new BigNumber(mkrBalanceHex._hex).shiftedBy(-MKR_NUMBER_OF_DIGITS); + console.info(`New MKR balance: ${mkrBalance}`); +}; + +export const setCollateralInVat = async ( + collateralType: CollateralType, + collateralAmount: BigNumber, + provider?: EthereumProvider +) => { + const value = collateralAmount.shiftedBy(WAD_NUMBER_OF_DIGITS); + const collateralTypeHex = ethers.utils.formatBytes32String(collateralType); + await overwriteUintTable('MCD_VAT', '0x4', collateralTypeHex, HARDHAT_PUBLIC_KEY, value, provider); +}; diff --git a/core/helpers/hardhat/erc20.ts b/core/helpers/hardhat/erc20.ts new file mode 100644 index 000000000..04c9dcd94 --- /dev/null +++ b/core/helpers/hardhat/erc20.ts @@ -0,0 +1,73 @@ +import { getContractAddressByName, getErc20Contract } from '../../src/contracts'; +import BigNumber from '../../src/bignumber'; +import { TEST_NETWORK, HARDHAT_PUBLIC_KEY } from '../../helpers/constants'; +import { CollateralConfig, CollateralType } from '../../src/types'; +import { getCollateralConfigBySymbol, getCollateralConfigByType } from '../../src/constants/COLLATERALS'; +import { overwriteUintMappingInAddress, runBalanceSlotDiscoveryLoopForERC20Token } from './slotOverwrite'; + +export const determineBalanceSlot = async ( + collateralType: CollateralType +): Promise<[string, 'vyper' | 'solidity'] | [null, null]> => { + console.info('Determining balance slot...'); + const collateralConfig = getCollateralConfigByType(collateralType); + const tokenContractAddress = await getContractAddressByName(TEST_NETWORK, collateralConfig.symbol); + try { + const [slot, languageFormat] = await findERC20BalanceSlot(tokenContractAddress); + console.info( + `Balance slot is ${slot}, language format is ${languageFormat}, contract address is ${tokenContractAddress}` + ); + return [slot, languageFormat]; + } catch (e) { + if ( + e instanceof Error && + e.message.startsWith('Failed to find the slot of the balance for the token in address ') + ) { + return [null, null]; + } + throw e; + } +}; + +export const findERC20BalanceSlot = async (tokenAddress: string): Promise<[string, 'vyper' | 'solidity']> => { + const contract = await getErc20Contract(TEST_NETWORK, tokenAddress); + const balanceHex = await contract.balanceOf(HARDHAT_PUBLIC_KEY); + const balance = new BigNumber(balanceHex._hex); + const overwriteValue = balance.eq(0) ? new BigNumber(10) : new BigNumber(0); + const discoverySolidity = await runBalanceSlotDiscoveryLoopForERC20Token( + tokenAddress, + contract, + overwriteValue, + balance, + 'solidity' + ); + if (discoverySolidity) { + return [discoverySolidity, 'solidity']; + } + const discoveryVyper = await runBalanceSlotDiscoveryLoopForERC20Token( + tokenAddress, + contract, + overwriteValue, + balance, + 'vyper' + ); + if (discoveryVyper) { + return [discoveryVyper, 'vyper']; + } + + throw new Error(`Failed to find the slot of the balance for the token in address ${tokenAddress}`); +}; + +export const setCollateralInWallet = async ( + collateralSymbol: CollateralConfig['symbol'], + collateralAmount: BigNumber, + address: string = HARDHAT_PUBLIC_KEY +) => { + const collateralConfig = getCollateralConfigBySymbol(collateralSymbol); + const value = collateralAmount.shiftedBy(collateralConfig.decimals); + const tokenAddress = await getContractAddressByName(TEST_NETWORK, collateralConfig.symbol); + const [balanceSlot, languageFormat] = await determineBalanceSlot(collateralConfig.ilk); + if (!balanceSlot || !languageFormat) { + throw new Error('Could not overwrite the balance since the balance slot was not found'); + } + await overwriteUintMappingInAddress(tokenAddress, balanceSlot, address, value, undefined, languageFormat); +}; diff --git a/core/helpers/hardhat/network.ts b/core/helpers/hardhat/network.ts new file mode 100644 index 000000000..84b68a787 --- /dev/null +++ b/core/helpers/hardhat/network.ts @@ -0,0 +1,56 @@ +import hre from 'hardhat'; +import { EthereumProvider } from 'hardhat/types'; +import { formatToHexWithoutPad } from '../format'; +import { setupRpcUrlAndGetNetworks } from '../../src/rpc'; +import { createWalletFromPrivateKey } from '../../src/signer'; +import { HARDHAT_PRIVATE_KEY, LOCAL_RPC_URL, TEST_NETWORK, REMOTE_RPC_URL } from '../../helpers/constants'; +import getProvider from '../../src/provider'; + +export const resetNetwork = async ( + blockNumber: number | undefined = undefined, + rpcUrl: string | undefined = REMOTE_RPC_URL, + provider: EthereumProvider = hre.network.provider +) => { + if (!rpcUrl && !REMOTE_RPC_URL) { + throw Error('Environment varialbe REMOTE_RPC_URL was not provided'); + } + if (blockNumber) { + console.info(`Forking at the block "${blockNumber}"`); + } else { + console.info('Forking at the latest block'); + } + await provider.request({ + method: 'hardhat_reset', + params: [ + { + forking: { + jsonRpcUrl: rpcUrl, + blockNumber: blockNumber, + }, + }, + ], + }); +}; + +export const createWalletForRpc = async (walletPrivateKey: string = HARDHAT_PRIVATE_KEY) => { + await setupRpcUrlAndGetNetworks(LOCAL_RPC_URL); + console.info(`New RPC endpoint has started on ${LOCAL_RPC_URL}`); + const walletAddress = await createWalletFromPrivateKey(walletPrivateKey, TEST_NETWORK); + console.info(`Using wallet with:\n\t - public key: ${walletAddress}\n\t - private key: ${walletPrivateKey}`); + return hre.network.provider; +}; + +export const warpTime = async function (blocks = 20000, secondsBetweenBlocks = 270) { + const provider = await getProvider(TEST_NETWORK); + await provider.send('hardhat_mine', [formatToHexWithoutPad(blocks), formatToHexWithoutPad(secondsBetweenBlocks)]); + return blocks * secondsBetweenBlocks; +}; + +export const resetNetworkAndSetupWallet = async function ( + blockNumber?: number, + walletPrivateKey: string = HARDHAT_PRIVATE_KEY +) { + await resetNetwork(blockNumber); + const provider = await createWalletForRpc(walletPrivateKey); + return provider; +}; diff --git a/core/helpers/hardhat/slotOverwrite.ts b/core/helpers/hardhat/slotOverwrite.ts new file mode 100644 index 000000000..339b50358 --- /dev/null +++ b/core/helpers/hardhat/slotOverwrite.ts @@ -0,0 +1,130 @@ +import hre from 'hardhat'; +import { ethers } from 'ethers'; +import { getContractAddressByName } from '../../src/contracts'; +import BigNumber from '../../src/bignumber'; +import { EthereumProvider } from 'hardhat/types'; +import { formatToHex } from '../format'; +import { pad32, concat, stripZeros } from '../hex'; +import { TEST_NETWORK, HARDHAT_PUBLIC_KEY } from '../../helpers/constants'; + +export const generateMappingSlotAddress = ( + mappingStartSlot: string, + key: string, + languageFormat: 'vyper' | 'solidity' = 'solidity' +) => { + if (languageFormat === 'solidity') { + return stripZeros(ethers.utils.keccak256(concat(pad32(key), pad32(mappingStartSlot)))); + } + return stripZeros(ethers.utils.keccak256(concat(pad32(mappingStartSlot), pad32(key)))); +}; + +export const overwriteUintValueInAddress = async ( + address: string, + slotAddress: string, + newValue: BigNumber, + provider: EthereumProvider = hre.network.provider +) => { + const hexValue = formatToHex(newValue, 32); + const storageToWrite = [address, slotAddress, hexValue]; + await provider.send('hardhat_setStorageAt', storageToWrite); +}; + +export const overwriteUintValue = async ( + contractName: string, + slotAddress: string, + newValue: BigNumber, + provider: EthereumProvider = hre.network.provider +) => { + const contractAddress = await getContractAddressByName(TEST_NETWORK, contractName); + await overwriteUintValueInAddress(contractAddress, slotAddress, newValue, provider); +}; + +export const overwriteUintMapping = async ( + contractName: string, + mappingSlotAddress: string, + mappingKey: string, + newValue: BigNumber, + provider: EthereumProvider = hre.network.provider +) => { + const slotAddress = generateMappingSlotAddress(mappingSlotAddress, mappingKey); + await overwriteUintValue(contractName, slotAddress, newValue, provider); +}; + +export const overwriteUintMappingInAddress = async ( + contractAddress: string, + mappingSlotAddress: string, + mappingKey: string, + newValue: BigNumber, + provider: EthereumProvider = hre.network.provider, + languageFormat: 'vyper' | 'solidity' = 'solidity' +) => { + const slotAddress = generateMappingSlotAddress(mappingSlotAddress, mappingKey, languageFormat); + await overwriteUintValueInAddress(contractAddress, slotAddress, newValue, provider); +}; + +export const overwriteUintTable = async ( + contractName: string, + mappingSlotAddress: string, + tableRowKey: string, + tableColumnKey: string, + newValue: BigNumber, + provider: EthereumProvider = hre.network.provider +) => { + const rowAddress = generateMappingSlotAddress(mappingSlotAddress, tableRowKey); + await overwriteUintMapping(contractName, rowAddress, tableColumnKey, newValue, provider); +}; +const isOverwrittenBalanceEqual = async (contract: ethers.Contract, oldBalance: BigNumber) => { + const overwrittenBalanceHex = await contract.balanceOf(HARDHAT_PUBLIC_KEY); + const overwrittenBalance = new BigNumber(overwrittenBalanceHex._hex); + return overwrittenBalance.eq(oldBalance); +}; +export const runBalanceSlotDiscoveryLoopForERC20Token = async ( + tokenAddress: string, + contract: ethers.Contract, + overwriteValue: BigNumber, + initialValue: BigNumber, + languageFormat: 'solidity' | 'vyper', + loops = 100 +) => { + for (const i of Array.from(Array(loops).keys())) { + const slot = ethers.utils.hexValue(i); + const slotValueBeforeEdit = new BigNumber(await hre.ethers.provider.getStorageAt(tokenAddress, slot)); + await overwriteUintMappingInAddress( + tokenAddress, + slot, + HARDHAT_PUBLIC_KEY, + overwriteValue, + undefined, + languageFormat + ); + + let isSlotFound = false; + if (await isOverwrittenBalanceEqual(contract, overwriteValue)) { + // double check to make sure the value in the slot is not accidentally the same as the hardcoded one above + await overwriteUintMappingInAddress( + tokenAddress, + slot, + HARDHAT_PUBLIC_KEY, + initialValue, + undefined, + languageFormat + ); + if (await isOverwrittenBalanceEqual(contract, initialValue)) { + isSlotFound = true; + } + } + // cleanup + await overwriteUintMappingInAddress( + tokenAddress, + slot, + HARDHAT_PUBLIC_KEY, + slotValueBeforeEdit, + undefined, + languageFormat + ); + if (isSlotFound) { + return slot; + } + } + return null; +}; diff --git a/core/simulations/configs/blocksWithVaultsInAllStates.ts b/core/simulations/configs/blocksWithVaultsInAllStates.ts index 0c4fdba7f..2cc7f4daa 100644 --- a/core/simulations/configs/blocksWithVaultsInAllStates.ts +++ b/core/simulations/configs/blocksWithVaultsInAllStates.ts @@ -1,4 +1,4 @@ -import { resetNetworkAndSetupWallet } from '../../helpers/hardhat'; +import { resetNetworkAndSetupWallet } from '../../helpers/hardhat/network'; import { Simulation } from '../types'; const simulation: Simulation = { diff --git a/core/simulations/configs/createDebtAuctionSimulation.ts b/core/simulations/configs/createDebtAuctionSimulation.ts index 9f6e373d5..37ed3f711 100644 --- a/core/simulations/configs/createDebtAuctionSimulation.ts +++ b/core/simulations/configs/createDebtAuctionSimulation.ts @@ -1,4 +1,5 @@ -import { resetNetworkAndSetupWallet, warpTime, addDaiToBalance, addMkrToBalance } from '../../helpers/hardhat'; +import { addDaiToBalance, addMkrToBalance } from '../../helpers/hardhat/balance'; +import { resetNetworkAndSetupWallet, warpTime } from '../../helpers/hardhat/network'; import { causeDebt } from '../../helpers/auctionSimulators'; import { Simulation } from '../types'; diff --git a/core/simulations/configs/createSurplusAcutionSimulation.ts b/core/simulations/configs/createSurplusAcutionSimulation.ts index ed78e2b96..a1b0e1d8d 100644 --- a/core/simulations/configs/createSurplusAcutionSimulation.ts +++ b/core/simulations/configs/createSurplusAcutionSimulation.ts @@ -1,4 +1,6 @@ -import { resetNetworkAndSetupWallet, warpTime, addDaiToBalance, addMkrToBalance } from '../../helpers/hardhat'; +import { resetNetworkAndSetupWallet, warpTime } from '../../helpers/hardhat/network'; +import { addDaiToBalance, addMkrToBalance } from '../../helpers/hardhat/balance'; + import { causeSurplus } from '../../helpers/auctionSimulators'; import { Simulation } from '../types'; diff --git a/core/simulations/configs/surplusAuctionSimulation.ts b/core/simulations/configs/surplusAuctionSimulation.ts index 575b50a8d..71ea5c408 100644 --- a/core/simulations/configs/surplusAuctionSimulation.ts +++ b/core/simulations/configs/surplusAuctionSimulation.ts @@ -1,4 +1,5 @@ -import { warpTime, resetNetworkAndSetupWallet, addDaiToBalance, addMkrToBalance } from '../../helpers/hardhat'; +import { resetNetworkAndSetupWallet, warpTime } from '../../helpers/hardhat/network'; +import { addDaiToBalance, addMkrToBalance } from '../../helpers/hardhat/balance'; import { Simulation } from '../types'; const HARDHAT_FORK_BLOCK_NUMBER = 14078339; diff --git a/core/simulations/configs/vaultLiquidation.ts b/core/simulations/configs/vaultLiquidation.ts index 69adc6969..95ccd4165 100644 --- a/core/simulations/configs/vaultLiquidation.ts +++ b/core/simulations/configs/vaultLiquidation.ts @@ -1,4 +1,5 @@ -import { warpTime, resetNetworkAndSetupWallet, addDaiToBalance, addMkrToBalance } from '../../helpers/hardhat'; +import { warpTime, resetNetworkAndSetupWallet } from '../../helpers/hardhat/network'; +import { addDaiToBalance, addMkrToBalance } from '../../helpers/hardhat/balance'; import { Simulation } from '../types'; import prompts from 'prompts'; import COLLATERALS from '../../src/constants/COLLATERALS'; @@ -11,7 +12,7 @@ import createVaultWithCollateral, { const UNSUPPORTED_COLLATERAL_TYPES = [ 'CRVV1ETHSTETH-A', // collateral handled differently 'UNIV2DAIUSDC-A', // Liquidation limit too high (fails with "Dog/liquidation-limit-hit") - 'WSTETH-B', // does not accumulate stability fee rate fast enough + 'WSTETH-B', // does not accumulate stability fee rate at all. ]; export const getLiquidatableCollateralTypes = () => { diff --git a/core/simulations/configs/wstethAuctionSimulation.ts b/core/simulations/configs/wstethAuctionSimulation.ts index 12171196e..27da57ffe 100644 --- a/core/simulations/configs/wstethAuctionSimulation.ts +++ b/core/simulations/configs/wstethAuctionSimulation.ts @@ -1,4 +1,4 @@ -import { warpTime, resetNetworkAndSetupWallet } from '../../helpers/hardhat'; +import { warpTime, resetNetworkAndSetupWallet } from '../../helpers/hardhat/network'; import { Simulation } from '../types'; const simulation: Simulation = { diff --git a/core/simulations/helpers/createVaultWithCollateral.ts b/core/simulations/helpers/createVaultWithCollateral.ts index d9415f63f..c346a8e19 100644 --- a/core/simulations/helpers/createVaultWithCollateral.ts +++ b/core/simulations/helpers/createVaultWithCollateral.ts @@ -1,4 +1,4 @@ -import { setCollateralInVat } from '../../helpers/hardhat'; +import { setCollateralInVat } from '../../helpers/hardhat/balance'; import { getCollateralConfigByType } from '../../src/constants/COLLATERALS'; import BigNumber from '../../src/bignumber'; import { changeVaultContents, fetchVault, openVault, fetchVaultCollateralParameters } from '../../src/vaults'; @@ -11,14 +11,15 @@ import { } from '../../src/contracts'; import { depositCollateralToVat, - fetchCollateralInVat, fetchERC20TokenBalance, + fetchCollateralInVat, withdrawCollateralFromVat, } from '../../src/wallet'; import { MAX } from '../../src/constants/UNITS'; import { CollateralConfig, CollateralType } from '../../src/types'; import { ethers } from 'ethers'; import { roundDownToFirstSignificantDecimal, roundUpToFirstSignificantDecimal } from '../../helpers/hex'; +import { determineBalanceSlot, setCollateralInWallet } from '../../helpers/hardhat/erc20'; const setAndCheckCollateralInVat = async (collateralType: CollateralType, collateralOwned: BigNumber) => { console.info(`Setting ${collateralType} balance in VAT...`); @@ -148,9 +149,16 @@ const giveJoinContractAllowance = async (collateralConfig: CollateralConfig, amo }; const createVaultWithCollateral = async (collateralType: CollateralType, collateralOwned: BigNumber) => { + const [balanceSlot, languageFormat] = await determineBalanceSlot(collateralType); const collateralConfig = getCollateralConfigByType(collateralType); - await setAndCheckCollateralInVat(collateralType, collateralOwned); - await checkAndWithdrawCollateralFromVat(collateralConfig, collateralOwned); + + if (balanceSlot && languageFormat) { + await setCollateralInWallet(collateralConfig.symbol, collateralOwned); + } else { + // fallback to setting vat balance and withdrawing it + await setAndCheckCollateralInVat(collateralType, collateralOwned); + await checkAndWithdrawCollateralFromVat(collateralConfig, collateralOwned); + } await ensureWalletBalance(collateralConfig, collateralOwned); const vaultId = await openVault(TEST_NETWORK, HARDHAT_PUBLIC_KEY, collateralType); diff --git a/core/src/getCollateralPriceOracleConfig.ts b/core/src/getCollateralPriceOracleConfig.ts index b97188cff..fe84ae849 100644 --- a/core/src/getCollateralPriceOracleConfig.ts +++ b/core/src/getCollateralPriceOracleConfig.ts @@ -3,17 +3,14 @@ import { getContractAddressByName } from './contracts'; import contractCollateralToOracleInterface from './abis/MCD_SPOT.json'; import contractOracleInterface from './abis/OSM.json'; import { ethers } from 'ethers'; -import { - generateMappingSlotAddress, - overwriteUintValueInAddress, - resetNetworkAndSetupWallet, -} from '../helpers/hardhat'; import BigNumber from './bignumber'; import { HARDHAT_PUBLIC_KEY, TEST_NETWORK } from '../helpers/constants'; import { CONFIG_WITH_NEXT_PRICE, CONFIG_WITHOUT_NEXT_PRICE } from './constants/COLLATERALS'; import { CollateralPriceSourceConfig, CollateralType } from './types'; import getSigner from './signer'; import keypress from '../helpers/keypress'; +import { resetNetworkAndSetupWallet } from '../helpers/hardhat/network'; +import { generateMappingSlotAddress, overwriteUintValueInAddress } from '../helpers/hardhat/slotOverwrite'; const choicesYesNo = [ { title: 'yes', value: true }, diff --git a/core/src/types.ts b/core/src/types.ts index 53c0c67f8..be2106697 100644 --- a/core/src/types.ts +++ b/core/src/types.ts @@ -294,7 +294,7 @@ export declare interface DebtAuctionEnriched extends DebtAuctionActive { export declare interface DebtAuctionTransaction extends DebtAuctionEnriched, CompensationAuctionTransactionFees {} -export type CollateralType = CollateralConfig['title']; +export type CollateralType = CollateralConfig['ilk']; export declare interface LiquidationLimits { maximumProtocolDebtDai: BigNumber; diff --git a/core/test/debt-test.ts b/core/test/debt-test.ts index b922aa678..98b0402e8 100644 --- a/core/test/debt-test.ts +++ b/core/test/debt-test.ts @@ -2,7 +2,7 @@ import { expect } from 'chai'; import { causeDebt } from '../helpers/auctionSimulators'; import getContract from '../src/contracts'; import { TEST_NETWORK } from '../helpers/constants'; -import { resetNetworkAndSetupWallet as reset } from '../helpers/hardhat'; +import { resetNetworkAndSetupWallet as reset } from '../helpers/hardhat/network'; describe('Debt Auction', () => { beforeEach(async () => { diff --git a/core/test/market-price-test.ts b/core/test/market-price-test.ts index 87c05bbda..d15832f6d 100644 --- a/core/test/market-price-test.ts +++ b/core/test/market-price-test.ts @@ -2,7 +2,7 @@ import { expect } from 'chai'; import { convertMkrToDai } from '../src/calleeFunctions/helpers/uniswapV3'; import { setupRpcUrlAndGetNetworks } from '../src/rpc'; import BigNumber from '../src/bignumber'; -import { resetNetwork } from '../helpers/hardhat'; +import { resetNetwork } from '../helpers/hardhat/network'; import { LOCAL_RPC_URL } from '../helpers/constants'; const HARDHAT_FORK_BLOCK_NUMBER = 14078339; diff --git a/core/test/surplus-test.ts b/core/test/surplus-test.ts index 7a4d49a8a..f2ebdc8f0 100644 --- a/core/test/surplus-test.ts +++ b/core/test/surplus-test.ts @@ -13,7 +13,7 @@ import { setupRpcUrlAndGetNetworks } from '../src/rpc'; import { swapToMKR } from '../src/helpers/swap'; import { createWalletFromPrivateKey } from '../src/signer'; import { SurplusAuctionActive } from '../src/types'; -import { resetNetwork } from '../helpers/hardhat'; +import { resetNetwork } from '../helpers/hardhat/network'; import BigNumber from '../src/bignumber'; import { fetchSurplusAuctionByIndex } from '../src/surplus'; diff --git a/core/test/vault-test.ts b/core/test/vault-test.ts index 98caa4096..9a8c6cb11 100644 --- a/core/test/vault-test.ts +++ b/core/test/vault-test.ts @@ -6,7 +6,8 @@ import { liquidateVault, } from '../src/vaults'; import { getOsmPrices } from '../src/oracles'; -import { createWalletForRpc, overwriteUintValue, resetNetwork, warpTime } from '../helpers/hardhat'; +import { createWalletForRpc, resetNetwork, warpTime } from '../helpers/hardhat/network'; +import { overwriteUintValue } from '../helpers/hardhat/slotOverwrite'; import { setupRpcUrlAndGetNetworks } from '../src/rpc'; import { HARDHAT_PRIVATE_KEY, HARDHAT_PUBLIC_KEY, LOCAL_RPC_URL, TEST_NETWORK } from '../helpers/constants'; import { expect } from 'chai'; @@ -436,7 +437,6 @@ describe(`Collateral vault simulation liquidation `, () => { } throw e; } - let vaultId: number; try { vaultId = await createVaultWithCollateral(collateralType, collateralOwned);