mirror of
				https://github.com/Instadapp/dsa-connectors.git
				synced 2024-07-29 22:37:00 +00:00 
			
		
		
		
	chore: add mainnet tests
This commit is contained in:
		
							parent
							
								
									b221c92d46
								
							
						
					
					
						commit
						f354f2112a
					
				
							
								
								
									
										160
									
								
								test/mainnet/mstable/mstable.helpers.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								test/mainnet/mstable/mstable.helpers.ts
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,160 @@ | |||
| import hre, { ethers } from "hardhat"; | ||||
| import { IERC20Minimal__factory } from "../../../typechain"; | ||||
| import { BigNumber as BN } from "ethers"; | ||||
| 
 | ||||
| export const DEAD_ADDRESS = "0x0000000000000000000000000000000000000001"; | ||||
| export const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; | ||||
| 
 | ||||
| export const DEFAULT_DECIMALS = 18; | ||||
| 
 | ||||
| export const ZERO = BN.from(0); | ||||
| export const ONE_MIN = BN.from(60); | ||||
| export const TEN_MINS = BN.from(60 * 10); | ||||
| export const ONE_HOUR = BN.from(60 * 60); | ||||
| export const ONE_DAY = BN.from(60 * 60 * 24); | ||||
| export const FIVE_DAYS = BN.from(60 * 60 * 24 * 5); | ||||
| export const TEN_DAYS = BN.from(60 * 60 * 24 * 10); | ||||
| export const ONE_WEEK = BN.from(60 * 60 * 24 * 7); | ||||
| export const ONE_YEAR = BN.from(60 * 60 * 24 * 365); | ||||
| 
 | ||||
| export const connectorName = "MStable"; | ||||
| 
 | ||||
| interface TokenData { | ||||
|   tokenAddress: string; | ||||
|   tokenWhaleAddress?: string; | ||||
|   feederPool?: string; | ||||
| } | ||||
| 
 | ||||
| export const toEther = (amount: BN) => ethers.utils.formatEther(amount); | ||||
| 
 | ||||
