430 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			430 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { ERC20Wrapper } from '@0x/contracts-asset-proxy';
 | |
| import { blockchainTests, describe } from '@0x/contracts-test-utils';
 | |
| import * as _ from 'lodash';
 | |
| 
 | |
| import { deployAndConfigureContractsAsync, StakingApiWrapper } from './utils/api_wrapper';
 | |
| import { CumulativeRewardTrackingSimulation, TestAction } from './utils/cumulative_reward_tracking_simulation';
 | |
| 
 | |
| // tslint:disable:no-unnecessary-type-assertion
 | |
| // tslint:disable:max-file-line-count
 | |
| blockchainTests.resets('Cumulative Reward Tracking', env => {
 | |
|     // tokens & addresses
 | |
|     let accounts: string[];
 | |
|     let owner: string;
 | |
|     // wrappers
 | |
|     let stakingApiWrapper: StakingApiWrapper;
 | |
|     let simulation: CumulativeRewardTrackingSimulation;
 | |
|     // let testWrapper: TestRewardBalancesContract;
 | |
|     let erc20Wrapper: ERC20Wrapper;
 | |
| 
 | |
|     // tests
 | |
|     before(async () => {
 | |
|         // create accounts
 | |
|         accounts = await env.getAccountAddressesAsync();
 | |
|         owner = accounts[0];
 | |
|         const actors = accounts.slice(1);
 | |
|         // set up ERC20Wrapper
 | |
|         erc20Wrapper = new ERC20Wrapper(env.provider, accounts, owner);
 | |
|         // deploy staking contracts
 | |
|         stakingApiWrapper = await deployAndConfigureContractsAsync(env, owner, erc20Wrapper);
 | |
|         simulation = new CumulativeRewardTrackingSimulation(stakingApiWrapper, actors);
 | |
|         await simulation.deployAndConfigureTestContractsAsync(env);
 | |
|     });
 | |
| 
 | |
|     describe('Tracking Cumulative Rewards (CR)', () => {
 | |
|         it('pool created at epoch 1', async () => {
 | |
|             await simulation.runTestAsync([], [TestAction.CreatePool], []);
 | |
|         });
 | |
|         it('pool created in epoch >1', async () => {
 | |
|             await simulation.runTestAsync([TestAction.Finalize], [TestAction.CreatePool], []);
 | |
|         });
 | |
|         it('delegating in the same epoch pool is created', async () => {
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Creates CR for epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Updates CR for epoch 1
 | |
|                     // Creates CR for epoch 2
 | |
|                     TestAction.Delegate,
 | |
|                 ],
 | |
|                 [{ event: 'SetCumulativeReward', epoch: 1 }],
 | |
|             );
 | |
|         });
 | |
|         it('re-delegating in the same epoch', async () => {
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Creates CR for epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Updates CR for epoch 1
 | |
|                     TestAction.Delegate,
 | |
|                     // Updates CR for epoch 1
 | |
|                     TestAction.Delegate,
 | |
|                 ],
 | |
|                 [{ event: 'SetCumulativeReward', epoch: 1 }],
 | |
|             );
 | |
|         });
 | |
|         it('delegating in new epoch', async () => {
 | |
|             // since there was no delegation in epoch 1 there is no longer a dependency on the CR for epoch 1
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Creates CR for epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                     // Moves to epoch 2
 | |
|                     TestAction.Finalize,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Creates a CR for epoch 2
 | |
|                     // Sets MRCR to epoch 2
 | |
|                     // Unsets the CR for epoch 1
 | |
|                     TestAction.Delegate,
 | |
|                 ],
 | |
|                 [{ event: 'SetCumulativeReward', epoch: 2 }],
 | |
|             );
 | |
|         });
 | |
