aave-protocol-v2/test/helpers/scenario-engine.ts

289 lines
6.8 KiB
TypeScript
Raw Normal View History

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} = 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`;
}
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, borrowRateMode, timeTravel} = action.args;
if (!amount || amount === "") {
throw `Invalid amount to borrow from the ${reserve} reserve`;
}
let rateMode: string = RateMode.None;
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";
}
await borrow(
reserve,
amount,
rateMode,
user,
timeTravel,
expected,
testEnv,
revertMessage
);
}
break;
case "repay":
{
const {amount, 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,
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, 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}`;
}
};