2021-02-07 03:10:29 +00:00
|
|
|
import { TestEnv, SignerWithAddress } from './make-suite';
|
|
|
|
import {
|
|
|
|
mint,
|
|
|
|
approve,
|
|
|
|
deposit,
|
|
|
|
borrow,
|
|
|
|
withdraw,
|
|
|
|
repay,
|
|
|
|
setUseAsCollateral,
|
|
|
|
swapBorrowRateMode,
|
|
|
|
rebalanceStableBorrowRate,
|
|
|
|
delegateBorrowAllowance,
|
2021-04-06 12:55:28 +00:00
|
|
|
repayWithPermit,
|
|
|
|
depositWithPermit,
|
2021-02-07 03:10:29 +00:00
|
|
|
} from './actions';
|
|
|
|
import { RateMode } from '../../../helpers/types';
|
2021-04-06 12:55:28 +00:00
|
|
|
import { Wallet } from '@ethersproject/wallet';
|
2021-02-07 03:10:29 +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) => {
|
|
|
|
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 = 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)];
|
|
|
|
|
2021-04-06 12:55:28 +00:00
|
|
|
const userPrivateKey = require('../../../test-wallets.js').accounts[parseInt(userIndex) + 1]
|
|
|
|
.secretKey;
|
|
|
|
if (!userPrivateKey) {
|
|
|
|
throw new Error('INVALID_OWNER_PK');
|
|
|
|
}
|
|
|
|
|
2021-02-07 03:10:29 +00:00
|
|
|
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, onBehalfOf: onBehalfOfIndex } = action.args;
|
|
|
|
const onBehalfOf = onBehalfOfIndex
|
|
|
|
? users[parseInt(onBehalfOfIndex)].address
|
|
|
|
: user.address;
|
|
|
|
|
|
|
|
if (!amount || amount === '') {
|
|
|
|
throw `Invalid amount to deposit into the ${reserve} reserve`;
|
|
|
|
}
|
|
|
|
|
|
|
|
await deposit(
|
|
|
|
reserve,
|
|
|
|
amount,
|
|
|
|
user,
|
|
|
|
onBehalfOf,
|
|
|
|
sendValue,
|
|
|
|
expected,
|
|
|
|
testEnv,
|
|
|
|
revertMessage
|
|
|
|
);
|
|
|
|
}
|
|
|
|
break;
|
2021-04-06 12:55:28 +00:00
|
|
|
case 'depositWithPermit':
|
|
|
|
{
|
|
|
|
const { amount, sendValue, onBehalfOf: onBehalfOfIndex } = action.args;
|
|
|
|
const onBehalfOf = onBehalfOfIndex
|
|
|
|
? users[parseInt(onBehalfOfIndex)].address
|
|
|
|
: user.address;
|
|
|
|
|
|
|
|
if (!amount || amount === '') {
|
|
|
|
throw `Invalid amount to deposit into the ${reserve} reserve`;
|
|
|
|
}
|
|
|
|
|
|
|
|
await depositWithPermit(
|
|
|
|
reserve,
|
|
|
|
amount,
|
|
|
|
user,
|
|
|
|
userPrivateKey,
|
|
|
|
onBehalfOf,
|
|
|
|
sendValue,
|
|
|
|
expected,
|
|
|
|
testEnv,
|
|
|
|
revertMessage
|
|
|
|
);
|
|
|
|
}
|
|
|
|
break;
|
2021-02-07 03:10:29 +00:00
|
|
|
|
|
|
|
case 'delegateBorrowAllowance':
|
|
|
|
{
|
|
|
|
const { amount, toUser: toUserIndex } = action.args;
|
|
|
|
const toUser = users[parseInt(toUserIndex, 10)].address;
|
|
|
|
if (!amount || amount === '') {
|
|
|
|
throw `Invalid amount to deposit into the ${reserve} reserve`;
|
|
|
|
}
|
|
|
|
|
|
|
|
await delegateBorrowAllowance(
|
|
|
|
reserve,
|
|
|
|
amount,
|
|
|
|
rateMode,
|
|
|
|
user,
|
|
|
|
toUser,
|
|
|
|
expected,
|
|
|
|
testEnv,
|
|
|
|
revertMessage
|
|
|
|
);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'withdraw':
|
|
|
|
{
|
|
|
|
const { amount } = action.args;
|
|
|
|
|
|
|
|
if (!amount || amount === '') {
|
|
|
|
throw `Invalid amount to withdraw from the ${reserve} reserve`;
|
|
|
|
}
|
|
|
|
|
|
|
|
await withdraw(reserve, amount, user, expected, testEnv, revertMessage);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'borrow':
|
|
|
|
{
|
|
|
|
const { amount, timeTravel, onBehalfOf: onBehalfOfIndex } = action.args;
|
|
|
|
|
|
|
|
const onBehalfOf = onBehalfOfIndex
|
|
|
|
? users[parseInt(onBehalfOfIndex)].address
|
|
|
|
: user.address;
|
|
|
|
|
|
|
|
if (!amount || amount === '') {
|
|
|
|
throw `Invalid amount to borrow from the ${reserve} reserve`;
|
|
|
|
}
|
|
|
|
|
|
|
|
await borrow(
|
|
|
|
reserve,
|
|
|
|
amount,
|
|
|
|
rateMode,
|
|
|
|
user,
|
|
|
|
onBehalfOf,
|
|
|
|
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;
|
|
|
|
|
2021-04-06 12:55:28 +00:00
|
|
|
case 'repayWithPermit':
|
|
|
|
{
|
|
|
|
const { amount, borrowRateMode, sendValue, deadline } = 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 repayWithPermit(
|
|
|
|
reserve,
|
|
|
|
amount,
|
|
|
|
rateMode,
|
|
|
|
user,
|
|
|
|
userPrivateKey,
|
|
|
|
userToRepayOnBehalf,
|
|
|
|
sendValue,
|
|
|
|
expected,
|
|
|
|
testEnv,
|
|
|
|
revertMessage
|
|
|
|
);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2021-02-07 03:10:29 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
default:
|
|
|
|
throw `Invalid action requested: ${name}`;
|
|
|
|
}
|
|
|
|
};
|