|         it('re-delegating in a new epoch', async () => {
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Creates CR in epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                     // Updates CR for epoch 1
 | |
|                     // Creates CR for epoch 2
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 2
 | |
|                     TestAction.Finalize,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Updates CR for epoch 2
 | |
|                     // Sets MRCR to epoch 2
 | |
|                     TestAction.Delegate,
 | |
|                 ],
 | |
|                 [{ event: 'SetCumulativeReward', epoch: 2 }],
 | |
|             );
 | |
|         });
 | |
|         it('delegating in epoch 2 then again in epoch 3', async () => {
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Creates CR for epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                     // Moves to epoch 2
 | |
|                     TestAction.Finalize,
 | |
|                     // Creates CR for epoch 2
 | |
|                     // Sets MRCR to epoch 2
 | |
|                     TestAction.Delegate,
 | |
|                     // Move to epoch 3
 | |
|                     TestAction.Finalize,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Updates CR for epoch 3
 | |
|                     // Sets MRCR to epoch 3
 | |
|                     // Creates CR for epoch 4
 | |
|                     // Clears CR for epoch 2
 | |
|                     TestAction.Delegate,
 | |
|                 ],
 | |
|                 [{ event: 'SetCumulativeReward', epoch: 3 }],
 | |
|             );
 | |
|         });
 | |
|         it('delegate in epoch 2 then undelegate in epoch 3', async () => {
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Creates CR for epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                     // Moves to epoch 2
 | |
|                     TestAction.Finalize,
 | |
|                     // Creates CR for epoch 2
 | |
|                     // Sets MRCR to epoch 1
 | |
|                     // Clears CR for epoch 1
 | |
|                     // Creates CR for epoch 3
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 3
 | |
|                     TestAction.Finalize,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Update CR for epoch 3
 | |
|                     // Set MRCR to epoch 3
 | |
|                     // Clear CR for epoch 2
 | |
|                     TestAction.Undelegate,
 | |
|                 ],
 | |
|                 [{ event: 'SetCumulativeReward', epoch: 3 }],
 | |
|             );
 | |
|         });
 | |
|         it('delegate in epoch 1 and epoch 2, then undelegate half in epoch 3', async () => {
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Create CR for epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                     // Updates CR for epoch 1
 | |
|                     // Sets MRCR to epoch 1
 | |
|                     // Creates CR for epoch 2
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 2
 | |
|                     TestAction.Finalize,
 | |
|                     // Updates CR for epoch 2
 | |
|                     // Sets MRCR to epoch 2
 | |
|                     // Creates CR for epoch 3
 | |
|                     // Clears CR for epoch 1
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 3
 | |
|                     TestAction.Finalize,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Updates CR for epoch 3
 | |
|                     // Sets MRCR to epoch 3
 | |
|                     // Creates CR for epoch 4 (because there will still be stake)
 | |
|                     // Clears CR for epoch 2
 | |
|                     TestAction.Undelegate,
 | |
|                 ],
 | |
|                 [{ event: 'SetCumulativeReward', epoch: 3 }],
 | |
|             );
 | |
|         });
 | |
|         it('delegate in epoch 2 and 3 then again in 3', async () => {
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Creates CR for epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                     // Updates CR for epoch 1
 | |
|                     // Sets MRCR to epoch 1
 | |
|                     // Creates CR for epoch 2
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 2
 | |
|                     TestAction.Finalize,
 | |
|                     // Updates CR for epoch 2
 | |
|                     // Sets MRCR to epoch 2
 | |
|                     // Creates CR for epoch 3
 | |
|                     // Clears CR for epoch 1
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 3
 | |
|                     TestAction.Finalize,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Updates CR for epoch 3
 | |
|                     // Sets MRCR to epoch 3
 | |
|                     // Creates CR for epoch 4
 | |
|                     // Clears CR for epoch 2
 | |
|                     TestAction.Delegate,
 | |
|                 ],
 | |
|                 [{ event: 'SetCumulativeReward', epoch: 3 }],
 | |
|             );
 | |
|         });
 | |
