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

305 lines
7.7 KiB
TypeScript
Raw Normal View History

import { TestEnv, SignerWithAddress } from './make-suite';
import {
mint,
approve,
deposit,
borrow,
withdraw,
repay,
setUseAsCollateral,
swapBorrowRateMode,
rebalanceStableBorrowRate,
delegateBorrowAllowance,
repayWithPermit,
depositWithPermit,
} from './actions';
import { RateMode } from '../../../helpers/types';
import { Wallet } from '@ethersproject/wallet';
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)];
const userPrivateKey = require('../../../test-wallets.js').accounts[parseInt(userIndex) + 1]
.secretKey;
if (!userPrivateKey) {
throw new Error('INVALID_OWNER_PK');
}
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;
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;
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;
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;
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}`;
}
};