| export const getToken = (tokenSymbol: string): TokenData => { | ||||
|   switch (tokenSymbol) { | ||||
|     case "MTA": | ||||
|       return { | ||||
|         tokenAddress: "0xa3BeD4E1c75D00fa6f4E5E6922DB7261B5E9AcD2" | ||||
|       }; | ||||
|     case "mUSD": | ||||
|       return { | ||||
|         tokenAddress: "0xe2f2a5c287993345a840db3b0845fbc70f5935a5", | ||||
|         tokenWhaleAddress: "0x503828976D22510aad0201ac7EC88293211D23Da" | ||||
|       }; | ||||
| 
 | ||||
|     case "DAI": | ||||
|       return { | ||||
|         tokenAddress: "0x6b175474e89094c44da98b954eedeac495271d0f", | ||||
|         tokenWhaleAddress: "0xF977814e90dA44bFA03b6295A0616a897441aceC" | ||||
|       }; | ||||
|     case "USDC": | ||||
|       return { | ||||
|         tokenAddress: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" | ||||
|       }; | ||||
|     case "imUSD": | ||||
|       return { | ||||
|         tokenAddress: "0x30647a72dc82d7fbb1123ea74716ab8a317eac19" | ||||
|       }; | ||||
| 
 | ||||
|     case "imUSDVault": | ||||
|       return { | ||||
|         tokenAddress: "0x78BefCa7de27d07DC6e71da295Cc2946681A6c7B" | ||||
|       }; | ||||
| 
 | ||||
|     // Feeder Asset
 | ||||
|     case "alUSD": | ||||
|       return { | ||||
|         tokenAddress: "0xbc6da0fe9ad5f3b0d58160288917aa56653660e9", | ||||
|         tokenWhaleAddress: "0x115f95c00e8cf2f5C57250caA555A6B4e50B446b", | ||||
|         feederPool: "0x4eaa01974B6594C0Ee62fFd7FEE56CF11E6af936" | ||||
|       }; | ||||
| 
 | ||||
|     default: | ||||
|       throw new Error(`Token ${tokenSymbol} not supported`); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| export const sendToken = async (token: string, amount: any, from: string, to: string): Promise<any> => { | ||||
|   await hre.network.provider.request({ | ||||
|     method: "hardhat_impersonateAccount", | ||||
|     params: [from] | ||||
|   }); | ||||
|   const [signer] = await ethers.getSigners(); | ||||
|   const sender = hre.ethers.provider.getSigner(from); | ||||
| 
 | ||||
|   await signer.sendTransaction({ | ||||
|     to: from, | ||||
|     value: ethers.utils.parseEther("1") | ||||
|   }); | ||||
| 
 | ||||
|   return await IERC20Minimal__factory.connect(token, sender).transfer(to, amount); | ||||
| }; | ||||
| 
 | ||||
| export const fundWallet = async (token: string, amount: any, to: string) => { | ||||
|   const { tokenAddress, tokenWhaleAddress } = getToken(token); | ||||
|   await sendToken(tokenAddress, amount, tokenWhaleAddress!, to); | ||||
| }; | ||||
| 
 | ||||
| export const calcMinOut = (amount: BN, slippage: number): BN => { | ||||
|   const value = simpleToExactAmount(1 - slippage); | ||||
|   const minOut = amount.mul(value).div(ethers.BigNumber.from(10).pow(DEFAULT_DECIMALS)); | ||||
|   return minOut; | ||||
| }; | ||||
| 
 | ||||
| export const simpleToExactAmount = (amount: number | string | BN, decimals: number | BN = DEFAULT_DECIMALS): BN => { | ||||
|   let amountString = amount.toString(); | ||||
|   const decimalsBN = BN.from(decimals); | ||||
| 
 | ||||
|   if (decimalsBN.gt(100)) { | ||||
|     throw new Error(`Invalid decimals amount`); | ||||
|   } | ||||
| 
 | ||||
|   const scale = BN.from(10).pow(decimals); | ||||
|   const scaleString = scale.toString(); | ||||
| 
 | ||||
|   // Is it negative?
 | ||||
|   const negative = amountString.substring(0, 1) === "-"; | ||||
|   if (negative) { | ||||
|     amountString = amountString.substring(1); | ||||
|   } | ||||
| 
 | ||||
|   if (amountString === ".") { | ||||
|     throw new Error(`Error converting number ${amountString} to precise unit, invalid value`); | ||||
|   } | ||||
| 
 | ||||
|   // Split it into a whole and fractional part
 | ||||
|   // eslint-disable-next-line prefer-const
 | ||||
|   let [whole, fraction, ...rest] = amountString.split("."); | ||||
|   if (rest.length > 0) { | ||||
|     throw new Error(`Error converting number ${amountString} to precise unit, too many decimal points`); | ||||
|   } | ||||
| 
 | ||||
|   if (!whole) { | ||||
|     whole = "0"; | ||||
|   } | ||||
|   if (!fraction) { | ||||
|     fraction = "0"; | ||||
|   } | ||||
| 
 | ||||
|   if (fraction.length > scaleString.length - 1) { | ||||
|     throw new Error(`Error converting number ${amountString} to precise unit, too many decimal places`); | ||||
|   } | ||||
| 
 | ||||
|   while (fraction.length < scaleString.length - 1) { | ||||
|     fraction += "0"; | ||||
|   } | ||||
| 
 | ||||
|   const wholeBN = BN.from(whole); | ||||
|   const fractionBN = BN.from(fraction); | ||||
|   let result = wholeBN.mul(scale).add(fractionBN); | ||||
| 
 | ||||
|   if (negative) { | ||||
|     result = result.mul("-1"); | ||||
|   } | ||||
| 
 | ||||
|   return result; | ||||
| }; | ||||
| 
 | ||||
| export const advanceBlock = async (): Promise<void> => ethers.provider.send("evm_mine", []); | ||||
| 
 | ||||
| export const increaseTime = async (length: BN | number): Promise<void> => { | ||||
|   await ethers.provider.send("evm_increaseTime", [BN.from(length).toNumber()]); | ||||
|   await advanceBlock(); | ||||
| }; | ||||
							
								
								
									
										269
									
								
								test/mainnet/mstable/mstable.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										269
									
								
								test/mainnet/mstable/mstable.test.ts
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,269 @@ | |||
| import { expect } from "chai"; | ||||
| import hre from "hardhat"; | ||||
| const { waffle, ethers } = hre; | ||||
| const { provider } = waffle; | ||||
| 
 | ||||
| import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector"; | ||||
| import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2"; | ||||
| import { encodeSpells } from "../../../scripts/tests/encodeSpells"; | ||||
| import { getMasterSigner } from "../../../scripts/tests/getMasterSigner"; | ||||
| 
 | ||||
| import { addresses } from "../../../scripts/tests/mainnet/addresses"; | ||||
| import { abis } from "../../../scripts/constant/abis"; | ||||
| import type { Signer, Contract } from "ethers"; | ||||
| 
 | ||||
| import { ConnectV2mStable__factory, IERC20Minimal__factory, IERC20Minimal } from "../../../typechain"; | ||||
| 
 | ||||
| import { executeAndAssertDeposit, executeAndAssertSwap, executeAndAssertWithdraw } from "./mstable.utils"; | ||||
| 
 | ||||
| import { | ||||
|   fundWallet, | ||||
|   getToken, | ||||
|   simpleToExactAmount, | ||||
|   DEAD_ADDRESS, | ||||
|   calcMinOut, | ||||
|   ONE_DAY, | ||||
|   increaseTime, | ||||
|   connectorName, | ||||
|   toEther | ||||
| } from "./mstable.helpers"; | ||||
| 
 | ||||
| describe("MStable", async () => { | ||||
|   let dsaWallet0: Contract; | ||||
|   let masterSigner: Signer; | ||||
|   let instaConnectorsV2: Contract; | ||||
|   let connector: Contract; | ||||
| 
 | ||||
|   let mtaToken: IERC20Minimal = IERC20Minimal__factory.connect(getToken("MTA").tokenAddress, provider); | ||||
|   let mUsdToken: IERC20Minimal = IERC20Minimal__factory.connect(getToken("mUSD").tokenAddress, provider); | ||||
|   let imUsdToken: IERC20Minimal = IERC20Minimal__factory.connect(getToken("imUSD").tokenAddress, provider); | ||||
|   let imUsdVault: IERC20Minimal = IERC20Minimal__factory.connect(getToken("imUSDVault").tokenAddress, provider); | ||||
| 
 | ||||
|   let daiToken: IERC20Minimal = IERC20Minimal__factory.connect(getToken("DAI").tokenAddress, provider); | ||||
|   let usdcToken: IERC20Minimal = IERC20Minimal__factory.connect(getToken("USDC").tokenAddress, provider); | ||||
|   let alusdToken: IERC20Minimal = IERC20Minimal__factory.connect(getToken("alUSD").tokenAddress, provider); | ||||
| 
 | ||||
|   const wallets = provider.getWallets(); | ||||
|   const [wallet0, wallet1, wallet2, wallet3] = wallets; | ||||
| 
 | ||||
|   describe("DSA wallet", async () => { | ||||
|     const fundAmount = simpleToExactAmount(10000); | ||||
| 
 | ||||
|     const setup = async () => { | ||||
|       await hre.network.provider.request({ | ||||
|         method: "hardhat_reset", | ||||
|         params: [ | ||||
|           { | ||||
|             forking: { | ||||
|               // @ts-ignore
 | ||||
|               jsonRpcUrl: hre.config.networks.hardhat.forking.url, | ||||
|               blockNumber: 13905885 | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       }); | ||||
| 
 | ||||
|       masterSigner = await getMasterSigner(); | ||||
|       instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); | ||||
|       connector = await deployAndEnableConnector({ | ||||
|         connectorName, | ||||
|         contractArtifact: ConnectV2mStable__factory, | ||||
|         signer: masterSigner, | ||||
|         connectors: instaConnectorsV2 | ||||
|       }); | ||||
| 
 | ||||
|       console.log("Connector address", connector.address); | ||||
| 
 | ||||
|       dsaWallet0 = await buildDSAv2(wallet0.address); | ||||
| 
 | ||||
|       await wallet0.sendTransaction({ | ||||
|         to: dsaWallet0.address, | ||||
|         value: simpleToExactAmount(10) | ||||
|       }); | ||||
| 
 | ||||
|       await fundWallet("mUSD", fundAmount, dsaWallet0.address); | ||||
|       await fundWallet("DAI", fundAmount, dsaWallet0.address); | ||||
|       await fundWallet("alUSD", fundAmount, dsaWallet0.address); | ||||
|     }; | ||||
| 
 | ||||
|     describe("Deploy", async () => { | ||||
|       before(async () => { | ||||
|         await setup(); | ||||
|       }); | ||||
| 
 | ||||
|       it("Should deploy properly", async () => { | ||||
|         expect(instaConnectorsV2.address).to.be.properAddress; | ||||
|         expect(connector.address).to.be.properAddress; | ||||
|         expect(await masterSigner.getAddress()).to.be.properAddress; | ||||
| 
 | ||||
|         expect(dsaWallet0.address).to.be.properAddress; | ||||
|       }); | ||||
|       it("Should fund the wallet", async () => { | ||||
|         expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10")); | ||||
| 
 | ||||
|         expect(await mUsdToken.balanceOf(dsaWallet0.address)).to.be.gte(fundAmount); | ||||
|         expect(await daiToken.balanceOf(dsaWallet0.address)).to.be.gte(fundAmount); | ||||
|         expect(await alusdToken.balanceOf(dsaWallet0.address)).to.be.gte(fundAmount); | ||||
|       }); | ||||
|       it("Should not have vault tokens prior", async () => { | ||||
|         // No deposits prior
 | ||||
|         expect(await imUsdToken.balanceOf(dsaWallet0.address)).to.be.eq(0); | ||||
|         expect(await imUsdVault.balanceOf(dsaWallet0.address)).to.be.eq(0); | ||||
|       }); | ||||
|     }); | ||||
| 
 | ||||
|     describe("Main SAVE", async () => { | ||||
|       before(async () => { | ||||
|         await setup(); | ||||
|       }); | ||||
|       it("Should deposit mUSD to Vault successfully", async () => { | ||||
|         const depositAmount = simpleToExactAmount(100); | ||||
| 
 | ||||
|         await executeAndAssertDeposit("deposit", mUsdToken, depositAmount, dsaWallet0, wallet0); | ||||
|       }); | ||||
|       it("Should deposit DAI to Vault successfully (mUSD bAsset)", async () => { | ||||
|         const depositAmount = simpleToExactAmount(100); | ||||
|         const minOut = calcMinOut(depositAmount, 0.02); | ||||
| 
 | ||||
|         await executeAndAssertDeposit("depositViaMint", daiToken, depositAmount, dsaWallet0, wallet0, [minOut]); | ||||
|       }); | ||||
|       it("Should deposit alUSD to Vault successfully (via Feeder Pool)", async () => { | ||||
|         const depositAmount = simpleToExactAmount(100); | ||||
|         const minOut = calcMinOut(depositAmount, 0.02); | ||||
|         const path = getToken("alUSD").feederPool; | ||||
| 
 | ||||
|         await executeAndAssertDeposit("depositViaSwap", alusdToken, depositAmount, dsaWallet0, wallet0, [minOut, path]); | ||||
|       }); | ||||
|       it("Should withdraw from Vault to mUSD", async () => { | ||||
|         const withdrawAmount = simpleToExactAmount(100); | ||||
| 
 | ||||
|         await executeAndAssertWithdraw("withdraw", mUsdToken, withdrawAmount, dsaWallet0, wallet0, [withdrawAmount]); | ||||
|       }); | ||||
|       it("Should withdraw from Vault to DAI (mUSD bAsset)", async () => { | ||||
|         const withdrawAmount = simpleToExactAmount(100); | ||||
|         const minOut = simpleToExactAmount(1); | ||||
| 
 | ||||
|         const daiBalanceBefore = await daiToken.balanceOf(dsaWallet0.address); | ||||
|         console.log("DAI balance before: ", toEther(daiBalanceBefore)); | ||||
| 
 | ||||
|         const imUsdVaultBalanceBefore = await imUsdVault.balanceOf(dsaWallet0.address); | ||||
|         console.log("imUSD Vault balance before: ", toEther(imUsdVaultBalanceBefore)); | ||||
| 
 | ||||
|         const spells = [ | ||||
|           { | ||||
|             connector: connectorName, | ||||
|             method: "withdrawViaRedeem", | ||||
|             args: [daiToken.address, withdrawAmount, minOut] | ||||
|           } | ||||
|         ]; | ||||
| 
 | ||||
|         const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), DEAD_ADDRESS); | ||||
| 
 | ||||
|         const imUsdVaultBalanceAfter = await imUsdVault.balanceOf(dsaWallet0.address); | ||||
|         console.log("imUSD Vault balance after: ", toEther(imUsdVaultBalanceAfter)); | ||||
| 
 | ||||
|         const daiBalanceAfter = await daiToken.balanceOf(dsaWallet0.address); | ||||
|         console.log("DAI balance after: ", toEther(daiBalanceAfter)); | ||||
| 
 | ||||
|         expect(imUsdVaultBalanceAfter).to.be.eq(imUsdVaultBalanceBefore.sub(withdrawAmount)); | ||||
|         expect(daiBalanceAfter).to.gt(daiBalanceBefore); | ||||
|       }); | ||||
|       it("Should withdraw from Vault to alUSD (via Feeder Pool)", async () => { | ||||
|         const withdrawAmount = simpleToExactAmount(100); | ||||
|         const minOut = simpleToExactAmount(1); | ||||
| 
 | ||||
|         const alusdBalanceBefore = await alusdToken.balanceOf(dsaWallet0.address); | ||||
|         console.log("Balance before: ", toEther(alusdBalanceBefore)); | ||||
| 
 | ||||
|         const imUsdVaultBalanceBefore = await imUsdVault.balanceOf(dsaWallet0.address); | ||||
|         console.log("imUSD Vault balance before: ", toEther(imUsdVaultBalanceBefore)); | ||||
| 
 | ||||
|         const spells = [ | ||||
|           { | ||||
|             connector: connectorName, | ||||
|             method: "withdrawViaSwap", | ||||
|             args: [alusdToken.address, withdrawAmount, minOut, getToken("alUSD").feederPool] | ||||
|           } | ||||
|         ]; | ||||
| 
 | ||||
|         const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), DEAD_ADDRESS); | ||||
| 
 | ||||
|         const imUsdVaultBalanceAfter = await imUsdVault.balanceOf(dsaWallet0.address); | ||||
|         console.log("imUSD Vault balance after: ", toEther(imUsdVaultBalanceAfter)); | ||||
| 
 | ||||
|         const alusdBalanceAfter = await alusdToken.balanceOf(dsaWallet0.address); | ||||
|         console.log("alUSD balance after: ", toEther(alusdBalanceAfter)); | ||||
| 
 | ||||
|         expect(imUsdVaultBalanceAfter).to.be.eq(imUsdVaultBalanceBefore.sub(withdrawAmount)); | ||||
|         expect(alusdBalanceAfter).to.gt(alusdBalanceBefore); | ||||
|       }); | ||||
|       it("Should claim Rewards", async () => { | ||||
|         const mtaBalanceBefore = await mtaToken.balanceOf(dsaWallet0.address); | ||||
|         console.log("MTA balance before: ", toEther(mtaBalanceBefore)); | ||||
| 
 | ||||
|         // Wait a bit and let the rewards accumulate
 | ||||
|         await increaseTime(ONE_DAY); | ||||
| 
 | ||||
|         const spells = [ | ||||
|           { | ||||
|             connector: connectorName, | ||||
|             method: "claimRewards", | ||||
|             args: [] | ||||
|           } | ||||
|         ]; | ||||
| 
 | ||||
|         const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), DEAD_ADDRESS); | ||||
| 
 | ||||
|         const mtaBalanceAfter = await mtaToken.balanceOf(dsaWallet0.address); | ||||
|         console.log("MTA balance after: ", toEther(mtaBalanceAfter)); | ||||
| 
 | ||||
|         expect(mtaBalanceAfter).to.be.gt(mtaBalanceBefore); | ||||
|       }); | ||||
|     }); | ||||
|     describe("Main SWAP", async () => { | ||||
|       before(async () => { | ||||
|         await setup(); | ||||
|       }); | ||||
|       it("Should swap mUSD to bAsset (redeem)", async () => { | ||||
|         const swapAmount = simpleToExactAmount(100); | ||||
|         await executeAndAssertSwap("swap", mUsdToken, 18, daiToken, 18, swapAmount, dsaWallet0, wallet0); | ||||
|       }); | ||||
|       it("Should swap mUSD to fAsset (via feeder pool)", async () => { | ||||
|         const swapAmount = simpleToExactAmount(100); | ||||
|         const path = getToken("alUSD").feederPool; | ||||
|         await executeAndAssertSwap("swapViaFeeder", mUsdToken, 18, alusdToken, 18, swapAmount, dsaWallet0, wallet0, [ | ||||
|           path | ||||
|         ]); | ||||
|       }); | ||||
|       it("Should swap bAsset to mUSD (mint)", async () => { | ||||
|         const swapAmount = simpleToExactAmount(100); | ||||
|         await executeAndAssertSwap("swap", daiToken, 18, mUsdToken, 18, swapAmount, dsaWallet0, wallet0); | ||||
|       }); | ||||
|       it("Should swap bAsset to bAsset (swap)", async () => { | ||||
|         const swapAmount = simpleToExactAmount(100); | ||||
|         await executeAndAssertSwap("swap", daiToken, 18, usdcToken, 6, swapAmount, dsaWallet0, wallet0); | ||||
|       }); | ||||
|       it("Should swap bAsset to fAsset (via feeder)", async () => { | ||||
|         const swapAmount = simpleToExactAmount(100); | ||||
|         const path = getToken("alUSD").feederPool; | ||||
|         await executeAndAssertSwap("swapViaFeeder", daiToken, 18, alusdToken, 18, swapAmount, dsaWallet0, wallet0, [ | ||||
|           path | ||||
|         ]); | ||||
|       }); | ||||
|       it("Should swap fAsset to bAsset (via feeder)", async () => { | ||||
|         const swapAmount = simpleToExactAmount(100); | ||||
|         const path = getToken("alUSD").feederPool; | ||||
|         await executeAndAssertSwap("swapViaFeeder", alusdToken, 18, daiToken, 18, swapAmount, dsaWallet0, wallet0, [ | ||||
|           path | ||||
|         ]); | ||||
|       }); | ||||
|       it("Should swap fAsset to mUSD (via feeder)", async () => { | ||||
|         const swapAmount = simpleToExactAmount(100); | ||||
|         const path = getToken("alUSD").feederPool; | ||||
|         await executeAndAssertSwap("swapViaFeeder", alusdToken, 18, mUsdToken, 18, swapAmount, dsaWallet0, wallet0, [ | ||||
|           path | ||||
|         ]); | ||||
|       }); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
							
								
								
									
										137
									
								
								test/mainnet/mstable/mstable.utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								test/mainnet/mstable/mstable.utils.ts
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,137 @@ | |||
| import hre from "hardhat"; | ||||
| import { ethers } from "hardhat"; | ||||
| import { assert, expect } from "chai"; | ||||
| 
 | ||||
| import { | ||||
|   DEFAULT_DECIMALS, | ||||
|   DEAD_ADDRESS, | ||||
|   toEther, | ||||
|   connectorName, | ||||
|   simpleToExactAmount, | ||||
|   getToken | ||||
| } from "./mstable.helpers"; | ||||
| 
 | ||||
| import { IERC20Minimal, IERC20Minimal__factory } from "../../../typechain"; | ||||
| import { BigNumber, Contract, Wallet } from "ethers"; | ||||
| 
 | ||||
| import { encodeSpells } from "../../../scripts/tests/encodeSpells"; | ||||
| 
 | ||||
| const provider = hre.waffle.provider; | ||||
| 
 | ||||
| let imUsdToken: IERC20Minimal = IERC20Minimal__factory.connect(getToken("imUSD").tokenAddress, provider); | ||||
| let imUsdVault: IERC20Minimal = IERC20Minimal__factory.connect(getToken("imUSDVault").tokenAddress, provider); | ||||
| 
 | ||||
| export const executeAndAssertSwap = async ( | ||||
|   method: string, | ||||
|   tokenFrom: IERC20Minimal, | ||||
|   tokenFromDecimals: number, | ||||
|   tokenTo: IERC20Minimal, | ||||
|   tokenToDecimals: number, | ||||
|   swapAmount: BigNumber, | ||||
|   dsaWallet0: Contract, | ||||
|   wallet0: Wallet, | ||||
|   args?: any[] | ||||
| ) => { | ||||
|   const diffFrom = ethers.BigNumber.from(10).pow(DEFAULT_DECIMALS - tokenFromDecimals); | ||||
|   const diffTo = ethers.BigNumber.from(10).pow(DEFAULT_DECIMALS - tokenToDecimals); | ||||
| 
 | ||||
|   const tokenFromBalanceBefore = (await tokenFrom.balanceOf(dsaWallet0.address)).mul(diffFrom); | ||||
|   console.log("Token From balance before: ", toEther(tokenFromBalanceBefore)); | ||||
| 
 | ||||
|   const tokenToBalanceBefore = (await tokenTo.balanceOf(dsaWallet0.address)).mul(diffTo); | ||||
|   console.log("Token To balance before: ", toEther(tokenToBalanceBefore)); | ||||
| 
 | ||||
|   const spells = [ | ||||
|     { | ||||
|       connector: connectorName, | ||||
|       method, | ||||
|       args: [tokenFrom.address, tokenTo.address, swapAmount, 1, ...(args ? args : [])] | ||||
|     } | ||||
|   ]; | ||||
| 
 | ||||
|   console.log("Swapping...", toEther(swapAmount)); | ||||
| 
 | ||||
|   const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), DEAD_ADDRESS); | ||||
| 
 | ||||
|   const tokenFromBalanceAfter = (await tokenFrom.balanceOf(dsaWallet0.address)).mul(diffFrom); | ||||
|   console.log("Token From balance after: ", toEther(tokenFromBalanceAfter)); | ||||
| 
 | ||||
|   const tokenToBalanceAfter = (await tokenTo.balanceOf(dsaWallet0.address)).mul(diffTo); | ||||
|   console.log("Token To balance after: ", toEther(tokenToBalanceAfter)); | ||||
| 
 | ||||
|   expect(tokenFromBalanceAfter).to.be.eq(tokenFromBalanceBefore.sub(swapAmount)); | ||||
|   expect(tokenToBalanceAfter).to.be.gt(tokenToBalanceBefore); | ||||
| }; | ||||
| 
 | ||||
| export const executeAndAssertDeposit = async ( | ||||
|   method: string, | ||||
|   tokenFrom: IERC20Minimal, | ||||
|   depositAmount: BigNumber, | ||||
|   dsaWallet0: Contract, | ||||
|   wallet0: Wallet, | ||||
|   args?: any[] | ||||
| ) => { | ||||
|   const FromBalanceBefore = await tokenFrom.balanceOf(dsaWallet0.address); | ||||
|   console.log("Balance before: ", toEther(FromBalanceBefore)); | ||||
| 
 | ||||
|   const imUsdVaultBalanceBefore = await imUsdVault.balanceOf(dsaWallet0.address); | ||||
|   console.log("imUSD Vault balance before: ", toEther(imUsdVaultBalanceBefore)); | ||||
| 
 | ||||
|   const spells = [ | ||||
|     { | ||||
|       connector: connectorName, | ||||
|       method, | ||||
|       args: [tokenFrom.address, depositAmount, ...(args ? args : [])] | ||||
|     } | ||||
|   ]; | ||||
| 
 | ||||
|   const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), DEAD_ADDRESS); | ||||
| 
 | ||||
|   const FromBalanceAfter = await tokenFrom.balanceOf(dsaWallet0.address); | ||||
|   console.log("Balance after: ", toEther(FromBalanceAfter)); | ||||
| 
 | ||||
|   const imUsdBalance = await imUsdToken.balanceOf(dsaWallet0.address); | ||||
|   console.log("imUSD balance: ", toEther(imUsdBalance)); | ||||
| 
 | ||||
|   const imUsdVaultBalance = await imUsdVault.balanceOf(dsaWallet0.address); | ||||
|   console.log("imUSD Vault balance: ", toEther(imUsdVaultBalance)); | ||||
| 
 | ||||
|   // Should have something in the vault but no imUSD
 | ||||
|   expect(await imUsdToken.balanceOf(dsaWallet0.address)).to.be.eq(0); | ||||
|   expect(await imUsdVault.balanceOf(dsaWallet0.address)).to.be.gt(imUsdVaultBalanceBefore); | ||||
|   expect(FromBalanceAfter).to.eq(FromBalanceBefore.sub(depositAmount)); | ||||
| }; | ||||
| 
 | ||||
