@dydxfoundation/governance
Version:
dYdX governance smart contracts
102 lines (101 loc) • 7.17 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const utils_1 = require("ethers/lib/utils");
const constants_1 = require("../../src/lib/constants");
const util_1 = require("../../src/lib/util");
const impersonate_account_1 = require("../../src/migrations/helpers/impersonate-account");
const types_1 = require("../../src/types");
const types_2 = require("../../types");
const StarkProxyV2__factory_1 = require("../../types/factories/StarkProxyV2__factory");
const describe_contract_1 = require("../helpers/describe-contract");
const evm_1 = require("../helpers/evm");
const get_address_with_role_1 = require("../helpers/get-address-with-role");
let mockStarkPerpetual;
let borrowerStarkProxy;
async function init(ctx) {
mockStarkPerpetual = ctx.starkPerpetual;
const ownerAddress = await (0, get_address_with_role_1.findAddressWithRole)(ctx.starkProxies[0], types_1.Role.OWNER_ROLE);
const borrower = await (0, impersonate_account_1.impersonateAndFundAccount)(ownerAddress);
borrowerStarkProxy = new StarkProxyV2__factory_1.StarkProxyV2__factory(borrower).attach(ctx.starkProxies[0].address);
}
(0, describe_contract_1.describeContractHardhatRevertBeforeEach)('SP2Owner', init, (ctx) => {
(0, describe_contract_1.describeContractForNetwork)('SP2Owner Hardhat Tests', ctx, types_1.NetworkName.hardhat, false, () => {
it('OWNER_ROLE can cancel and reclaim a deposit', async () => {
// Register STARK key and add it to the allowlist.
const mockStarkKey = 0;
const mockAssetType = 1;
const mockVaultId = 2;
await mockStarkPerpetual.registerUser(borrowerStarkProxy.address, mockStarkKey, []);
await borrowerStarkProxy.allowStarkKey(mockStarkKey);
await (0, chai_1.expect)(borrowerStarkProxy.depositCancel(mockStarkKey, mockAssetType, mockVaultId))
.to.emit(borrowerStarkProxy, 'DepositCanceled')
.withArgs(mockStarkKey, mockAssetType, mockVaultId, false);
await (0, chai_1.expect)(borrowerStarkProxy.depositReclaim(mockStarkKey, mockAssetType, mockVaultId))
.to.emit(borrowerStarkProxy, 'DepositReclaimed')
.withArgs(mockStarkKey, mockAssetType, mockVaultId, 0, false);
});
it('User without OWNER_ROLE cannot cancel or reclaim a deposit', async () => {
// Register STARK key and add it to the allowlist.
const mockStarkKey = 0;
const mockAssetType = 1;
const mockVaultId = 2;
await mockStarkPerpetual.registerUser(borrowerStarkProxy.address, mockStarkKey, []);
await borrowerStarkProxy.allowStarkKey(mockStarkKey);
const starkProxy = borrowerStarkProxy.connect(ctx.users[0]);
const userAddress = ctx.users[0].address.toLowerCase();
const accessControlError = `AccessControl: account ${userAddress} is missing role ${(0, util_1.getRole)(types_1.Role.OWNER_ROLE)}`;
await (0, chai_1.expect)(starkProxy.depositCancel(mockStarkKey, mockAssetType, mockVaultId))
.to.be.revertedWith(accessControlError);
await (0, chai_1.expect)(starkProxy.depositReclaim(mockStarkKey, mockAssetType, mockVaultId))
.to.be.revertedWith(accessControlError);
});
});
(0, describe_contract_1.describeContractForNetwork)('SP2Owner Hardhat Tests', ctx, types_1.NetworkName.hardhat, true, () => {
it('OWNER_ROLE can cancel faulty deposit and reclaim funds', async () => {
const wintermuteStarkProxy = ctx.starkProxies[0];
const ownerAddress = await (0, get_address_with_role_1.findAddressWithRole)(wintermuteStarkProxy, types_1.Role.OWNER_ROLE);
const owner = await (0, impersonate_account_1.impersonateAndFundAccount)(ownerAddress);
const starkProxy = new StarkProxyV2__factory_1.StarkProxyV2__factory(owner).attach(wintermuteStarkProxy.address);
const starkProxyBalanceBefore = await starkProxy.getTokenBalance();
const depositEvents = await starkProxy.queryFilter(starkProxy.filters.DepositedToExchange(null, null, null, null));
const badVaultId = '32';
const faultyDeposits = depositEvents.filter((e) => e.args.starkVaultId.toString() === badVaultId);
(0, chai_1.expect)(faultyDeposits.length).to.equal(1);
const starkKey = faultyDeposits[0].args.starkKey;
const assetType = faultyDeposits[0].args.starkAssetType;
await (0, chai_1.expect)(starkProxy.depositCancel(starkKey, assetType, badVaultId))
.to.emit(starkProxy, 'DepositCanceled')
.withArgs(starkKey, assetType, badVaultId, false);
const twoDaysSeconds = 2 * 24 * 60 * 60;
await (0, evm_1.increaseTimeAndMine)(twoDaysSeconds);
const lockedFunds = (0, utils_1.parseUnits)('50000000', 6);
await (0, chai_1.expect)(starkProxy.depositReclaim(starkKey, assetType, badVaultId))
.to.emit(starkProxy, 'DepositReclaimed')
.withArgs(starkKey, assetType, badVaultId, lockedFunds, false);
const starkProxyBalanceAfter = await starkProxy.getTokenBalance();
const diff = starkProxyBalanceAfter.sub(starkProxyBalanceBefore).toString();
(0, chai_1.expect)(diff).to.equal(lockedFunds);
});
it('OWNER_ROLE can force withdraw funds from the exchange', async () => {
const wintermuteStarkProxy = ctx.starkProxies[0];
const ownerAddress = await (0, get_address_with_role_1.findAddressWithRole)(wintermuteStarkProxy, types_1.Role.OWNER_ROLE);
const owner = await (0, impersonate_account_1.impersonateAndFundAccount)(ownerAddress);
const starkProxy = new StarkProxyV2__factory_1.StarkProxyV2__factory(owner).attach(wintermuteStarkProxy.address);
const depositEvents = await starkProxy.queryFilter(starkProxy.filters.DepositedToExchange(null, null, null, null));
const wintermuteVaultId = '50';
const deposits = depositEvents.filter((e) => e.args.starkVaultId.toString() === wintermuteVaultId);
(0, chai_1.expect)(deposits.length).to.be.be.gte(1);
const starkKey = deposits[0].args.starkKey;
const quantizedAmount = '1';
await (0, chai_1.expect)(starkProxy.forcedWithdrawalRequest(starkKey, wintermuteVaultId, quantizedAmount, false))
.to.emit(starkProxy, 'RequestedForcedWithdrawal')
.withArgs(starkKey, wintermuteVaultId, false);
const currentBlockTime = await (0, evm_1.latestBlockTimestamp)();
await (0, evm_1.incrementTimeToTimestamp)((constants_1.ONE_DAY_SECONDS * 14) + currentBlockTime);
const starkPerpetual = types_2.IFreezableStarkPerpetual__factory.connect(ctx.starkPerpetual.address, ctx.deployer);
await (0, chai_1.expect)(starkPerpetual.freezeRequest(starkKey, wintermuteVaultId, quantizedAmount))
.to.emit(starkPerpetual, 'LogFrozen');
});
});
});