|         it('delegate in epoch 1, earn reward in epoch 2', async () => {
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Create CR for epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                     // Updates CR for epoch 1
 | |
|                     // Sets MRCR to epoch 1
 | |
|                     // Creates CR for epoch 2
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 2
 | |
|                     TestAction.Finalize,
 | |
|                     // Credits pool with rewards
 | |
|                     TestAction.PayProtocolFee,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Moves to epoch 3
 | |
|                     // Creates CR for epoch 3
 | |
|                     // Sets MRCR to epoch 3
 | |
|                     TestAction.Finalize,
 | |
|                 ],
 | |
|                 [{ event: 'SetCumulativeReward', epoch: 3 }],
 | |
|             );
 | |
|         });
 | |
|         it('delegate in epoch 1, epoch 3, earn reward in epoch 4, then delegate', async () => {
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Create CR for epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                     // Updates CR for epoch 1
 | |
|                     // Sets MRCR to epoch 1
 | |
|                     // Creates CR for epoch 2
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 2
 | |
|                     TestAction.Finalize,
 | |
|                     // Updates CR for epoch 2
 | |
|                     // Sets MRCR to epoch 2
 | |
|                     // Creates CR for epoch 3
 | |
|                     // Clears CR for epoch 1
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 3
 | |
|                     TestAction.Finalize,
 | |
|                     // Credits pool with rewards
 | |
|                     TestAction.PayProtocolFee,
 | |
|                     // Moves to epoch 4
 | |
|                     // Creates CR for epoch 4
 | |
|                     // Sets MRCR to epoch 4
 | |
|                     TestAction.Finalize,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Updates CR for epoch 4
 | |
|                     // Creates CR for epoch 5
 | |
|                     // Clears CR for epoch 2
 | |
|                     // Clears CR for epoch 3
 | |
|                     TestAction.Delegate,
 | |
|                 ],
 | |
|                 [],
 | |
|             );
 | |
|         });
 | |
|         it('delegate in epoch 1 and 2, earn reward in epoch 4, then undelegate half', async () => {
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Create CR for epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                     // Updates CR for epoch 1
 | |
|                     // Sets MRCR to epoch 1
 | |
|                     // Creates CR for epoch 2
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 2
 | |
|                     TestAction.Finalize,
 | |
|                     // Updates CR for epoch 2
 | |
|                     // Sets MRCR to epoch 2
 | |
|                     // Creates CR for epoch 3
 | |
|                     // Clears CR for epoch 1
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 3
 | |
|                     TestAction.Finalize,
 | |
|                     // Credits pool with rewards
 | |
|                     TestAction.PayProtocolFee,
 | |
|                     // Moves to epoch 4
 | |
|                     // Creates CR for epoch 4
 | |
|                     // Sets MRCR to epoch 4
 | |
|                     TestAction.Finalize,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Updates CR for epoch 4
 | |
|                     // Creates CR for epoch 5 (because there is still stake remaming)
 | |
|                     // Clears CR for epoch 2
 | |
|                     // Clears CR for epoch 3
 | |
|                     TestAction.Undelegate,
 | |
|                 ],
 | |
|                 [],
 | |
|             );
 | |
|         });
 | |
|         it('delegate in epoch 2, 3, earn rewards in epoch 4, skip to epoch 5, then delegate', async () => {
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Create CR for epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                     // Updates CR for epoch 1
 | |
|                     // Sets MRCR to epoch 1
 | |
|                     // Creates CR for epoch 2
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 2
 | |
|                     TestAction.Finalize,
 | |
|                     // Updates CR for epoch 2
 | |
|                     // Sets MRCR to epoch 2
 | |
|                     // Creates CR for epoch 3
 | |
|                     // Clears CR for epoch 1
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 3
 | |
|                     TestAction.Finalize,
 | |
|                     // Credits pool with rewards
 | |
|                     TestAction.PayProtocolFee,
 | |
|                     // Moves to epoch 4
 | |
|                     // Creates CR for epoch 4
 | |
|                     // Sets MRCR to epoch 4
 | |
|                     TestAction.Finalize,
 | |
|                     // Moves to epoch 5
 | |
|                     TestAction.Finalize,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Creates CR for epoch 5
 | |
|                     // Sets MRCR to epoch 5
 | |
|                     // Clears CR for epoch 4
 | |
|                     // Creates CR for epoch 6
 | |
|                     // Clears CR for epoch 2
 | |
|                     TestAction.Delegate,
 | |
|                 ],
 | |
|                 [{ event: 'SetCumulativeReward', epoch: 5 }],
 | |
|             );
 | |
