mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
313 lines
9.3 KiB
TypeScript
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');
|
||
|
});
|
||
|
});
|