2020-06-12 20:12:53 +00:00
|
|
|
import {TestEnv, SignerWithAddress} from "./make-suite";
|
2020-06-13 09:12:49 +00:00
|
|
|
import {
|
|
|
|
mint,
|
|
|
|
approve,
|
|
|
|
deposit,
|
|
|
|
borrow,
|
|
|
|
redeem,
|
|
|
|
repay,
|
|
|
|
setUseAsCollateral,
|
|
|
|
swapBorrowRateMode,
|
|
|
|
rebalanceStableBorrowRate,
|
|
|
|
redirectInterestStream,
|
|
|
|
redirectInterestStreamOf,
|
|
|
|
allowInterestRedirectionTo,
|
|
|
|
} from "./actions";
|
|
|
|
import {RateMode} from "../../helpers/types";
|
2020-06-12 20:12:53 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
) => {
|
2020-07-07 10:07:31 +00:00
|
|
|
const {reserve, user: userIndex, borrowRateMode} = action.args;
|
2020-06-12 20:12:53 +00:00
|
|
|
const {name, expected, revertMessage} = action;
|
|
|
|
|
|
|
|
if (!name || name === "") {
|
|
|
|
throw "Action name is missing";
|
|
|
|
}
|
|
|
|
if (!reserve || reserve === "") {
|
|
|
|
throw "Invalid reserve selected for deposit";
|
|
|
|
}
|
2020-06-13 09:12:49 +00:00
|
|
|
if (!userIndex || userIndex === "") {
|
2020-06-12 20:12:53 +00:00
|
|
|
throw `Invalid user selected to deposit into the ${reserve} reserve`;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!expected || expected === "") {
|
|
|
|
throw `An expected resut for action ${name} is required`;
|
|
|
|
}
|
|
|
|
|
2020-07-07 10:07:31 +00:00
|
|
|
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";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-13 09:12:49 +00:00
|
|
|
const user = users[parseInt(userIndex)];
|
2020-06-12 20:12:53 +00:00
|
|
|
|
|
|
|
switch (name) {
|
|
|
|
case "mint":
|
|
|
|
const {amount} = action.args;
|
|
|
|
|
|
|
|
if (!amount || amount === "") {
|
|
|
|
throw `Invalid amount of ${reserve} to mint`;
|
|
|
|
}
|
|
|
|
|
2020-06-13 09:12:49 +00:00
|
|
|
await mint(reserve, amount, user);
|
2020-06-12 20:12:53 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case "approve":
|
2020-06-13 09:12:49 +00:00
|
|
|
await approve(reserve, user, testEnv);
|
2020-06-12 20:12:53 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case "deposit":
|
|
|
|
{
|
|
|
|
const {amount, sendValue} = action.args;
|
|
|
|
|
|
|
|
if (!amount || amount === "") {
|
|
|
|
throw `Invalid amount to deposit into the ${reserve} reserve`;
|
|
|
|
}
|
|
|
|
|
|
|
|
await deposit(
|
|
|
|
reserve,
|
|
|
|
amount,
|
2020-06-13 09:12:49 +00:00
|
|
|
user,
|
2020-06-12 20:12:53 +00:00
|
|
|
sendValue,
|
|
|
|
expected,
|
|
|
|
testEnv,
|
|
|
|
revertMessage
|
|
|
|
);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2020-06-13 09:12:49 +00:00
|
|
|
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":
|
|
|
|
{
|
2020-07-07 10:07:31 +00:00
|
|
|
const {amount, timeTravel} = action.args;
|
2020-06-13 09:12:49 +00:00
|
|
|
|
|
|
|
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":
|
|
|
|
{
|
2020-06-30 12:09:28 +00:00
|
|
|
const {amount, borrowRateMode, sendValue} = action.args;
|
2020-06-13 09:12:49 +00:00
|
|
|
let {onBehalfOf: onBehalfOfIndex} = action.args;
|
|
|
|
|
|
|
|
if (!amount || amount === "") {
|
|
|
|
throw `Invalid amount to repay into the ${reserve} reserve`;
|
|
|
|
}
|
2020-07-07 10:07:31 +00:00
|
|
|
|
2020-06-13 09:12:49 +00:00
|
|
|
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,
|
2020-06-30 12:09:28 +00:00
|
|
|
rateMode,
|
2020-06-13 09:12:49 +00:00
|
|
|
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":
|
2020-07-07 10:07:31 +00:00
|
|
|
await swapBorrowRateMode(reserve, user, rateMode, expected, testEnv, revertMessage);
|
2020-06-13 09:12:49 +00:00
|
|
|
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;
|
2020-06-12 20:12:53 +00:00
|
|
|
default:
|
|
|
|
throw `Invalid action requested: ${name}`;
|
|
|
|
}
|
|
|
|
};
|