| export const executeAndAssertWithdraw = async ( | ||||
|   method: string, | ||||
|   tokenFrom: IERC20Minimal, | ||||
|   withdrawAmount: BigNumber, | ||||
|   dsaWallet0: Contract, | ||||
|   wallet0: Wallet, | ||||
|   args: any[] | ||||
| ) => { | ||||
|   const mUsdBalanceBefore = await tokenFrom.balanceOf(dsaWallet0.address); | ||||
|   console.log("Balance before: ", toEther(mUsdBalanceBefore)); | ||||
| 
 | ||||
|   const imUsdVaultBalanceBefore = await imUsdVault.balanceOf(dsaWallet0.address); | ||||
|   console.log("imUSD Vault balance before: ", toEther(imUsdVaultBalanceBefore)); | ||||
| 
 | ||||
|   const spells = [ | ||||
|     { | ||||
|       connector: connectorName, | ||||
|       method, | ||||
|       args | ||||
|     } | ||||
|   ]; | ||||
| 
 | ||||
|   const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), DEAD_ADDRESS); | ||||
| 
 | ||||
|   const imUsdVaultBalanceAfter = await imUsdVault.balanceOf(dsaWallet0.address); | ||||
|   console.log("imUSD Vault balance after: ", toEther(imUsdVaultBalanceAfter)); | ||||
| 
 | ||||
|   const mUsdBalanceAfter = await tokenFrom.balanceOf(dsaWallet0.address); | ||||
|   console.log("Balance after: ", toEther(mUsdBalanceAfter)); | ||||
| 
 | ||||
|   expect(imUsdVaultBalanceAfter).to.be.eq(imUsdVaultBalanceBefore.sub(withdrawAmount)); | ||||
|   expect(mUsdBalanceAfter).to.gt(mUsdBalanceBefore); | ||||
| }; | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Dimitri
						Dimitri