Skip to content

Commit

Permalink
Merge pull request #33 from threshold-network/system-tests
Browse files Browse the repository at this point in the history
System tests for KEEP<>T staking contracts interactions

System tests are performed on mainnet block 13619810 fork chain using three real stakers from KEEP network: liquid token staker, managed grant staker, and non-managed grant staker.


Stake delegation
- Given I am KEEP network liquid token staker, when I have authorized T staking contract, when I have not undelegated my legacy stake, `stakeKeep` should copy my stake to T staking contract.
- Given I am KEEP network liquid token staker, when I have authorized T staking contract, when I have undelegated my legacy stake, `stakeKeep` should revert.
            
Top-ups
- Given I am KEEP network liquid token staker, when I copied my stake to T staking contract, when I executed top-up of my legacy stake, `topUpKeep` should top-up my stake in T staking contract.

Stake undelegation
- Given I am KEEP network liquid token staker, when I copied my stake to T staking contract, when I authorized and deauthorized application, `unstakeKeep` should release my KEEP stake.
- Given I am KEEP network liquid token staker, when I copied my stake to T staking contract, when I authorized and deauthorized application, `unstakeKeep` should let me undelegate my KEEP stake.

Slashing
- Given I am KEEP network liquid token staker, when I copied my stake to T staking contract, when I authorized application, when I got slashed by the application, `processSlashing` should slash my KEEP stake.
- Given I am KEEP network liquid token staker, when I copied my stake to T staking contract, when I authorized application, when I got slashed by the application, `notifyKeepStakeDiscrepancy` should revert.
- Given I am KEEP network liquid token staker, when I copied my stake to T staking contract, when I authorized application, when the application seized my stake, `processSlashing` should seize my KEEP stake.
- Given I am KEEP network liquid token staker, when I copied my stake to T staking contract, when I authorized application, when the application seized my stake, `notifyKeepStakeDiscrepancy` should revert.
    
Exactly the same tests are repeated for two other types of actors:
- Given I am KEEP network managed grant staker... 
- Given I am KEEP network non-managed grant staker...
  • Loading branch information
nkuba authored Dec 20, 2021
2 parents a70d05c + bb5e4a3 commit 15fdfd7
Show file tree
Hide file tree
Showing 7 changed files with 533 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity 0.8.9;

import "../staking/KeepStake.sol";

