import {TestEnv, SignerWithAddress} from "./make-suite"; import { mint, approve, deposit, borrow, redeem, repay, setUseAsCollateral, swapBorrowRateMode, rebalanceStableBorrowRate, redirectInterestStream, redirectInterestStreamOf, allowInterestRedirectionTo, } from "./actions"; import {RateMode} from "../../helpers/types"; export interface Action { name: string; args?: any; expected: string; revertMessage?: string; } export interface Story { description: string; actions: Action[]; } export interface Scenario { title: string; description: string; stories: Story[]; } export const executeStory = async (story: Story, testEnv: TestEnv) => { for (const action of story.actions) { const {users} = testEnv; await executeAction(action, users, testEnv); } }; const executeAction = async ( action: Action, users: SignerWithAddress[], testEnv: TestEnv ) => { const {reserve, user: userIndex, borrowRateMode} = action.args; const {name, expected, revertMessage} = action; if (!name || name === "") { throw "Action name is missing"; } if (!reserve || reserve === "") { throw "Invalid reserve selected for deposit"; } if (!userIndex || userIndex === "") { throw `Invalid user selected to deposit into the ${reserve} reserve`; } if (!expected || expected === "") { throw `An expected resut for action ${name} is required`; } let rateMode: string = RateMode.None; if(borrowRateMode) { if (borrowRateMode === "none") { RateMode.None; } else if (borrowRateMode === "stable") { rateMode = RateMode.Stable; } else if (borrowRateMode === "variable") { rateMode = RateMode.Variable; } else { //random value, to test improper selection of the parameter rateMode = "4"; } } const user = users[parseInt(userIndex)]; switch (name) { case "mint": const {amount} = action.args; if (!amount || amount === "") { throw `Invalid amount of ${reserve} to mint`; } await mint(reserve, amount, user); break; case "approve": await approve(reserve, user, testEnv); break; case "deposit": { const {amount, sendValue} = action.args; if (!amount || amount === "") { throw `Invalid amount to deposit into the ${reserve} reserve`; } await deposit( reserve, amount, user, sendValue, expected, testEnv, revertMessage ); } break; case "redeem": { const {amount} = action.args; if (!amount || amount === "") { throw `Invalid amount to redeem from the ${reserve} reserve`; } await redeem(reserve, amount, user, expected, testEnv, revertMessage); } break; case "borrow": { const {amount, timeTravel} = action.args; if (!amount || amount === "") { throw `Invalid amount to borrow from the ${reserve} reserve`; } await borrow( reserve, amount, rateMode, user, timeTravel, expected, testEnv, revertMessage ); } break; case "repay": { const {amount, borrowRateMode, sendValue} = action.args; let {onBehalfOf: onBehalfOfIndex} = action.args; if (!amount || amount === "") { throw `Invalid amount to repay into the ${reserve} reserve`; } let userToRepayOnBehalf: SignerWithAddress; if (!onBehalfOfIndex || onBehalfOfIndex === "") { console.log( "WARNING: No onBehalfOf specified for a repay action. Defaulting to the repayer address" ); userToRepayOnBehalf = user; } else { userToRepayOnBehalf = users[parseInt(onBehalfOfIndex)]; } await repay( reserve, amount, rateMode, user, userToRepayOnBehalf, sendValue, expected, testEnv, revertMessage ); } break; case "setUseAsCollateral": { const {useAsCollateral} = action.args; if (!useAsCollateral || useAsCollateral === "") { throw `A valid value for useAsCollateral needs to be set when calling setUseReserveAsCollateral on reserve ${reserve}`; } await setUseAsCollateral( reserve, user, useAsCollateral, expected, testEnv, revertMessage ); } break; case "swapBorrowRateMode": await swapBorrowRateMode(reserve, user, rateMode, expected, testEnv, revertMessage); break; case "rebalanceStableBorrowRate": { const {target: targetIndex} = action.args; if (!targetIndex || targetIndex === "") { throw `A target must be selected when trying to rebalance a stable rate`; } const target = users[parseInt(targetIndex)]; await rebalanceStableBorrowRate( reserve, user, target, expected, testEnv, revertMessage ); } break; case "redirectInterestStream": { const {to: toIndex} = action.args; if (!toIndex || toIndex === "") { throw `A target must be selected when trying to redirect the interest`; } const toUser = users[parseInt(toIndex)]; await redirectInterestStream( reserve, user, toUser.address, expected, testEnv, revertMessage ); } break; case "redirectInterestStreamOf": { const {from: fromIndex, to: toIndex} = action.args; if (!fromIndex || fromIndex === "") { throw `A from address must be specified when trying to redirect the interest`; } if (!toIndex || toIndex === "") { throw `A target must be selected when trying to redirect the interest`; } const toUser = users[parseInt(toIndex)]; const fromUser = users[parseInt(fromIndex)]; await redirectInterestStreamOf( reserve, user, fromUser.address, toUser.address, expected, testEnv, revertMessage ); } break; case "allowInterestRedirectionTo": { const {to: toIndex} = action.args; if (!toIndex || toIndex === "") { throw `A target must be selected when trying to redirect the interest`; } const toUser = users[parseInt(toIndex)]; await allowInterestRedirectionTo( reserve, user, toUser.address, expected, testEnv, revertMessage ); } break; default: throw `Invalid action requested: ${name}`; } };