UNPKG

@dydxfoundation/governance

Version:
146 lines (145 loc) 9.72 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const chai_1 = require("chai"); const utils_1 = require("ethers/lib/utils"); const config_1 = __importDefault(require("../../src/config")); const constants_1 = require("../../src/lib/constants"); const util_1 = require("../../src/lib/util"); const describe_contract_1 = require("../helpers/describe-contract"); const keys_1 = require("../helpers/keys"); const signature_helpers_1 = require("../helpers/signature-helpers"); const hre_1 = __importDefault(require("../hre")); const SAFETY_MODULE_EIP_712_DOMAIN_NAME = 'dYdX Safety Module'; let userKeys; function init() { userKeys = (0, keys_1.getUserKeys)(); } (0, describe_contract_1.describeContract)('Safety Module Staked DYDX - ERC20 Permit', init, (ctx) => { it('sanity check chain ID', async () => { // Skip when forking mainnet, since these won't match. if (!config_1.default.FORK_MAINNET) { const chainId = await (0, signature_helpers_1.getChainIdForSigning)(); const configChainId = hre_1.default.network.config.chainId; (0, chai_1.expect)(configChainId).to.be.equal(chainId); } }); it('Reverts submitting a permit with 0 expiration', async () => { const owner = ctx.users[0].address; const spender = ctx.users[1].address; const chainId = await (0, signature_helpers_1.getChainIdForSigning)(); const expiration = 0; const nonce = (await ctx.safetyModule.nonces(owner)).toNumber(); const permitAmount = (0, utils_1.parseEther)('2').toString(); const msgParams = (0, signature_helpers_1.buildPermitParams)(chainId, ctx.safetyModule.address, owner, spender, nonce, permitAmount, expiration.toFixed(), SAFETY_MODULE_EIP_712_DOMAIN_NAME); const ownerPrivateKey = userKeys[0]; (0, chai_1.expect)((await ctx.safetyModule.allowance(owner, spender)).toString()).to.be.equal('0', 'INVALID_ALLOWANCE_BEFORE_PERMIT'); const { v, r, s } = (0, signature_helpers_1.getSignatureFromTypedData)(ownerPrivateKey, msgParams); await (0, chai_1.expect)(ctx.safetyModule .connect(ctx.users[1]) .permit(owner, spender, permitAmount, expiration, v, r, s)).to.be.revertedWith('INVALID_EXPIRATION'); (0, chai_1.expect)((await ctx.safetyModule.allowance(owner, spender)).toString()).to.be.equal('0', 'INVALID_ALLOWANCE_AFTER_PERMIT'); }); it('Submits a permit with maximum expiration length', async () => { const owner = ctx.users[0].address; const spender = ctx.users[1].address; const chainId = await (0, signature_helpers_1.getChainIdForSigning)(); const deadline = constants_1.MAX_UINT_AMOUNT; const nonce = (await ctx.safetyModule.nonces(owner)).toNumber(); const permitAmount = (0, utils_1.parseEther)('2').toString(); const msgParams = (0, signature_helpers_1.buildPermitParams)(chainId, ctx.safetyModule.address, owner, spender, nonce, deadline, permitAmount, SAFETY_MODULE_EIP_712_DOMAIN_NAME); const ownerPrivateKey = userKeys[0]; (0, chai_1.expect)((await ctx.safetyModule.allowance(owner, spender)).toString()).to.be.equal('0', 'INVALID_ALLOWANCE_BEFORE_PERMIT'); const { v, r, s } = (0, signature_helpers_1.getSignatureFromTypedData)(ownerPrivateKey, msgParams); await (0, util_1.waitForTx)(await ctx.safetyModule .connect(ctx.users[1]) .permit(owner, spender, permitAmount, deadline, v, r, s)); (0, chai_1.expect)((await ctx.safetyModule.nonces(owner)).toNumber()).to.be.equal(1); }); it('Cancels the previous permit', async () => { const owner = ctx.users[0].address; const spender = ctx.users[1].address; const chainId = await (0, signature_helpers_1.getChainIdForSigning)(); const deadline = constants_1.MAX_UINT_AMOUNT; { const permitAmount = (0, utils_1.parseEther)('2').toString(); const nonce = (await ctx.safetyModule.nonces(owner)).toNumber(); const msgParams = (0, signature_helpers_1.buildPermitParams)(chainId, ctx.safetyModule.address, owner, spender, nonce, deadline, permitAmount, SAFETY_MODULE_EIP_712_DOMAIN_NAME); const ownerPrivateKey = userKeys[0]; (0, chai_1.expect)((await ctx.safetyModule.allowance(owner, spender)).toString()).to.be.equal('0', 'INVALID_ALLOWANCE_BEFORE_PERMIT'); const { v, r, s } = (0, signature_helpers_1.getSignatureFromTypedData)(ownerPrivateKey, msgParams); await ctx.safetyModule .connect(ctx.users[1]) .permit(owner, spender, permitAmount, deadline, v, r, s); } { const nonce = (await ctx.safetyModule.nonces(owner)).toNumber(); const permitAmount = '0'; const msgParams = (0, signature_helpers_1.buildPermitParams)(chainId, ctx.safetyModule.address, owner, spender, nonce, deadline, permitAmount, SAFETY_MODULE_EIP_712_DOMAIN_NAME); const ownerPrivateKey = userKeys[0]; const { v, r, s } = (0, signature_helpers_1.getSignatureFromTypedData)(ownerPrivateKey, msgParams); (0, chai_1.expect)((await ctx.safetyModule.allowance(owner, spender)).toString()).to.be.equal((0, utils_1.parseEther)('2'), 'INVALID_ALLOWANCE_BEFORE_PERMIT'); await (0, util_1.waitForTx)(await ctx.safetyModule .connect(ctx.users[1]) .permit(owner, spender, permitAmount, deadline, v, r, s)); (0, chai_1.expect)((await ctx.safetyModule.allowance(owner, spender)).toString()).to.be.equal(permitAmount, 'INVALID_ALLOWANCE_AFTER_PERMIT'); (0, chai_1.expect)((await ctx.safetyModule.nonces(owner)).toNumber()).to.be.equal(2); } }); it('Tries to submit a permit with invalid nonce', async () => { const owner = ctx.users[0].address; const spender = ctx.users[1].address; const chainId = await (0, signature_helpers_1.getChainIdForSigning)(); const deadline = constants_1.MAX_UINT_AMOUNT; const nonce = 1000; const permitAmount = '0'; const msgParams = (0, signature_helpers_1.buildPermitParams)(chainId, ctx.safetyModule.address, owner, spender, nonce, deadline, permitAmount, SAFETY_MODULE_EIP_712_DOMAIN_NAME); const ownerPrivateKey = userKeys[0]; const { v, r, s } = (0, signature_helpers_1.getSignatureFromTypedData)(ownerPrivateKey, msgParams); await (0, chai_1.expect)(ctx.safetyModule.connect(ctx.users[1]).permit(owner, spender, 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 owner = ctx.users[0].address; const spender = ctx.users[1].address; const chainId = await (0, signature_helpers_1.getChainIdForSigning)(); const expiration = '1'; const nonce = (await ctx.safetyModule.nonces(owner)).toNumber(); const permitAmount = '0'; const msgParams = (0, signature_helpers_1.buildPermitParams)(chainId, ctx.safetyModule.address, owner, spender, nonce, expiration, permitAmount, SAFETY_MODULE_EIP_712_DOMAIN_NAME); const ownerPrivateKey = userKeys[0]; const { v, r, s } = (0, signature_helpers_1.getSignatureFromTypedData)(ownerPrivateKey, msgParams); await (0, chai_1.expect)(ctx.safetyModule .connect(ctx.users[1]) .permit(owner, spender, expiration, permitAmount, v, r, s)).to.be.revertedWith('INVALID_EXPIRATION'); }); it('Tries to submit a permit with invalid signature', async () => { const owner = ctx.users[0].address; const spender = ctx.users[1].address; const chainId = await (0, signature_helpers_1.getChainIdForSigning)(); const deadline = constants_1.MAX_UINT_AMOUNT; const nonce = (await ctx.safetyModule.nonces(owner)).toNumber(); const permitAmount = '0'; const msgParams = (0, signature_helpers_1.buildPermitParams)(chainId, ctx.safetyModule.address, owner, spender, nonce, deadline, permitAmount, SAFETY_MODULE_EIP_712_DOMAIN_NAME); const ownerPrivateKey = userKeys[0]; const { v, r, s } = (0, signature_helpers_1.getSignatureFromTypedData)(ownerPrivateKey, msgParams); await (0, chai_1.expect)(ctx.safetyModule .connect(ctx.users[1]) .permit(owner, constants_1.ZERO_ADDRESS, permitAmount, deadline, v, r, s)).to.be.revertedWith('INVALID_SIGNATURE'); }); it('Tries to submit a permit with invalid owner', async () => { const owner = ctx.users[0].address; const spender = ctx.users[1].address; const chainId = await (0, signature_helpers_1.getChainIdForSigning)(); const expiration = constants_1.MAX_UINT_AMOUNT; const nonce = (await ctx.safetyModule.nonces(owner)).toNumber(); const permitAmount = '0'; const msgParams = (0, signature_helpers_1.buildPermitParams)(chainId, ctx.safetyModule.address, owner, spender, nonce, expiration, permitAmount, SAFETY_MODULE_EIP_712_DOMAIN_NAME); const ownerPrivateKey = userKeys[0]; const { v, r, s } = (0, signature_helpers_1.getSignatureFromTypedData)(ownerPrivateKey, msgParams); await (0, chai_1.expect)(ctx.safetyModule .connect(ctx.users[1]) .permit(constants_1.ZERO_ADDRESS, spender, expiration, permitAmount, v, r, s)).to.be.revertedWith('INVALID_OWNER'); }); });