Skip to content

Commit

Permalink
feat: Set ERC20 balance for collateral auction simulation (#499)
Browse files Browse the repository at this point in the history
  • Loading branch information
KirillDogadin-std authored Oct 19, 2022
1 parent bf702c4 commit 695d43d
Show file tree
Hide file tree
Showing 19 changed files with 332 additions and 171 deletions.
2 changes: 1 addition & 1 deletion core/helpers/auctionSimulators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
148 changes: 0 additions & 148 deletions core/helpers/hardhat.ts

This file was deleted.

40 changes: 40 additions & 0 deletions core/helpers/hardhat/balance.ts
Original file line number Diff line number Diff line change
@@ -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);
};
73 changes: 73 additions & 0 deletions core/helpers/hardhat/erc20.ts
Original file line number Diff line number Diff line change
@@ -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);
};
56 changes: 56 additions & 0 deletions core/helpers/hardhat/network.ts
Original file line number Diff line number Diff line change
@@ -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;
};
Loading

0 comments on commit 695d43d

Please sign in to comment.