|         });
 | |
|         it('earn reward in epoch 2 with no stake, then delegate', async () => {
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Creates CR for epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                     // Credit pool with rewards
 | |
|                     TestAction.PayProtocolFee,
 | |
|                     // Moves to epoch 2
 | |
|                     // That's it, because there's no active pools.
 | |
|                     TestAction.Finalize,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Updates CR to epoch 2
 | |
|                     // Sets MRCR to epoch 2
 | |
|                     // Clears CR for epoch 1
 | |
|                     // Creates CR for epoch 3
 | |
|                     TestAction.Delegate,
 | |
|                 ],
 | |
|                 [{ event: 'SetCumulativeReward', epoch: 2 }],
 | |
|             );
 | |
|         });
 | |
|         it('delegate in epoch 2, 4, then delegate in epoch 5', async () => {
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Creates CR for epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                     // Moves to epoch 2
 | |
|                     TestAction.Finalize,
 | |
|                     // Creates CR for epoch 2
 | |
|                     // Sets MRCR to epoch 1
 | |
|                     // Clears CR for epoch 1
 | |
|                     // Creates CR for epoch 3
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 3
 | |
|                     TestAction.Finalize,
 | |
|                     // Moves to epoch 4
 | |
|                     TestAction.Finalize,
 | |
|                     // Creates CR for epoch 4
 | |
|                     // Sets MRCR to epoch 4
 | |
|                     // Clears CR for epoch 2
 | |
|                     // Creates CR for epoch 5
 | |
|                     // Clears CR for epoch 3
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 5
 | |
|                     TestAction.Finalize,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Updates CR for epoch 5
 | |
|                     // Sets MRCR to epoch 5
 | |
|                     // Clears CR for epoch 4
 | |
|                     // Creates CR for epoch 6
 | |
|                     TestAction.Delegate,
 | |
|                 ],
 | |
|                 [{ event: 'SetCumulativeReward', epoch: 5 }],
 | |
|             );
 | |
|         });
 | |
|         it('delegate in epoch 2, then epoch 4', async () => {
 | |
|             await simulation.runTestAsync(
 | |
|                 [
 | |
|                     // Creates CR for epoch 1
 | |
|                     TestAction.CreatePool,
 | |
|                     // Moves to epoch 2
 | |
|                     TestAction.Finalize,
 | |
|                     // Creates CR for epoch 2
 | |
|                     // Sets MRCR to epoch 1
 | |
|                     // Clears CR for epoch 1
 | |
|                     // Creates CR for epoch 3
 | |
|                     TestAction.Delegate,
 | |
|                     // Moves to epoch 3
 | |
|                     TestAction.Finalize,
 | |
|                     // Moves to epoch 4
 | |
|                     TestAction.Finalize,
 | |
|                 ],
 | |
|                 [
 | |
|                     // Creates CR for epoch 4
 | |
|                     // Sets MRCR to epoch 4
 | |
|                     // Clears CR for epoch 2
 | |
|                     // Creates CR for epoch 5
 | |
|                     // Clears CR for epoch 3
 | |
|                     TestAction.Delegate,
 | |
|                 ],
 | |
|                 [{ event: 'SetCumulativeReward', epoch: 4 }],
 | |
|             );
 | |
|         });
 | |
|     });
 | |
| });
 | |
| // tslint:enable:no-unnecessary-type-assertion
 |