aave-protocol-v2/test/atoken-permit.spec.ts
2020-09-15 17:24:50 +02:00

316 lines
9.2 KiB
TypeScript

import {MAX_UINT_AMOUNT, ZERO_ADDRESS, BUIDLEREVM_CHAINID} from '../helpers/constants';
import {buildPermitParams, getSignatureFromTypedData} from '../helpers/contracts-helpers';
import {expect} from 'chai';
import {ethers} from 'ethers';
import {eEthereumNetwork} from '../helpers/types';
import {makeSuite, TestEnv} from './helpers/make-suite';
import {BRE} from '../helpers/misc-utils';
import {
ConfigNames,
getATokenDomainSeparatorPerNetwork,
loadPoolConfig,
} from '../helpers/configuration';
import {waitForTx} from '../helpers/misc-utils';
const {parseEther} = ethers.utils;
makeSuite('AToken: Permit', (testEnv: TestEnv) => {
const poolConfig = loadPoolConfig(ConfigNames.Commons);
it('Checks the domain separator', async () => {
const DOMAIN_SEPARATOR_ENCODED = getATokenDomainSeparatorPerNetwork(
eEthereumNetwork.buidlerevm,
poolConfig
);
const {aDai} = testEnv;
const separator = await aDai.DOMAIN_SEPARATOR();
expect(separator).to.be.equal(DOMAIN_SEPARATOR_ENCODED, 'Invalid domain separator');
});
it('Get aDAI for tests', async () => {
const {dai, deployer, pool} = 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 = BRE.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 = BRE.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 = BRE.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 = BRE.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 = BRE.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 = BRE.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 = BRE.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');
});
});