UNPKG

@dydxfoundation/governance

Version:
66 lines (65 loc) 3.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const chai_1 = require("chai"); const types_1 = require("../../src/types"); const describe_contract_1 = require("../helpers/describe-contract"); const staking_helper_1 = require("../helpers/staking-helper"); const stakerInitialBalance = 1000000; // Users. let stakers; let operator; // Smart contract callers. let operatorSigner; let contract; async function init(ctx) { // Users. stakers = ctx.users.slice(1, 3); // 2 stakers operator = ctx.users[3]; operatorSigner = ctx.safetyModule.connect(operator); // Use helper class to automatically check contract invariants after every update. contract = new staking_helper_1.StakingHelper(ctx, ctx.safetyModule, ctx.dydxToken, ctx.rewardsTreasury.address, ctx.deployer, ctx.deployer, stakers.concat([ctx.deployer, operator]), true); // Mint staked tokens and set allowances. await Promise.all(stakers.map((s) => contract.mintAndApprove(s, stakerInitialBalance))); } (0, describe_contract_1.describeContractHardhatRevertBeforeEach)('SM1Operator', init, (ctx) => { before(() => { contract.saveSnapshot('main'); }); afterEach(() => { contract.loadSnapshot('main'); }); describe('Stake and claim operators', () => { it('The stake operator can withdraw stake on behalf of a user', async () => { const largeBalance = stakerInitialBalance * 100; await contract.addOperator(operator, types_1.Role.STAKE_OPERATOR_ROLE); await contract.mintAndApprove(operator, largeBalance); // Stake using the operator's funds, and withdraw back to the operator. await operatorSigner.stakeFor(stakers[0].address, largeBalance); await operatorSigner.requestWithdrawalFor(stakers[0].address, largeBalance); await contract.elapseEpoch(); await operatorSigner.withdrawStakeFor(stakers[0].address, operator.address, largeBalance); (0, chai_1.expect)(await ctx.dydxToken.balanceOf(operator.address)).to.equal(largeBalance); }); it('Another user can stake on behalf of a user, but not withdraw', async () => { const stakerSigner = ctx.safetyModule.connect(stakers[1]); await stakerSigner.stakeFor(stakers[0].address, stakerInitialBalance); await (0, chai_1.expect)(stakerSigner.requestWithdrawalFor(stakers[0].address, 1)).to.be.revertedWith('AccessControl: account'); }); it('The claim operator can claim rewards on behalf of a user', async () => { // Safety module rewards first begin in the middle of the epoch. // Advance to the start of an epoch. await contract.elapseEpoch(); await contract.addOperator(operator, types_1.Role.CLAIM_OPERATOR_ROLE); const initialBalance = await ctx.dydxToken.balanceOf(operator.address); const rewardsRate = 16; await contract.setRewardsPerSecond(rewardsRate); await contract.stake(stakers[0], stakerInitialBalance); await contract.elapseEpoch(); await operatorSigner.claimRewardsFor(stakers[0].address, operator.address); const finalBalance = await ctx.dydxToken.balanceOf(operator.address); const amountReceived = finalBalance.sub(initialBalance).toNumber(); const expectedReceived = ctx.config.EPOCH_LENGTH * rewardsRate; (0, chai_1.expect)(amountReceived).to.be.closeTo(expectedReceived, 100); }); }); });