aave-protocol-v2/test-suites/test-amm/atoken-permit.spec.ts
2021-02-23 10:59:02 -05:00

313 lines
9.3 KiB
TypeScript

import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../../helpers/constants';
import { BUIDLEREVM_CHAINID } from '../../helpers/buidler-constants';
import { buildPermitParams, getSignatureFromTypedData } from '../../helpers/contracts-helpers';
import { expect } from 'chai';
import { ethers } from 'ethers';
import { makeSuite, TestEnv } from './helpers/make-suite';
import { DRE } from '../../helpers/misc-utils';
import { waitForTx } from '../../helpers/misc-utils';
import { _TypedDataEncoder } from 'ethers/lib/utils';
const { parseEther } = ethers.utils;
makeSuite('AToken: Permit', (testEnv: TestEnv) => {
it('Checks the domain separator', async () => {
const { aDai } = testEnv;
const separator = await aDai.DOMAIN_SEPARATOR();
const domain = {
name: await aDai.name(),
version: '1',
chainId: DRE.network.config.chainId,
verifyingContract: aDai.address,
};
const domainSeparator = _TypedDataEncoder.hashDomain(domain);
expect(separator).to.be.equal(domainSeparator, 'Invalid domain separator');
});
it('Get aDAI for tests', async () => {
const { dai, pool, deployer } = testEnv;
await dai.mint(parseEther('20000'));
await dai.approve(pool.address, parseEther('20000'));
await pool.deposit(dai.address, parseEther('20000'), deployer.address, 0);
});
it('Reverts submitting a permit with 0 expiration', async () => {
const { aDai, deployer, users } = testEnv;
const owner = deployer;
const spender = users[1];
const tokenName = await aDai.name();
const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
const expiration = 0;
const nonce = (await aDai._nonces(owner.address)).toNumber();
const permitAmount = ethers.utils.parseEther('2').toString();
const msgParams = buildPermitParams(
chainId,
aDai.address,
'1',
tokenName,
owner.address,
spender.address,
nonce,
permitAmount,
expiration.toFixed()
);
const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
if (!ownerPrivateKey) {
throw new Error('INVALID_OWNER_PK');
}
expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
'0',
'INVALID_ALLOWANCE_BEFORE_PERMIT'
);
const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
await expect(
aDai
.connect(spender.signer)
.permit(owner.address, spender.address, permitAmount, expiration, v, r, s)
).to.be.revertedWith('INVALID_EXPIRATION');
expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
'0',
'INVALID_ALLOWANCE_AFTER_PERMIT'
);
});
it('Submits a permit with maximum expiration length', async () => {
const { aDai, deployer, users } = testEnv;
const owner = deployer;
const spender = users[1];
const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
const deadline = MAX_UINT_AMOUNT;
const nonce = (await aDai._nonces(owner.address)).toNumber();
const permitAmount = parseEther('2').toString();
const msgParams = buildPermitParams(
chainId,
aDai.address,
'1',
await aDai.name(),
owner.address,
spender.address,
nonce,
deadline,
permitAmount
);
const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
if (!ownerPrivateKey) {
throw new Error('INVALID_OWNER_PK');
}
expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
'0',
'INVALID_ALLOWANCE_BEFORE_PERMIT'
);
const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
await waitForTx(
await aDai
.connect(spender.signer)
.permit(owner.address, spender.address, permitAmount, deadline, v, r, s)
);
expect((await aDai._nonces(owner.address)).toNumber()).to.be.equal(1);
});
it('Cancels the previous permit', async () => {
const { aDai, deployer, users } = testEnv;
const owner = deployer;
const spender = users[1];
const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
const deadline = MAX_UINT_AMOUNT;
const nonce = (await aDai._nonces(owner.address)).toNumber();
const permitAmount = '0';
const msgParams = buildPermitParams(
chainId,
aDai.address,
'1',
await aDai.name(),
owner.address,
spender.address,
nonce,
deadline,
permitAmount
);
const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
if (!ownerPrivateKey) {
throw new Error('INVALID_OWNER_PK');
}
const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
ethers.utils.parseEther('2'),
'INVALID_ALLOWANCE_BEFORE_PERMIT'
);
await waitForTx(
await aDai
.connect(spender.signer)
.permit(owner.address, spender.address, permitAmount, deadline, v, r, s)
);
expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal(
permitAmount,
'INVALID_ALLOWANCE_AFTER_PERMIT'
);
expect((await aDai._nonces(owner.address)).toNumber()).to.be.equal(2);
});
it('Tries to submit a permit with invalid nonce', async () => {
const { aDai, deployer, users } = testEnv;
const owner = deployer;
const spender = users[1];
const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
const deadline = MAX_UINT_AMOUNT;
const nonce = 1000;
const permitAmount = '0';
const msgParams = buildPermitParams(
chainId,
aDai.address,
'1',
await aDai.name(),
owner.address,
spender.address,
nonce,
deadline,
permitAmount
);
const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
if (!ownerPrivateKey) {
throw new Error('INVALID_OWNER_PK');
}
const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
await expect(
aDai
.connect(spender.signer)
.permit(owner.address, spender.address, permitAmount, deadline, v, r, s)
).to.be.revertedWith('INVALID_SIGNATURE');
});
it('Tries to submit a permit with invalid expiration (previous to the current block)', async () => {
const { aDai, deployer, users } = testEnv;
const owner = deployer;
const spender = users[1];
const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
const expiration = '1';
const nonce = (await aDai._nonces(owner.address)).toNumber();
const permitAmount = '0';
const msgParams = buildPermitParams(
chainId,
aDai.address,
'1',
await aDai.name(),
owner.address,
spender.address,
nonce,
expiration,
permitAmount
);
const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
if (!ownerPrivateKey) {
throw new Error('INVALID_OWNER_PK');
}
const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
await expect(
aDai
.connect(spender.signer)
.permit(owner.address, spender.address, expiration, permitAmount, v, r, s)
).to.be.revertedWith('INVALID_EXPIRATION');
});
it('Tries to submit a permit with invalid signature', async () => {
const { aDai, deployer, users } = testEnv;
const owner = deployer;
const spender = users[1];
const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
const deadline = MAX_UINT_AMOUNT;
const nonce = (await aDai._nonces(owner.address)).toNumber();
const permitAmount = '0';
const msgParams = buildPermitParams(
chainId,
aDai.address,
'1',
await aDai.name(),
owner.address,
spender.address,
nonce,
deadline,
permitAmount
);
const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
if (!ownerPrivateKey) {
throw new Error('INVALID_OWNER_PK');
}
const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
await expect(
aDai
.connect(spender.signer)
.permit(owner.address, ZERO_ADDRESS, permitAmount, deadline, v, r, s)
).to.be.revertedWith('INVALID_SIGNATURE');
});
it('Tries to submit a permit with invalid owner', async () => {
const { aDai, deployer, users } = testEnv;
const owner = deployer;
const spender = users[1];
const chainId = DRE.network.config.chainId || BUIDLEREVM_CHAINID;
const expiration = MAX_UINT_AMOUNT;
const nonce = (await aDai._nonces(owner.address)).toNumber();
const permitAmount = '0';
const msgParams = buildPermitParams(
chainId,
aDai.address,
'1',
await aDai.name(),
owner.address,
spender.address,
nonce,
expiration,
permitAmount
);
const ownerPrivateKey = require('../../test-wallets.js').accounts[0].secretKey;
if (!ownerPrivateKey) {
throw new Error('INVALID_OWNER_PK');
}
const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams);
await expect(
aDai
.connect(spender.signer)
.permit(ZERO_ADDRESS, spender.address, expiration, permitAmount, v, r, s)
).to.be.revertedWith('INVALID_OWNER');
});
});