735546619e
Signed-off-by: T-Hax <>
199 lines
7.4 KiB
TypeScript
199 lines
7.4 KiB
TypeScript
import { constants, Wallet } from 'ethers'
|
|
import { waffle, ethers } from 'hardhat'
|
|
|
|
import { Fixture } from 'ethereum-waffle'
|
|
import { SelfPermitTest, TestERC20PermitAllowed } from '../typechain'
|
|
import { expect } from 'chai'
|
|
import { getPermitSignature } from './shared/permit'
|
|
|
|
describe('SelfPermit', () => {
|
|
let wallet: Wallet
|
|
let other: Wallet
|
|
|
|
const fixture: Fixture<{
|
|
token: TestERC20PermitAllowed
|
|
selfPermitTest: SelfPermitTest
|
|
}> = async (wallets, provider) => {
|
|
const tokenFactory = await ethers.getContractFactory('TestERC20PermitAllowed')
|
|
const token = (await tokenFactory.deploy(0)) as TestERC20PermitAllowed
|
|
|
|
const selfPermitTestFactory = await ethers.getContractFactory('SelfPermitTest')
|
|
const selfPermitTest = (await selfPermitTestFactory.deploy()) as SelfPermitTest
|
|
|
|
return {
|
|
token,
|
|
selfPermitTest,
|
|
}
|
|
}
|
|
|
|
let token: TestERC20PermitAllowed
|
|
let selfPermitTest: SelfPermitTest
|
|
|
|
let loadFixture: ReturnType<typeof waffle.createFixtureLoader>
|
|
|
|
before('create fixture loader', async () => {
|
|
const wallets = await (ethers as any).getSigners()
|
|
;[wallet, other] = wallets
|
|
loadFixture = waffle.createFixtureLoader(wallets)
|
|
})
|
|
|
|
beforeEach('load fixture', async () => {
|
|
;({ token, selfPermitTest } = await loadFixture(fixture))
|
|
})
|
|
|
|
it('#permit', async () => {
|
|
const value = 123
|
|
|
|
const { v, r, s } = await getPermitSignature(wallet, token, other.address, value)
|
|
|
|
expect(await token.allowance(wallet.address, other.address)).to.be.eq(0)
|
|
await token['permit(address,address,uint256,uint256,uint8,bytes32,bytes32)'](
|
|
wallet.address,
|
|
other.address,
|
|
value,
|
|
constants.MaxUint256,
|
|
v,
|
|
r,
|
|
s
|
|
)
|
|
expect(await token.allowance(wallet.address, other.address)).to.be.eq(value)
|
|
})
|
|
|
|
describe('#selfPermit', () => {
|
|
const value = 456
|
|
|
|
it('works', async () => {
|
|
const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, value)
|
|
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0)
|
|
await selfPermitTest.selfPermit(token.address, value, constants.MaxUint256, v, r, s)
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(value)
|
|
})
|
|
|
|
it('fails if permit is submitted externally', async () => {
|
|
const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, value)
|
|
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0)
|
|
await token['permit(address,address,uint256,uint256,uint8,bytes32,bytes32)'](
|
|
wallet.address,
|
|
selfPermitTest.address,
|
|
value,
|
|
constants.MaxUint256,
|
|
v,
|
|
r,
|
|
s
|
|
)
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(value)
|
|
|
|
await expect(selfPermitTest.selfPermit(token.address, value, constants.MaxUint256, v, r, s)).to.be.revertedWith(
|
|
'ERC20Permit: invalid signature'
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('#selfPermitIfNecessary', () => {
|
|
const value = 789
|
|
|
|
it('works', async () => {
|
|
const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, value)
|
|
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0)
|
|
await selfPermitTest.selfPermitIfNecessary(token.address, value, constants.MaxUint256, v, r, s)
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(value)
|
|
})
|
|
|
|
it('does not fail if permit is submitted externally', async () => {
|
|
const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, value)
|
|
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0)
|
|
await token['permit(address,address,uint256,uint256,uint8,bytes32,bytes32)'](
|
|
wallet.address,
|
|
selfPermitTest.address,
|
|
value,
|
|
constants.MaxUint256,
|
|
v,
|
|
r,
|
|
s
|
|
)
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(value)
|
|
|
|
await selfPermitTest.selfPermitIfNecessary(token.address, value, constants.MaxUint256, v, r, s)
|
|
})
|
|
})
|
|
|
|
describe('#selfPermitAllowed', () => {
|
|
it('works', async () => {
|
|
const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, constants.MaxUint256)
|
|
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0)
|
|
await expect(selfPermitTest.selfPermitAllowed(token.address, 0, constants.MaxUint256, v, r, s))
|
|
.to.emit(token, 'Approval')
|
|
.withArgs(wallet.address, selfPermitTest.address, constants.MaxUint256)
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(constants.MaxUint256)
|
|
})
|
|
|
|
it('fails if permit is submitted externally', async () => {
|
|
const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, constants.MaxUint256)
|
|
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0)
|
|
await token['permit(address,address,uint256,uint256,bool,uint8,bytes32,bytes32)'](
|
|
wallet.address,
|
|
selfPermitTest.address,
|
|
0,
|
|
constants.MaxUint256,
|
|
true,
|
|
v,
|
|
r,
|
|
s
|
|
)
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(constants.MaxUint256)
|
|
|
|
await expect(
|
|
selfPermitTest.selfPermitAllowed(token.address, 0, constants.MaxUint256, v, r, s)
|
|
).to.be.revertedWith('TestERC20PermitAllowed::permit: wrong nonce')
|
|
})
|
|
})
|
|
|
|
describe('#selfPermitAllowedIfNecessary', () => {
|
|
it('works', async () => {
|
|
const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, constants.MaxUint256)
|
|
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.eq(0)
|
|
await expect(selfPermitTest.selfPermitAllowedIfNecessary(token.address, 0, constants.MaxUint256, v, r, s))
|
|
.to.emit(token, 'Approval')
|
|
.withArgs(wallet.address, selfPermitTest.address, constants.MaxUint256)
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.eq(constants.MaxUint256)
|
|
})
|
|
|
|
it('skips if already max approved', async () => {
|
|
const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, constants.MaxUint256)
|
|
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0)
|
|
await token.approve(selfPermitTest.address, constants.MaxUint256)
|
|
await expect(
|
|
selfPermitTest.selfPermitAllowedIfNecessary(token.address, 0, constants.MaxUint256, v, r, s)
|
|
).to.not.emit(token, 'Approval')
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.eq(constants.MaxUint256)
|
|
})
|
|
|
|
it('does not fail if permit is submitted externally', async () => {
|
|
const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, constants.MaxUint256)
|
|
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0)
|
|
await token['permit(address,address,uint256,uint256,bool,uint8,bytes32,bytes32)'](
|
|
wallet.address,
|
|
selfPermitTest.address,
|
|
0,
|
|
constants.MaxUint256,
|
|
true,
|
|
v,
|
|
r,
|
|
s
|
|
)
|
|
expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(constants.MaxUint256)
|
|
|
|
await selfPermitTest.selfPermitAllowedIfNecessary(token.address, 0, constants.MaxUint256, v, r, s)
|
|
})
|
|
})
|
|
})
|