interface ITestManagedGrant is IManagedGrant {
interface IKeepManagedGrant is IManagedGrant {
function stake(
address stakingContract,
uint256 amount,
Expand Down
13 changes: 13 additions & 0 deletions contracts/test/IKeepToken.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.9;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface IKeepToken is IERC20 {
function approveAndCall(
address spender,
uint256 value,
bytes memory extraData
) external returns (bool success);
}
14 changes: 14 additions & 0 deletions contracts/test/IKeepTokenGrant.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.9;

import "../staking/ILegacyTokenStaking.sol";

interface IKeepTokenGrant {
function stake(
uint256 id,
address stakingContract,
uint256 amount,
bytes memory extraData
) external;
}
9 changes: 9 additions & 0 deletions contracts/test/ITestKeepTokenStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,13 @@ interface ITestKeepTokenStaking is IKeepTokenStaking {
address operator,
address operatorContract
) external;

function commitTopUp(address operator) external;

function undelegate(address operator) external;

function getLocks(address operator)
external
view
returns (address[] memory creators, uint256[] memory expirations);
}
35 changes: 32 additions & 3 deletions test/system/constants.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
const { to1e18 } = require("../helpers/contract-test-helpers")

module.exports.keepTokenAddress = "0x85Eee30c52B0b379b046Fb0F85F4f3Dc3009aFEC"
module.exports.keepTokenGrantAddress =
"0x175989c71fd023d580c65f5dc214002687ff88b7"
module.exports.nuCypherTokenAddress =
"0x4fE83213D56308330EC302a8BD641f1d0113A4Cc"
module.exports.keepTokenStakingAddress =
Expand All @@ -8,6 +12,31 @@ module.exports.nuCypherStakingEscrowAddress =
module.exports.keepRegistryAddress =
"0x1a9589F56c969d6b0D3787ea02322476eAd3fB05"

// A grant has been chosen arbitrarily to get a state allowing to perform test scenarios.
module.exports.keepManagedGrantAddress =
"0x6123fC47Fab68fB7905aDD5dcd3Bd1eb131556Dc"
// liquid token owner with 3,000,000 staked
module.exports.keepLiquidTokenStake = {
owner: "0x4A0A927043B01a7fB175BCa4F4837e3b817C5e6b",
operator: "0x64A8856cBD255765D16B901a0B899daefC78FB13",
authorizer: "0x5481188e698a5752c5cab6e2494fc2cfbb644f2d",
beneficiary: "0xa49f1b845a8086ac0b820ce6fa8ce92d223765d2",
keepStaked: to1e18("3000000"),
}

// managed grantee with 1,196,000 KEEP staked
module.exports.keepManagedGrantStake = {
grantee: "0x011074cA9EEff0836a68b170E46c4d20F8CAc727",
operator: "0xc6349eEC31048787676b6297ba71721376A8DdcF",
authorizer: "0x011074cA9EEff0836a68b170E46c4d20F8CAc727",
beneficiary: "0x011074cA9EEff0836a68b170E46c4d20F8CAc727",
managedGrant: "0xac1a985E75C6a0b475b9c807Ad0705a988Be2D99",
keepStaked: to1e18("1196000"),
}

// standard grant delegation with 832,533 staked
module.exports.keepGrantStake = {
grantee: "0xf6f372DfAeCC1431186598c304e91B79Ce115766",
operator: "0x8Bd660A764Ca14155F3411a4526a028b6316CB3E",
authorizer: "0x826b18a8c61e976156a962613e2c189b3ee5f2cb",
beneficiary: "0xf6f372DfAeCC1431186598c304e91B79Ce115766",
keepStaked: to1e18("832533"),
grantID: 37,
}
28 changes: 22 additions & 6 deletions test/system/init-contracts.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const {
keepTokenStakingAddress,
nuCypherStakingEscrowAddress,
keepRegistryAddress,
keepTokenGrantAddress,
} = require("./constants.js")
const {
to1e18,
Expand All @@ -18,21 +19,28 @@ async function initContracts() {
const keepTokenStaking = await resolveKeepTokenStaking()
const nuCypherStakingEscrow = await resolveNuCypherStakingEscrow()
const keepRegistry = await resolveKeepRegistry()
const keepTokenGrant = await resolveKeepTokenGrant()

const tToken = await deployTToken(to1e18(1000000))
// 10 billion T minted
const tToken = await deployTToken(to1e18(10000000000))

const keepVendingMachine = await deployVendingMachine(
keepToken,
tToken,
to1e18(1000000),
to1e18(500000)
// 999,848,780 KEEP is the current KEEP total supply
to1e18(999848780),
// 45% of T supply goes to KEEP vending machine
to1e18(4500000000)
)

const nuCypherVendingMachine = await deployVendingMachine(
nuCypherToken,
tToken,
to1e18(1000000),
to1e18(500000)
// 1,350,000,000 is the NU total supply after pausing inflation
// (this number will be different for mainnet deployment but close to this one)
to1e18(1350000000),
// 45% of T supply goes to KEEP vending machine
to1e18(4500000000)
)

const keepStake = await deployKeepStake(keepTokenStaking)
Expand All @@ -59,13 +67,17 @@ async function initContracts() {
.approveOperatorContract(tokenStaking.address)

return {
keepToken: keepToken,
keepTokenGrant: keepTokenGrant,
keepTokenStaking: keepTokenStaking,
tokenStaking: tokenStaking,
keepVendingMachine: keepVendingMachine,
nuVendingMaching: nuCypherVendingMachine,
}
}

async function resolveKeepToken() {
return await ethers.getContractAt("IERC20", keepTokenAddress)
return await ethers.getContractAt("IKeepToken", keepTokenAddress)
}

async function resolveNuCypherToken() {
Expand All @@ -90,6 +102,10 @@ async function resolveKeepRegistry() {
return await ethers.getContractAt("IKeepRegistry", keepRegistryAddress)
}

async function resolveKeepTokenGrant() {
return await ethers.getContractAt("IKeepTokenGrant", keepTokenGrantAddress)
}

async function deployTToken() {
const TToken = await ethers.getContractFactory("T")
const tToken = await TToken.deploy()
Expand Down
Loading

0 comments on commit 15fdfd7

Please sign in to comment.