From 4c1972148ae4dd263146844090024f92129772f3 Mon Sep 17 00:00:00 2001 From: Uladzislau Hubar Date: Wed, 30 Oct 2024 15:40:37 +0800 Subject: [PATCH] Fixed check during KA submission to Paranet, added redelegation --- abi/StakingV2.json | 23 + contracts/v2/Staking.sol | 76 +- contracts/v2/paranets/Paranet.sol | 8 +- deploy/035_deploy_profile_v2.ts | 2 +- deployments/base_mainnet_contracts.json | 323 -------- deployments/base_sepolia_test_contracts.json | 323 -------- .../base_sepolia_v8_dev_contracts.json | 24 +- .../base_sepolia_v8_stable_dev_contracts.json | 24 +- .../base_sepolia_v8_test_contracts.json | 24 +- deployments/gnosis_chiado_test_contracts.json | 322 -------- deployments/gnosis_mainnet_contracts.json | 330 -------- deployments/otp_mainnet_contracts.json | 321 -------- deployments/otp_testnet_contracts.json | 310 ------- package-lock.json | 4 +- package.json | 2 +- test/v1/unit/AssertionStorage.test.ts | 139 ---- test/v1/unit/CommitManagerV1.test.ts | 194 ----- test/v1/unit/CommitManagerV1U1.test.ts | 343 -------- test/v1/unit/ProofManagerV1.test.ts | 591 -------------- test/v1/unit/ProofManagerV1U1.test.ts | 753 ------------------ .../unit/ServiceAgreementStorageProxy.test.ts | 373 --------- .../v1/unit/ServiceAgreementStorageV1.test.ts | 176 ---- .../unit/ServiceAgreementStorageV1U1.test.ts | 237 ------ test/v1/unit/ServiceAgreementV1.test.ts | 229 ------ test/v1/unit/UnfinalizedStateStorage.test.ts | 77 -- test/v2/unit/CommitManagerV2.test.ts | 513 ------------ test/v2/unit/CommitManagerV2U1.test.ts | 713 ----------------- test/v2/unit/Paranet.test.ts | 4 +- test/v2/unit/ParanetsRegistry.test.ts | 27 +- test/v2/unit/StakingV2.test.ts | 331 +++++++- 30 files changed, 484 insertions(+), 6332 deletions(-) delete mode 100644 deployments/base_mainnet_contracts.json delete mode 100644 deployments/base_sepolia_test_contracts.json delete mode 100644 deployments/gnosis_chiado_test_contracts.json delete mode 100644 deployments/gnosis_mainnet_contracts.json delete mode 100644 deployments/otp_mainnet_contracts.json delete mode 100644 deployments/otp_testnet_contracts.json delete mode 100644 test/v1/unit/AssertionStorage.test.ts delete mode 100644 test/v1/unit/CommitManagerV1.test.ts delete mode 100644 test/v1/unit/CommitManagerV1U1.test.ts delete mode 100644 test/v1/unit/ProofManagerV1.test.ts delete mode 100644 test/v1/unit/ProofManagerV1U1.test.ts delete mode 100644 test/v1/unit/ServiceAgreementStorageProxy.test.ts delete mode 100644 test/v1/unit/ServiceAgreementStorageV1.test.ts delete mode 100644 test/v1/unit/ServiceAgreementStorageV1U1.test.ts delete mode 100644 test/v1/unit/ServiceAgreementV1.test.ts delete mode 100644 test/v1/unit/UnfinalizedStateStorage.test.ts delete mode 100644 test/v2/unit/CommitManagerV2.test.ts delete mode 100644 test/v2/unit/CommitManagerV2U1.test.ts diff --git a/abi/StakingV2.json b/abi/StakingV2.json index aab204f0..ea92a602 100644 --- a/abi/StakingV2.json +++ b/abi/StakingV2.json @@ -681,6 +681,29 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint72", + "name": "from", + "type": "uint72" + }, + { + "internalType": "uint72", + "name": "to", + "type": "uint72" + }, + { + "internalType": "uint96", + "name": "sharesToBurn", + "type": "uint96" + } + ], + "name": "redelegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "serviceAgreementStorageProxy", diff --git a/contracts/v2/Staking.sol b/contracts/v2/Staking.sol index 1be62211..5356205c 100644 --- a/contracts/v2/Staking.sol +++ b/contracts/v2/Staking.sol @@ -88,7 +88,7 @@ contract StakingV2 is Named, Versioned, ContractStatusV2, Initializable { event OperatorFeeChangeFinished(uint72 indexed identityId, bytes nodeId, uint8 operatorFee); string private constant _NAME = "Staking"; - string private constant _VERSION = "2.2.0"; + string private constant _VERSION = "2.3.0"; ShardingTableV2 public shardingTableContract; IdentityStorageV2 public identityStorage; @@ -212,6 +212,80 @@ contract StakingV2 is Named, Versioned, ContractStatusV2, Initializable { emit SharesMinted(identityId, address(sharesContract), msg.sender, sharesMinted, sharesContract.totalSupply()); } + function redelegate(uint72 from, uint72 to, uint96 sharesToBurn) external { + if (sharesToBurn == 0) { + revert StakingErrors.ZeroSharesAmount(); + } + + ProfileStorage ps = profileStorage; + StakingStorage ss = stakingStorage; + ShardingTableStorageV2 sts = shardingTableStorage; + + if (!ps.profileExists(from)) { + revert ProfileErrors.ProfileDoesntExist(from); + } + + if (!ps.profileExists(to)) { + revert ProfileErrors.ProfileDoesntExist(to); + } + + Shares fromSharesContract = Shares(ps.getSharesContractAddress(from)); + Shares toSharesContract = Shares(ps.getSharesContractAddress(to)); + + if (sharesToBurn > fromSharesContract.balanceOf(msg.sender)) { + revert TokenErrors.TooLowBalance(address(fromSharesContract), fromSharesContract.balanceOf(msg.sender)); + } + + ParametersStorage params = parametersStorage; + + uint96 fromCurrentStake = ss.totalStakes(from); + uint96 toCurrentStake = ss.totalStakes(to); + + uint96 redelegationAmount = uint96( + (uint256(fromCurrentStake) * sharesToBurn) / fromSharesContract.totalSupply() + ); + + if (toCurrentStake + redelegationAmount > params.maximumStake()) { + revert StakingErrors.MaximumStakeExceeded(params.maximumStake()); + } + + fromSharesContract.burnFrom(msg.sender, sharesToBurn); + + uint256 sharesToMint; + if (toSharesContract.totalSupply() == 0) { + sharesToMint = redelegationAmount; + } else { + sharesToMint = ((uint256(redelegationAmount) * toSharesContract.totalSupply()) / toCurrentStake); + } + toSharesContract.mint(msg.sender, sharesToMint); + + ss.setTotalStake(from, fromCurrentStake - redelegationAmount); + + if (sts.nodeExists(from) && (fromCurrentStake - redelegationAmount) < params.minimumStake()) { + shardingTableContract.removeNode(from); + } + + ss.setTotalStake(to, toCurrentStake + redelegationAmount); + + if (!sts.nodeExists(to) && (toCurrentStake + redelegationAmount >= params.minimumStake())) { + if (sts.nodesCount() >= params.shardingTableSizeLimit()) { + revert ShardingTableErrors.ShardingTableIsFull(); + } + shardingTableContract.insertNode(to); + } + + emit SharesBurned( + from, + address(fromSharesContract), + msg.sender, + sharesToBurn, + fromSharesContract.totalSupply() + ); + emit StakeWithdrawn(from, ps.getNodeId(from), msg.sender, redelegationAmount); + emit SharesMinted(to, address(toSharesContract), msg.sender, sharesToMint, toSharesContract.totalSupply()); + emit StakeIncreased(to, ps.getNodeId(to), msg.sender, toCurrentStake, toCurrentStake + redelegationAmount); + } + function startStakeWithdrawal(uint72 identityId, uint96 sharesToBurn) external { if (sharesToBurn == 0) { revert StakingErrors.ZeroSharesAmount(); diff --git a/contracts/v2/paranets/Paranet.sol b/contracts/v2/paranets/Paranet.sol index 80d7aaef..afc78308 100644 --- a/contracts/v2/paranets/Paranet.sol +++ b/contracts/v2/paranets/Paranet.sol @@ -123,7 +123,7 @@ contract Paranet is Named, Versioned, ContractStatusV2, Initializable { ); string private constant _NAME = "Paranet"; - string private constant _VERSION = "2.2.0"; + string private constant _VERSION = "2.2.1"; ParanetsRegistry public paranetsRegistry; ParanetServicesRegistry public paranetServicesRegistry; @@ -914,7 +914,11 @@ contract Paranet is Named, Versioned, ContractStatusV2, Initializable { } } - if (paranetKnowledgeAssetsRegistry.isParanetKnowledgeAsset(paranetId)) { + if ( + paranetKnowledgeAssetsRegistry.isParanetKnowledgeAsset( + keccak256(abi.encodePacked(knowledgeAssetStorageContract, knowledgeAssetTokenId)) + ) + ) { revert ParanetErrors.KnowledgeAssetIsAPartOfOtherParanet( knowledgeAssetStorageContract, knowledgeAssetTokenId, diff --git a/deploy/035_deploy_profile_v2.ts b/deploy/035_deploy_profile_v2.ts index 4b916c5b..b70f6688 100644 --- a/deploy/035_deploy_profile_v2.ts +++ b/deploy/035_deploy_profile_v2.ts @@ -19,7 +19,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { }; export default func; -func.tags = ['Profile', 'v2']; +func.tags = ['ProfileV2', 'v2']; func.dependencies = [ 'Hub', 'Identity', diff --git a/deployments/base_mainnet_contracts.json b/deployments/base_mainnet_contracts.json deleted file mode 100644 index 30a80dc0..00000000 --- a/deployments/base_mainnet_contracts.json +++ /dev/null @@ -1,323 +0,0 @@ -{ - "contracts": { - "Token": { - "deployed": true, - "evmAddress": "0xa81a52b4dda010896cdd386c7fbdc5cdc835ba23" - }, - "Hub": { - "evmAddress": "0xaBfcf2ad1718828E7D3ec20435b0d0b5EAfbDf2c", - "version": "2.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310628, - "deploymentTimestamp": 1719410606574, - "deployed": true - }, - "HubController": { - "evmAddress": "0x6b9cfFB2CB5b8835880Ab455329E7ca2a0989d17", - "version": "1.0.2", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310631, - "deploymentTimestamp": 1719410613045, - "deployed": true - }, - "ParametersStorage": { - "evmAddress": "0x3c556Ae354bDcE25537661169206B2099DA588E2", - "version": "1.1.1", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310638, - "deploymentTimestamp": 1719410626851, - "deployed": true - }, - "WhitelistStorage": { - "evmAddress": "0x5975BA918a9F686D8a30B21cC5214909B86A45d4", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310643, - "deploymentTimestamp": 1719410638633, - "deployed": true - }, - "HashingProxy": { - "evmAddress": "0x9c86fAdDf5FF1c3b3c831ad84ddc2F1758C46671", - "version": "1.0.1", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310647, - "deploymentTimestamp": 1719410646218, - "deployed": true - }, - "SHA256": { - "evmAddress": "0xBF6d121c60160326a009998d3BBB7F0603E5563e", - "version": null, - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310651, - "deploymentTimestamp": 1719410653950, - "deployed": true - }, - "ScoringProxy": { - "evmAddress": "0x030cA97435fb416fa0531EB28c7a24CA08ecAEcD", - "version": "2.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310655, - "deploymentTimestamp": 1719410660590, - "deployed": true - }, - "LinearSum": { - "evmAddress": "0x4a6ee029c21840BdE7Cdb08fbC0cda5058E515C3", - "version": null, - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310658, - "deploymentTimestamp": 1719410667086, - "deployed": true - }, - "AssertionStorage": { - "evmAddress": "0x77aAEDb38Fb9fBba8C86232Fc3F9193e602b0B79", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310662, - "deploymentTimestamp": 1719410674934, - "deployed": true - }, - "IdentityStorage": { - "evmAddress": "0xD40c74f5D1Ee382deb63Fa92d7ff5bC65415bBEE", - "version": "2.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310665, - "deploymentTimestamp": 1719410681735, - "deployed": true - }, - "ShardingTableStorage": { - "evmAddress": "0x61FFE2Ed44A2bbd9E225DB8ecA09E9480899a166", - "version": "2.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310669, - "deploymentTimestamp": 1719410688588, - "deployed": true - }, - "StakingStorage": { - "evmAddress": "0x56ff4982Be0703456Dcc232fbA5ED90C68952BDe", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310672, - "deploymentTimestamp": 1719410695509, - "deployed": true - }, - "ProfileStorage": { - "evmAddress": "0xC07a4a352de680788497aF20f7D66964D08E31D2", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310676, - "deploymentTimestamp": 1719410702392, - "deployed": true - }, - "ServiceAgreementStorageV1": { - "evmAddress": "0x855e7bb3cC680B231f50A24257BCf5b920a9Bf76", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310679, - "deploymentTimestamp": 1719410709319, - "deployed": true - }, - "ServiceAgreementStorageV1U1": { - "evmAddress": "0xebB3C4f89e59Bd905dBF2967B1833fB2c0Ff6c74", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310682, - "deploymentTimestamp": 1719410716133, - "deployed": true - }, - "ServiceAgreementStorageProxy": { - "evmAddress": "0x015547c73AF2D581A39C47959EF57E74E7e2f7B9", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310686, - "deploymentTimestamp": 1719410728068, - "deployed": true - }, - "ContentAssetStorage": { - "evmAddress": "0x3bdfA81079B2bA53a25a6641608E5E1E6c464597", - "version": "2.0.1", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310692, - "deploymentTimestamp": 1719410735086, - "deployed": true - }, - "UnfinalizedStateStorage": { - "evmAddress": "0xca5c9A170d4acC694F7730f1Bb841553278fF24B", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310695, - "deploymentTimestamp": 1719410741786, - "deployed": true - }, - "ParanetsRegistry": { - "evmAddress": "0x4382835340c91811800a54B4e3Af2878c7968A24", - "version": "2.1.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310699, - "deploymentTimestamp": 1719410748480, - "deployed": true - }, - "ParanetServicesRegistry": { - "evmAddress": "0x3f3AD359f79B8987Ac0f642e309B2c195D458199", - "version": "2.1.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310702, - "deploymentTimestamp": 1719410755220, - "deployed": true - }, - "ParanetKnowledgeAssetsRegistry": { - "evmAddress": "0xA85cb8367dca370F2E26b28E3597c67427F37ee3", - "version": "2.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310705, - "deploymentTimestamp": 1719410761987, - "deployed": true - }, - "ParanetKnowledgeMinersRegistry": { - "evmAddress": "0xB0b91AD1E1f6646Ee503D7750552A656e12eAE04", - "version": "2.0.1", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310709, - "deploymentTimestamp": 1719410768720, - "deployed": true - }, - "Assertion": { - "evmAddress": "0xD3cb63419506df9F5bddA800B136dBCA75B2dD59", - "version": "1.0.1", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310712, - "deploymentTimestamp": 1719410775477, - "deployed": true - }, - "Identity": { - "evmAddress": "0x14DFd7E7D324677aB7749Bc532f04358B53877fc", - "version": "1.1.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310716, - "deploymentTimestamp": 1719410782268, - "deployed": true - }, - "ShardingTable": { - "evmAddress": "0x71DD0069EFd6bfaB5B8b3988dCC114F4C6b7A274", - "version": "2.0.1", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310719, - "deploymentTimestamp": 1719410789276, - "deployed": true - }, - "NodeOperatorFeesStorage": { - "evmAddress": "0x5bE77Ee0FF0FA692d12898ad7B7582BcA6a1A97b", - "version": "2.0.2", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310723, - "deploymentTimestamp": 1719410796546, - "deployed": true - }, - "Staking": { - "evmAddress": "0x39713a4E7d05dAB796fCA6e84cBA5aFC905822d9", - "version": "2.2.0", - "gitBranch": "main", - "gitCommitHash": "b9e7dede2a75acf193272f84b1a5ce155210e47a", - "deploymentBlock": 19022524, - "deploymentTimestamp": 1724834405325, - "deployed": true - }, - "Profile": { - "evmAddress": "0x41F7274fC5981eb7001dDE2A97Efa9CEcC9b1a01", - "version": "1.2.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310730, - "deploymentTimestamp": 1719410810611, - "deployed": true - }, - "CommitManagerV1": { - "evmAddress": "0xCAFF55d5a22C0b58452420f642ef22a8c5DB4500", - "version": "2.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310733, - "deploymentTimestamp": 1719410817652, - "deployed": true - }, - "CommitManagerV1U1": { - "evmAddress": "0x411d7ddF4164f8bD57f2462d86bA3C1d55005144", - "version": "2.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310737, - "deploymentTimestamp": 1719410825678, - "deployed": true - }, - "ProofManagerV1": { - "evmAddress": "0x53d5337d63f404D60df0D019cb1D834d1Ee179D6", - "version": "1.0.3", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310741, - "deploymentTimestamp": 1719410834106, - "deployed": true - }, - "ProofManagerV1U1": { - "evmAddress": "0xdF1fdDEa77D33068eA0CBAA0d4A220c9Ba848C75", - "version": "1.0.3", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310745, - "deploymentTimestamp": 1719410841930, - "deployed": true - }, - "ServiceAgreementV1": { - "evmAddress": "0xfbAa8010Bb9cD37f86a2c2D9589cD9ead62355f4", - "version": "1.1.1", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310749, - "deploymentTimestamp": 1719410849698, - "deployed": true - }, - "ContentAsset": { - "evmAddress": "0xFAC3F90a2b3719bF39058a98b6cc58Aabddc611a", - "version": "2.1.0", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310753, - "deploymentTimestamp": 1719410856427, - "deployed": true - }, - "Paranet": { - "evmAddress": "0x78b4173d25e30C0B52A855FE522EF2B3FB95c8C7", - "version": "2.1.3", - "gitBranch": "feature/base", - "gitCommitHash": "d3eab3d1a0fde48db522b16b49654558eed07dc3", - "deploymentBlock": 16310756, - "deploymentTimestamp": 1719410863148, - "deployed": true - } - } -} diff --git a/deployments/base_sepolia_test_contracts.json b/deployments/base_sepolia_test_contracts.json deleted file mode 100644 index 28301283..00000000 --- a/deployments/base_sepolia_test_contracts.json +++ /dev/null @@ -1,323 +0,0 @@ -{ - "contracts": { - "Token": { - "deployed": true, - "evmAddress": "0x9b17032749aa066a2DeA40b746AA6aa09CdE67d9" - }, - "Hub": { - "evmAddress": "0x144eDa5cbf8926327cb2cceef168A121F0E4A299", - "version": "2.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510449, - "deploymentTimestamp": 1718789190774, - "deployed": true - }, - "HubController": { - "evmAddress": "0xeD19e9E1bBd5ffAe09C40d2e8873B1c6b1F0eaF4", - "version": "1.0.2", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510452, - "deploymentTimestamp": 1718789196801, - "deployed": true - }, - "ParametersStorage": { - "evmAddress": "0x6684c0B2b09eBDc3417649bCAd09e68A86a6377a", - "version": "1.1.1", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510459, - "deploymentTimestamp": 1718789209558, - "deployed": true - }, - "WhitelistStorage": { - "evmAddress": "0xC7B142dE4CfdE7CFDb181cf83A009A93be6CC211", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510464, - "deploymentTimestamp": 1718789220718, - "deployed": true - }, - "HashingProxy": { - "evmAddress": "0xB5Ef1A9137e0466EA4a5C9A4ae52DB9a05568134", - "version": "1.0.1", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510467, - "deploymentTimestamp": 1718789226970, - "deployed": true - }, - "SHA256": { - "evmAddress": "0xD508F02487970FB4e9d756A8845475a43B85a2f4", - "version": null, - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510470, - "deploymentTimestamp": 1718789232946, - "deployed": true - }, - "ScoringProxy": { - "evmAddress": "0x5403133B5B29F102E6d27130625E470687e6fa43", - "version": "2.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510474, - "deploymentTimestamp": 1718789239295, - "deployed": true - }, - "LinearSum": { - "evmAddress": "0x288afa63B03Eb952e214a40623a718E0744aDbd6", - "version": null, - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510477, - "deploymentTimestamp": 1718789245705, - "deployed": true - }, - "AssertionStorage": { - "evmAddress": "0x90C73C8F6f03576b9277D59F47F6559beA72B5ed", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510480, - "deploymentTimestamp": 1718789253751, - "deployed": true - }, - "IdentityStorage": { - "evmAddress": "0x42Da9B93e2B31077365E7FF324f52093e99de55d", - "version": "2.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510484, - "deploymentTimestamp": 1718789260267, - "deployed": true - }, - "ShardingTableStorage": { - "evmAddress": "0x9D34Af88a67369b93A66E0588f54bafA21Bbc733", - "version": "2.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510487, - "deploymentTimestamp": 1718789266607, - "deployed": true - }, - "StakingStorage": { - "evmAddress": "0xbFB9e8164440562A7b297ab68418e4Dde28adD3F", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510490, - "deploymentTimestamp": 1718789272911, - "deployed": true - }, - "ProfileStorage": { - "evmAddress": "0x2705782F7C247870b24517A511C648b58C448Ed8", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510494, - "deploymentTimestamp": 1718789279171, - "deployed": true - }, - "ServiceAgreementStorageV1": { - "evmAddress": "0xA9a0f14c4d48204148e551D0788013Ac063f6b29", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510497, - "deploymentTimestamp": 1718789285490, - "deployed": true - }, - "ServiceAgreementStorageV1U1": { - "evmAddress": "0x8466cDF2F87b3442C04c3ba0C37cf9E90e1F7Ddc", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510500, - "deploymentTimestamp": 1718789291701, - "deployed": true - }, - "ServiceAgreementStorageProxy": { - "evmAddress": "0x912E7200266c1132f1fa26a912e5d5eCd8117De8", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510503, - "deploymentTimestamp": 1718789298072, - "deployed": true - }, - "ContentAssetStorage": { - "evmAddress": "0x9e3071Dc0730CB6dd0ce42969396D716Ea33E7e1", - "version": "2.0.1", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510506, - "deploymentTimestamp": 1718789304402, - "deployed": true - }, - "UnfinalizedStateStorage": { - "evmAddress": "0x9DD432f676b0E79D41F95c18f2ec6eAe255cD7Da", - "version": "1.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510509, - "deploymentTimestamp": 1718789310978, - "deployed": true - }, - "ParanetsRegistry": { - "evmAddress": "0x8268d80Beb76A4566764B2679b99B6fE5eF0afB6", - "version": "2.1.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510513, - "deploymentTimestamp": 1718789318100, - "deployed": true - }, - "ParanetServicesRegistry": { - "evmAddress": "0x6C0cCC8ADa325F9CB98a53df50F80aBB43bb4B5d", - "version": "2.1.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510516, - "deploymentTimestamp": 1718789324569, - "deployed": true - }, - "ParanetKnowledgeAssetsRegistry": { - "evmAddress": "0x7E5BC33148f13f26e4AAEe947cEFb9Ba516f4A6F", - "version": "2.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510519, - "deploymentTimestamp": 1718789330860, - "deployed": true - }, - "ParanetKnowledgeMinersRegistry": { - "evmAddress": "0x9B923C74A928E2f98e4EAE8F614449067EC4C2Ae", - "version": "2.0.1", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510523, - "deploymentTimestamp": 1718789337119, - "deployed": true - }, - "Assertion": { - "evmAddress": "0x6ee356CB1aF85CA6D49b9C8A769c78542795790A", - "version": "1.0.1", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510525, - "deploymentTimestamp": 1718789343453, - "deployed": true - }, - "Identity": { - "evmAddress": "0x79Fe6392892bE72106DB555e136E9f9717D55A59", - "version": "1.1.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510529, - "deploymentTimestamp": 1718789350080, - "deployed": true - }, - "ShardingTable": { - "evmAddress": "0x6cAe059E31a02759e1A3210E9644828C7973478A", - "version": "2.0.1", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510532, - "deploymentTimestamp": 1718789356852, - "deployed": true - }, - "NodeOperatorFeesStorage": { - "evmAddress": "0x47522F86067C85Fb0a7e2ABFDe0154973EE652fB", - "version": "2.0.2", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510536, - "deploymentTimestamp": 1718789363934, - "deployed": true - }, - "Staking": { - "evmAddress": "0x1dD6bE1EC9410aff2E95685d84cEA6aCf40bFBa9", - "version": "2.2.0", - "gitBranch": "main", - "gitCommitHash": "b9e7dede2a75acf193272f84b1a5ce155210e47a", - "deploymentBlock": 14543315, - "deploymentTimestamp": 1724854925334, - "deployed": true - }, - "Profile": { - "evmAddress": "0x9f30f197eD4B2BB3fE140452E7518A52BF1Ed738", - "version": "1.2.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510542, - "deploymentTimestamp": 1718789376823, - "deployed": true - }, - "CommitManagerV1": { - "evmAddress": "0x98367A2a147b173b7Aae9d41a17167cd62bc8b81", - "version": "2.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510546, - "deploymentTimestamp": 1718789383500, - "deployed": true - }, - "CommitManagerV1U1": { - "evmAddress": "0x630A19886E9A426c732E8bce4580378C58Fa7e19", - "version": "2.0.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510550, - "deploymentTimestamp": 1718789391124, - "deployed": true - }, - "ProofManagerV1": { - "evmAddress": "0xD357eE1069135C04C60fd60165076717d6FB84cd", - "version": "1.0.3", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510553, - "deploymentTimestamp": 1718789398998, - "deployed": true - }, - "ProofManagerV1U1": { - "evmAddress": "0xcDDdcbFb24BC82762D48b2D1523eb9A98C0867e1", - "version": "1.0.3", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510557, - "deploymentTimestamp": 1718789406477, - "deployed": true - }, - "ServiceAgreementV1": { - "evmAddress": "0x9a6C2479320DeaE5D89db893F3E18D8A731781b5", - "version": "1.1.1", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510561, - "deploymentTimestamp": 1718789413895, - "deployed": true - }, - "ContentAsset": { - "evmAddress": "0xA02DB908723f4306c1FF2eD4984192325785ad0D", - "version": "2.1.0", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510564, - "deploymentTimestamp": 1718789420271, - "deployed": true - }, - "Paranet": { - "evmAddress": "0x994E07810bD8a312531D00E7B0E733517C571bCa", - "version": "2.1.3", - "gitBranch": "feature/base", - "gitCommitHash": "49543b7f02d9543b4c744dc8b8153921cf178ad9", - "deploymentBlock": 11510567, - "deploymentTimestamp": 1718789426637, - "deployed": true - } - } -} diff --git a/deployments/base_sepolia_v8_dev_contracts.json b/deployments/base_sepolia_v8_dev_contracts.json index 8c91b1c2..8798a250 100644 --- a/deployments/base_sepolia_v8_dev_contracts.json +++ b/deployments/base_sepolia_v8_dev_contracts.json @@ -239,12 +239,12 @@ "deployed": true }, "Staking": { - "evmAddress": "0xe06711f05AAab1b90C4D1021Da041DB28C74DB5E", - "version": "2.2.0", - "gitBranch": "v8/curated-paranets", - "gitCommitHash": "3eafa7e892fd91ed7a9fcf22ece46aab5c0f5174", - "deploymentBlock": 15710314, - "deploymentTimestamp": 1727188923372, + "evmAddress": "0x6e2f201Fa8E6015A69418d1cb8a3babfE48E2AD5", + "version": "2.3.0", + "gitBranch": "v8/develop", + "gitCommitHash": "6ad3e9bcea8152c4d7370a33ab5f2f3988987552", + "deploymentBlock": 17252419, + "deploymentTimestamp": 1730273131630, "deployed": true }, "Profile": { @@ -311,12 +311,12 @@ "deployed": true }, "Paranet": { - "evmAddress": "0x1485724a905Ab9AeC9D9b69d540f1076683262Cd", - "version": "2.2.0", - "gitBranch": "v8/curated-paranets", - "gitCommitHash": "f28dfca8d20cdd15d301598127ab649ee15cbfd1", - "deploymentBlock": 15832560, - "deploymentTimestamp": 1727433410570, + "evmAddress": "0x4fD405ee7EBBC40CEcD88F907dc90B21edfD3800", + "version": "2.2.1", + "gitBranch": "v8/develop", + "gitCommitHash": "6ad3e9bcea8152c4d7370a33ab5f2f3988987552", + "deploymentBlock": 17252628, + "deploymentTimestamp": 1730273551423, "deployed": true } } diff --git a/deployments/base_sepolia_v8_stable_dev_contracts.json b/deployments/base_sepolia_v8_stable_dev_contracts.json index 5e0f9c81..572dad04 100644 --- a/deployments/base_sepolia_v8_stable_dev_contracts.json +++ b/deployments/base_sepolia_v8_stable_dev_contracts.json @@ -239,12 +239,12 @@ "deployed": true }, "Staking": { - "evmAddress": "0xa3aB2007dd4E38aEdA3c6360C04061E81d40c060", - "version": "2.2.0", - "gitBranch": "improvement/curated-paranet-nodes", - "gitCommitHash": "de5edfde0f044d13bcdec8a33baaec934e2b62c4", - "deploymentBlock": 15791621, - "deploymentTimestamp": 1727351537118, + "evmAddress": "0x7eC8B89B092249a4E4B4438BE2313B8594324Ff6", + "version": "2.3.0", + "gitBranch": "v8/develop", + "gitCommitHash": "6ad3e9bcea8152c4d7370a33ab5f2f3988987552", + "deploymentBlock": 17252454, + "deploymentTimestamp": 1730273200639, "deployed": true }, "Profile": { @@ -311,12 +311,12 @@ "deployed": true }, "Paranet": { - "evmAddress": "0xeEC264Cf4BDa4bD386847B26d2c6A2A36e597326", - "version": "2.2.0", - "gitBranch": "improvement/curated-paranet-nodes", - "gitCommitHash": "de5edfde0f044d13bcdec8a33baaec934e2b62c4", - "deploymentBlock": 15791659, - "deploymentTimestamp": 1727351609154, + "evmAddress": "0x0186f33f97B9D57a574aEa913d08b40fcC143D11", + "version": "2.2.1", + "gitBranch": "v8/develop", + "gitCommitHash": "6ad3e9bcea8152c4d7370a33ab5f2f3988987552", + "deploymentBlock": 17252707, + "deploymentTimestamp": 1730273703569, "deployed": true } } diff --git a/deployments/base_sepolia_v8_test_contracts.json b/deployments/base_sepolia_v8_test_contracts.json index 13eb83e6..83f9c4b0 100644 --- a/deployments/base_sepolia_v8_test_contracts.json +++ b/deployments/base_sepolia_v8_test_contracts.json @@ -239,12 +239,12 @@ "deployed": true }, "Staking": { - "evmAddress": "0x4C2abdae3C271cd4965688b93a791EBC180D5F6E", - "version": "2.2.0", - "gitBranch": "v8/curated-paranets", - "gitCommitHash": "2f42b4c1922decb1aa952cc93c8a7c556b6193cd", - "deploymentBlock": 16045534, - "deploymentTimestamp": 1727859358928, + "evmAddress": "0x57C7408AD3a053a8B5a1E6785F7382c8e10C381B", + "version": "2.3.0", + "gitBranch": "v8/develop", + "gitCommitHash": "6ad3e9bcea8152c4d7370a33ab5f2f3988987552", + "deploymentBlock": 17252784, + "deploymentTimestamp": 1730273859670, "deployed": true }, "Profile": { @@ -311,12 +311,12 @@ "deployed": true }, "Paranet": { - "evmAddress": "0x56384E913Ea106404f9ea77e8d635d74068C56c2", - "version": "2.2.0", - "gitBranch": "v8/curated-paranets", - "gitCommitHash": "2f42b4c1922decb1aa952cc93c8a7c556b6193cd", - "deploymentBlock": 16045566, - "deploymentTimestamp": 1727859423252, + "evmAddress": "0xd68f00E072F7f1351810000cB618940908bd4DA9", + "version": "2.2.1", + "gitBranch": "v8/develop", + "gitCommitHash": "6ad3e9bcea8152c4d7370a33ab5f2f3988987552", + "deploymentBlock": 17252797, + "deploymentTimestamp": 1730273882952, "deployed": true } } diff --git a/deployments/gnosis_chiado_test_contracts.json b/deployments/gnosis_chiado_test_contracts.json deleted file mode 100644 index 961b5f40..00000000 --- a/deployments/gnosis_chiado_test_contracts.json +++ /dev/null @@ -1,322 +0,0 @@ -{ - "contracts": { - "AssertionStorage": { - "deployed": true, - "deploymentTimestamp": 1701108890140, - "evmAddress": "0xffDe7E801B4a56dd373f8435327E3709F04bD005", - "gitBranch": "main", - "gitCommitHash": "83b739de2ea02ce8027e2fccc6e04e9d5da48814", - "version": "1.0.0" - }, - "ContentAssetStorage": { - "deployed": true, - "deploymentTimestamp": 1702464503710, - "evmAddress": "0xeA3423e02c8d231532dab1BCE5D034f3737B3638", - "gitBranch": "main", - "gitCommitHash": "24d3e2392c0bb6a6164533219a84cd216b46a6a5", - "version": "2.0.1" - }, - "Hub": { - "deployed": true, - "deploymentTimestamp": 1701108752055, - "evmAddress": "0xC06210312C9217A0EdF67453618F5eB96668679A", - "gitBranch": "main", - "gitCommitHash": "83b739de2ea02ce8027e2fccc6e04e9d5da48814", - "version": "2.0.0" - }, - "HubController": { - "deployed": true, - "deploymentTimestamp": 1702464414306, - "evmAddress": "0x9197fD3277cA04E7FF66257F2E89A11998105D4d", - "gitBranch": "main", - "gitCommitHash": "24d3e2392c0bb6a6164533219a84cd216b46a6a5", - "version": "1.0.1" - }, - "IdentityStorage": { - "evmAddress": "0x2f5f89DED7c01724BbE37CC6F65298633B1C61fb", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202467, - "deploymentTimestamp": 1707755061471, - "deployed": true - }, - "ProfileStorage": { - "evmAddress": "0x1239305669EDB283a57ae2De109e9c1fe28a9F66", - "version": "1.0.0", - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202474, - "deploymentTimestamp": 1707755098795, - "deployed": true - }, - "ServiceAgreementStorageProxy": { - "deployed": true, - "deploymentTimestamp": 1701109021126, - "evmAddress": "0x1F43763970184be72b75Aa1c7F29a8794B8B815A", - "gitBranch": "main", - "gitCommitHash": "83b739de2ea02ce8027e2fccc6e04e9d5da48814", - "version": "1.0.0" - }, - "ServiceAgreementStorageV1": { - "deployed": true, - "deploymentTimestamp": 1701108985392, - "evmAddress": "0xE3f97f140fa4dbbc129ac6A1bA4F0a3D8F629f4a", - "gitBranch": "main", - "gitCommitHash": "83b739de2ea02ce8027e2fccc6e04e9d5da48814", - "version": "1.0.0" - }, - "ServiceAgreementStorageV1U1": { - "deployed": true, - "deploymentTimestamp": 1701109003381, - "evmAddress": "0x092342A18C1c1df2728315c91648fD3B42D03e0c", - "gitBranch": "main", - "gitCommitHash": "83b739de2ea02ce8027e2fccc6e04e9d5da48814", - "version": "1.0.0" - }, - "ShardingTableStorage": { - "evmAddress": "0x05c9B5d26935F2614AE53A3A791552E9b55dB402", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202468, - "deploymentTimestamp": 1707755067975, - "deployed": true - }, - "StakingStorage": { - "evmAddress": "0x2f621C951F50B999Aa98d38E89d84D70B39226AF", - "version": "1.0.0", - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202470, - "deploymentTimestamp": 1707755078083, - "deployed": true - }, - "Token": { - "deployed": true, - "evmAddress": "0x9cFa71394906fa38399aD305E7Ca97b00e3b4449" - }, - "UnfinalizedStateStorage": { - "deployed": true, - "deploymentTimestamp": 1701109037643, - "evmAddress": "0xF6FD36d9C9724318fD6272bFD351466B762BCCE7", - "gitBranch": "main", - "gitCommitHash": "83b739de2ea02ce8027e2fccc6e04e9d5da48814", - "version": "1.0.0" - }, - "WhitelistStorage": { - "deployed": true, - "deploymentTimestamp": 1701108834800, - "evmAddress": "0x422E1Ba4804d17A2DC491faAf0300a53D1964B15", - "gitBranch": "main", - "gitCommitHash": "83b739de2ea02ce8027e2fccc6e04e9d5da48814", - "version": "1.0.0" - }, - "ParametersStorage": { - "evmAddress": "0x3ab885f3DF70828ca3ae3880a8D19cd83F33AD16", - "version": "1.1.1", - "gitBranch": "main", - "gitCommitHash": "06afb8b08c1f5afb779d1c89157021bc70f2fe98", - "deploymentTimestamp": 1707488945746, - "deployed": true - }, - "HashingProxy": { - "evmAddress": "0x022bFebD51235318db2E0FB1a3837F00F89ca080", - "version": "1.0.1", - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202457, - "deploymentTimestamp": 1707755013408, - "deployed": true - }, - "SHA256": { - "evmAddress": "0x5b61eeb3f148Eb675777B7a47760f69eabDC4811", - "version": null, - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202459, - "deploymentTimestamp": 1707755023236, - "deployed": true - }, - "ScoringProxy": { - "evmAddress": "0x2bb3566E8b95C22f5CE702f5fFDfaA70620025b8", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202461, - "deploymentTimestamp": 1707755033847, - "deployed": true - }, - "Log2PLDSF": { - "evmAddress": "0xF9f97d2a37C595141CaB81f5F36E72140066F0aB", - "version": null, - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202463, - "deploymentTimestamp": 1707755043822, - "deployed": true - }, - "LinearSum": { - "evmAddress": "0xe937CF669748Cd28830039f387E799a43b4c307C", - "version": null, - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202465, - "deploymentTimestamp": 1707755053990, - "deployed": true - }, - "Assertion": { - "evmAddress": "0x2CfFa57B6f10329B8Ae4C1CCd5E89577F545d031", - "version": "1.0.1", - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202475, - "deploymentTimestamp": 1707755100814, - "deployed": true - }, - "Identity": { - "evmAddress": "0x5abDC7506d19a243415e67426094Ff98071fEfBA", - "version": "1.1.0", - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202476, - "deploymentTimestamp": 1707755107604, - "deployed": true - }, - "ShardingTable": { - "evmAddress": "0x2769b841751f9e84EFd0D8d620dC28542f2D47A8", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202478, - "deploymentTimestamp": 1707755117674, - "deployed": true - }, - "Profile": { - "evmAddress": "0x55F7185eF55bf04876eCDC088c6a8F35A642c6f8", - "version": "1.2.0", - "gitBranch": "feature/paranets", - "gitCommitHash": "afd2acd78886641415e423de5a20ec19df88b621", - "deploymentBlock": 10188284, - "deploymentTimestamp": 1717766652633, - "deployed": true - }, - "CommitManagerV1": { - "evmAddress": "0xccdAbea65eAf9700CF068e0776A2c5B12d160C1e", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202483, - "deploymentTimestamp": 1707755143682, - "deployed": true - }, - "CommitManagerV1U1": { - "evmAddress": "0x3246012BC7c9Bf13Dc00166Cf969467Ef93bf7E5", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202485, - "deploymentTimestamp": 1707755154637, - "deployed": true - }, - "ProofManagerV1": { - "evmAddress": "0x551a9f92478A8cFC8AF187b7996E950C8101ea56", - "version": "1.0.3", - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202487, - "deploymentTimestamp": 1707755162081, - "deployed": true - }, - "ProofManagerV1U1": { - "evmAddress": "0xB72b9865a922305Af83803472d6054d4488B9Cc4", - "version": "1.0.3", - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202489, - "deploymentTimestamp": 1707755173692, - "deployed": true - }, - "ServiceAgreementV1": { - "evmAddress": "0x2c780a3AcC3b75fb55B50A9064180F46E872F294", - "version": "1.1.1", - "gitBranch": "main", - "gitCommitHash": "8877334d94d89edfa2fea5bff3cd7f367a8609ae", - "deploymentBlock": 8202491, - "deploymentTimestamp": 1707755184879, - "deployed": true - }, - "NodeOperatorFeesStorage": { - "evmAddress": "0x692b3CC200BccF4c6ee0969818Da6c1a88A8cBC7", - "version": "2.0.0", - "gitBranch": "fix/active-node-operator-fee", - "gitCommitHash": "26d06f055165991b60936cad3dfb14ba3b2afe9b", - "deploymentBlock": 9415093, - "deploymentTimestamp": 1713883778621, - "deployed": true - }, - "Staking": { - "evmAddress": "0xe4ce91C83B018B6E1e5a117eD899F35E502400E0", - "version": "2.2.0", - "gitBranch": "main", - "gitCommitHash": "b9e7dede2a75acf193272f84b1a5ce155210e47a", - "deploymentBlock": 11519686, - "deploymentTimestamp": 1724854815721, - "deployed": true - }, - "ContentAsset": { - "evmAddress": "0x20A489D9dc7d2D241AF24C650d71631722aF0Aa1", - "version": "2.1.0", - "gitBranch": "main", - "gitCommitHash": "7700a1a2a9389f0bdddd95a9dafb8a294e2d732d", - "deploymentBlock": 10372822, - "deploymentTimestamp": 1718695363704, - "deployed": true - }, - "ParanetsRegistry": { - "evmAddress": "0x3Dd6e2baEd8e28fB8bB20a6C7d520eB111c7b85A", - "version": "2.1.0", - "gitBranch": "improvement/paranet-incentives-additional-getters", - "gitCommitHash": "bbf78d963b46a63c4c55fd6a82fc0bbdb59c40bc", - "deploymentBlock": 10360038, - "deploymentTimestamp": 1718630966354, - "deployed": true - }, - "ParanetServicesRegistry": { - "evmAddress": "0x5978e2507a818c469CC4b1202493e48365eD74A4", - "version": "2.1.0", - "gitBranch": "improvement/paranet-incentives-additional-getters", - "gitCommitHash": "bbf78d963b46a63c4c55fd6a82fc0bbdb59c40bc", - "deploymentBlock": 10360039, - "deploymentTimestamp": 1718630972351, - "deployed": true - }, - "ParanetKnowledgeAssetsRegistry": { - "evmAddress": "0xEA68509e996305002965BFa5c8314529457136F7", - "version": "2.0.0", - "gitBranch": "improvement/paranet-incentives-additional-getters", - "gitCommitHash": "bbf78d963b46a63c4c55fd6a82fc0bbdb59c40bc", - "deploymentBlock": 10360040, - "deploymentTimestamp": 1718630978043, - "deployed": true - }, - "ParanetKnowledgeMinersRegistry": { - "evmAddress": "0x7D61Ab26c2B644b2ae20AA5E16845bA3Ea6d25f7", - "version": "2.0.1", - "gitBranch": "improvement/paranet-incentives-additional-getters", - "gitCommitHash": "bbf78d963b46a63c4c55fd6a82fc0bbdb59c40bc", - "deploymentBlock": 10360042, - "deploymentTimestamp": 1718630988275, - "deployed": true - }, - "Paranet": { - "evmAddress": "0x69Ca47Ccb0c9838417Ef001eCE184350b41f9Ff7", - "version": "2.1.3", - "gitBranch": "improvement/paranet-incentives-additional-getters", - "gitCommitHash": "bbf78d963b46a63c4c55fd6a82fc0bbdb59c40bc", - "deploymentBlock": 10360044, - "deploymentTimestamp": 1718630997982, - "deployed": true - } - } -} diff --git a/deployments/gnosis_mainnet_contracts.json b/deployments/gnosis_mainnet_contracts.json deleted file mode 100644 index 0691dca4..00000000 --- a/deployments/gnosis_mainnet_contracts.json +++ /dev/null @@ -1,330 +0,0 @@ -{ - "contracts": { - "Hub": { - "deployed": true, - "deploymentTimestamp": 1703022869550, - "evmAddress": "0xbEF14fc04F870c2dD65c13Df4faB6ba01A9c746b", - "gitBranch": "main", - "gitCommitHash": "c993c8564d17e5b8fbab770b020d7c926608ea24", - "version": "2.0.0" - }, - "HubController": { - "deployed": true, - "deploymentTimestamp": 1703022879509, - "evmAddress": "0x48EA24e5C817C13215B3121bd6Fcc6B93D3c0caC", - "gitBranch": "main", - "gitCommitHash": "c993c8564d17e5b8fbab770b020d7c926608ea24", - "version": "1.0.2" - }, - "Token": { - "deployed": true, - "evmAddress": "0xEddd81E0792E764501AaE206EB432399a0268DB5" - }, - "ParametersStorage": { - "evmAddress": "0xce472e665287cDa46AE63696AE6d06A2ab2c041b", - "version": "1.1.1", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446787, - "deploymentTimestamp": 1707908232710, - "deployed": true - }, - "WhitelistStorage": { - "evmAddress": "0x50342047B2015E9ABe4d1a1f8748216F34017462", - "version": "1.0.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446791, - "deploymentTimestamp": 1707908266619, - "deployed": true - }, - "HashingProxy": { - "evmAddress": "0x6f67914ADA921383B0Caa7Ac6379d8b7eEfaaa51", - "version": "1.0.1", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446794, - "deploymentTimestamp": 1707908272894, - "deployed": true - }, - "SHA256": { - "evmAddress": "0x5f47719edb91da6d0182Dd6eFbFCaBFF838d2E5D", - "version": null, - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446796, - "deploymentTimestamp": 1707908299324, - "deployed": true - }, - "ScoringProxy": { - "evmAddress": "0x54604eCee27f99ccA7eCd354F2524A2B9459b615", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446800, - "deploymentTimestamp": 1707908309923, - "deployed": true - }, - "Log2PLDSF": { - "evmAddress": "0xF0623380b172250e204cd6ab151Be2e51E47A0D3", - "version": null, - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446802, - "deploymentTimestamp": 1707908320008, - "deployed": true - }, - "LinearSum": { - "evmAddress": "0x9E4474E2D161aC88Ea2064208630D9674dD465F0", - "version": null, - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446803, - "deploymentTimestamp": 1707908339610, - "deployed": true - }, - "AssertionStorage": { - "evmAddress": "0x22FAF11FF0a3182B57067c88149f4F9f5633cf4c", - "version": "1.0.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446811, - "deploymentTimestamp": 1707908370080, - "deployed": true - }, - "IdentityStorage": { - "evmAddress": "0xe369328795B24853C53132186DE45757105f79e4", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446832, - "deploymentTimestamp": 1707908485534, - "deployed": true - }, - "ShardingTableStorage": { - "evmAddress": "0xC6425168794Cb62B7E4288CF8bEa69e4EEB245Ae", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446835, - "deploymentTimestamp": 1707908492282, - "deployed": true - }, - "StakingStorage": { - "evmAddress": "0xC317969a8fBC36E3fD70351eC6Dd816662ABadCF", - "version": "1.0.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446837, - "deploymentTimestamp": 1707908502792, - "deployed": true - }, - "ProfileStorage": { - "evmAddress": "0x5b52765a7A46196f7a8c7dBec234D3Df23248BB4", - "version": "1.0.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446841, - "deploymentTimestamp": 1707908531490, - "deployed": true - }, - "ServiceAgreementStorageV1": { - "evmAddress": "0xF24DE7884A55DcD71c43f68BF2F174F1106fE1Dd", - "version": "1.0.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446843, - "deploymentTimestamp": 1707908537778, - "deployed": true - }, - "ServiceAgreementStorageV1U1": { - "evmAddress": "0xa97A72D0d59EA811d5B8Ba7393176654FE7729e5", - "version": "1.0.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446845, - "deploymentTimestamp": 1707908548273, - "deployed": true - }, - "ServiceAgreementStorageProxy": { - "evmAddress": "0x58B014Ee9296C4BE5dec056a7577Df2d18aa5974", - "version": "1.0.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446848, - "deploymentTimestamp": 1707908569673, - "deployed": true - }, - "ContentAssetStorage": { - "evmAddress": "0xf81a8C0008DE2DCdb73366Cf78F2b178616d11DD", - "version": "2.0.1", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446850, - "deploymentTimestamp": 1707908581380, - "deployed": true - }, - "UnfinalizedStateStorage": { - "evmAddress": "0x896CCbCEB7a5B30f8a68ec02bee79A50007095Ba", - "version": "1.0.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446852, - "deploymentTimestamp": 1707908588808, - "deployed": true - }, - "Assertion": { - "evmAddress": "0xe0eb7A3cd98cAD1a5AE744a3B70BA767c88C23a3", - "version": "1.0.1", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446854, - "deploymentTimestamp": 1707908607100, - "deployed": true - }, - "Identity": { - "evmAddress": "0x16A170D7552D5A14be0dAc2AC25456B720cdee59", - "version": "1.1.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446891, - "deploymentTimestamp": 1707908802696, - "deployed": true - }, - "ShardingTable": { - "evmAddress": "0x0cD31e3Ca36cff2EFBDda27B1D40c36928a4b594", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446893, - "deploymentTimestamp": 1707908815590, - "deployed": true - }, - "Staking": { - "evmAddress": "0x8883aA8cd98fCf6D9203b731F843Fe9eed09E3bb", - "version": "2.2.0", - "gitBranch": "main", - "gitCommitHash": "b9e7dede2a75acf193272f84b1a5ce155210e47a", - "deploymentBlock": 35708723, - "deploymentTimestamp": 1724834659300, - "deployed": true - }, - "Profile": { - "evmAddress": "0x262fCB804E03aadC4858e940950E932DA53F41B0", - "version": "1.2.0", - "gitBranch": "deployment/4.3.0", - "gitCommitHash": "7bd7fcbc9d5e8bfa5eb47573d57b0958515aca00", - "deploymentBlock": 34443980, - "deploymentTimestamp": 1718286050353, - "deployed": true - }, - "CommitManagerV1": { - "evmAddress": "0x3E8C4B4EfC5BE76812d598449BA010E206516eB9", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446899, - "deploymentTimestamp": 1707908865673, - "deployed": true - }, - "CommitManagerV1U1": { - "evmAddress": "0xaf496a2840d15Ee4E07962682EE4bE26C7932391", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446904, - "deploymentTimestamp": 1707908873240, - "deployed": true - }, - "ProofManagerV1": { - "evmAddress": "0xdDA3c01E795881C27A6B796e935061829E5F66Ce", - "version": "1.0.3", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446907, - "deploymentTimestamp": 1707908897432, - "deployed": true - }, - "ProofManagerV1U1": { - "evmAddress": "0xA1Af6Edf76aBBab6B255892F6337f1365B3B73d7", - "version": "1.0.3", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446910, - "deploymentTimestamp": 1707908908676, - "deployed": true - }, - "ServiceAgreementV1": { - "evmAddress": "0x9A8d89d653aa4E040577a78760435638Feb174Ec", - "version": "1.1.1", - "gitBranch": "main", - "gitCommitHash": "26881f1a79eaf41f13d1c48a2c5952d0a1d14274", - "deploymentBlock": 32446912, - "deploymentTimestamp": 1707908922271, - "deployed": true - }, - "ContentAsset": { - "evmAddress": "0x1985439E09719EfdC8bcd753936D5059E8E98df4", - "version": "2.1.0", - "gitBranch": "main", - "gitCommitHash": "7700a1a2a9389f0bdddd95a9dafb8a294e2d732d", - "deploymentBlock": 34523434, - "deploymentTimestamp": 1718695496879, - "deployed": true - }, - "NodeOperatorFeesStorage": { - "evmAddress": "0x2F2031A35dE9297f2372569551F8682E818C4943", - "version": "2.0.2", - "gitBranch": "operatorFee-fixes-2", - "gitCommitHash": "38d7bc4595f2ff59bf0d3d11efd291241ecc992f", - "deploymentBlock": 34206991, - "deploymentTimestamp": 1717062353134, - "deployed": true - }, - "ParanetsRegistry": { - "evmAddress": "0xe0Be6F5a415eF20CE763e9927d901145c00f8aB4", - "version": "2.1.0", - "gitBranch": "improvement/paranet-incentives-additional-getters", - "gitCommitHash": "4cef06a0b27b03e64d68215f5b3df091b73e31e2", - "deploymentBlock": 34510987, - "deploymentTimestamp": 1718631494369, - "deployed": true - }, - "ParanetServicesRegistry": { - "evmAddress": "0xe8cF6A3b5Ae913F280A27F94461eEb0F2a8969b9", - "version": "2.1.0", - "gitBranch": "improvement/paranet-incentives-additional-getters", - "gitCommitHash": "4cef06a0b27b03e64d68215f5b3df091b73e31e2", - "deploymentBlock": 34510989, - "deploymentTimestamp": 1718631509049, - "deployed": true - }, - "ParanetKnowledgeAssetsRegistry": { - "evmAddress": "0x1f7ce865a32928E202346136f5f73EB1757067dD", - "version": "2.0.0", - "gitBranch": "improvement/paranet-incentives-additional-getters", - "gitCommitHash": "4cef06a0b27b03e64d68215f5b3df091b73e31e2", - "deploymentBlock": 34510991, - "deploymentTimestamp": 1718631518947, - "deployed": true - }, - "ParanetKnowledgeMinersRegistry": { - "evmAddress": "0x7c9ea1bCa803F02B2985C84038e6233c51213930", - "version": "2.0.1", - "gitBranch": "improvement/paranet-incentives-additional-getters", - "gitCommitHash": "4cef06a0b27b03e64d68215f5b3df091b73e31e2", - "deploymentBlock": 34510993, - "deploymentTimestamp": 1718631529879, - "deployed": true - }, - "Paranet": { - "evmAddress": "0xb3271af260275d16f73d4a033B61d0bD8c45f264", - "version": "2.1.3", - "gitBranch": "improvement/paranet-incentives-additional-getters", - "gitCommitHash": "4cef06a0b27b03e64d68215f5b3df091b73e31e2", - "deploymentBlock": 34510996, - "deploymentTimestamp": 1718631542236, - "deployed": true - } - } -} diff --git a/deployments/otp_mainnet_contracts.json b/deployments/otp_mainnet_contracts.json deleted file mode 100644 index b3fbeea1..00000000 --- a/deployments/otp_mainnet_contracts.json +++ /dev/null @@ -1,321 +0,0 @@ -{ - "contracts": { - "Assertion": { - "deployed": true, - "deploymentTimestamp": 1703088297036, - "evmAddress": "0xA3E0553Cc0fd9bA586d23109D949980374D72134", - "gitBranch": "main", - "gitCommitHash": "56fd79b5ed1d45284edba9f3f88fe7d14c8c2287", - "substrateAddress": "5EMjsczu1e733AFHTxZkMjqPDSNstQetCCBkcAcYH3rWCavu", - "version": "1.0.1" - }, - "AssertionStorage": { - "deployed": true, - "evmAddress": "0x15D40218D61d2F99313F07D9dC285df37eee265e", - "substrateAddress": "5EMjsczQYos6eg1jtTqPi8GQ1VcNswLPcVaBz7n522r9iF4X" - }, - "ContentAssetStorage": { - "deployed": true, - "evmAddress": "0x5cAC41237127F94c2D21dAe0b14bFeFa99880630", - "substrateAddress": "5EMjsczek95xeaypyqHJDkBBtrrSXU5kvGpYfrbiYmt7tyVj" - }, - "HashingProxy": { - "deployed": true, - "deploymentTimestamp": 1703088194864, - "evmAddress": "0xA5d7c299fF608C0D3149B1A6523A1536F9909F7b", - "gitBranch": "main", - "gitCommitHash": "56fd79b5ed1d45284edba9f3f88fe7d14c8c2287", - "substrateAddress": "5EMjsczuQVeCX4CFJDgDesBJtTp6884BsRKmKzJPDBQ41aY1", - "version": "1.0.1" - }, - "Hub": { - "deployed": true, - "evmAddress": "0x5fA7916c48Fe6D5F1738d12Ad234b78c90B4cAdA", - "substrateAddress": "5EMjsczfLnupWbYdJh2XoriNjMN1hYG8GpqM3xzFNg1VwG8v" - }, - "HubController": { - "deployed": true, - "deploymentTimestamp": 1703069899375, - "evmAddress": "0xC9d90B4AF12dE5d25767fcd7d34529e432730F51", - "gitBranch": "main", - "gitCommitHash": "56fd79b5ed1d45284edba9f3f88fe7d14c8c2287", - "substrateAddress": "5EMjsd12cvzooYETdVd9b7Ab2EDpbwVuFnxMPU2JMgnGJktE", - "version": "1.0.2" - }, - "Identity": { - "evmAddress": "0x8B5d66e363CF622E1448670F344f887C5eb2411f", - "substrateAddress": "5EMjsczp6n3UXMnkZq7Yb92MXqb3w5ZqztjVq1zcESNMYydq", - "version": "1.1.0", - "gitBranch": "gnosis-mainnet-delegations", - "gitCommitHash": "5756f47b75b5c1e9503ecbb3c905fac3ba7f75ea", - "deploymentBlock": 4319953, - "deploymentTimestamp": 1707917812243, - "deployed": true - }, - "IdentityStorage": { - "deployed": true, - "evmAddress": "0x2C81a650A2E9C8eB88d941A8ab50E1F3eEEe08Ac", - "substrateAddress": "5EMjsczV6NGqodVLdCx9TKsqkYend2geBAuKMajx8RzG6EBL" - }, - "ParametersStorage": { - "evmAddress": "0x45ca950f69663DDCD98B66D3a2d4F590cCe84bb1", - "substrateAddress": "5EMjsczaADgKRgqA5d5yXjY5ADoduwVUc5EihPvKyebYYC82", - "version": "1.1.1", - "gitBranch": "gnosis-mainnet-delegations", - "gitCommitHash": "5756f47b75b5c1e9503ecbb3c905fac3ba7f75ea", - "deploymentBlock": 4319951, - "deploymentTimestamp": 1707917780095, - "deployed": true - }, - "Profile": { - "evmAddress": "0xaC5838db2f8ae4F64d161b202e8429dfF42df36c", - "substrateAddress": "5EMjsczvi4DRTczWFyz83isaCcSeFnnmfMDmFxYWv1LhRZU1", - "version": "1.2.0", - "gitBranch": "deployment/4.3.0", - "gitCommitHash": "7bd7fcbc9d5e8bfa5eb47573d57b0958515aca00", - "deploymentBlock": 5134300, - "deploymentTimestamp": 1718285482644, - "deployed": true - }, - "ProfileStorage": { - "deployed": true, - "evmAddress": "0x625Eef3714D13620850FE76725D44698a5fE171D", - "substrateAddress": "5EMjsczftMq5bR62RatL5TB3wAxvibERDuP3A3Z9p8AXwXef" - }, - "ProofManagerV1": { - "evmAddress": "0x74Cb5C6F864F236618114Ba8A16D6583c95C4227", - "substrateAddress": "5EMjsczjaUJn9WbpNrJWyu71brnSzSm3ovwJYGEkPMnQEDUn", - "version": "1.0.3", - "gitBranch": "main", - "gitCommitHash": "cdd09025ee035eb72c4322639cefe1848dd90ecb", - "deploymentBlock": 4786007, - "deploymentTimestamp": 1713972349597, - "deployed": true - }, - "ProofManagerV1U1": { - "evmAddress": "0x851bad0EcFf733c0d5C02c1778C532f8Da880140", - "substrateAddress": "5EMjscznr4f27iDXyMKqYLafj6eLkT8zRev23iDiAEhH8dQa", - "version": "1.0.3", - "gitBranch": "main", - "gitCommitHash": "cdd09025ee035eb72c4322639cefe1848dd90ecb", - "deploymentBlock": 4786010, - "deploymentTimestamp": 1713972387998, - "deployed": true - }, - "SHA256": { - "deployed": true, - "deploymentTimestamp": 1703088224689, - "evmAddress": "0x86235908122a5343dEDA07FCE367D19542C02295", - "gitBranch": "main", - "gitCommitHash": "56fd79b5ed1d45284edba9f3f88fe7d14c8c2287", - "substrateAddress": "5EMjsczo42uoNbE4MMtd17VxJxBj6d5e7cXFPH6n7aw4VAG7", - "version": null - }, - "ServiceAgreementStorageProxy": { - "deployed": true, - "evmAddress": "0xDb2752D8a31c67C51283E8cfF24E4B86c11C1768", - "substrateAddress": "5EMjsd16643PWiRFrq1LsbEjkKY7kwjkdDEDiaCEAViMcb2Z" - }, - "ServiceAgreementStorageV1": { - "deployed": true, - "evmAddress": "0x61BB5F3Db740a9cb3451049c5166f319a18927eb", - "substrateAddress": "5EMjsczfkwAZKF2M8r93J7bgmenKucW8DjaAuqMUqqG2FMnS" - }, - "ServiceAgreementStorageV1U1": { - "deployed": true, - "evmAddress": "0xB8047175EFAC487Bb53f16783E796A4355CfC1a7", - "substrateAddress": "5EMjsczy3iHG1pBHx4JueZxGTqoUyqamxkSmyvStQKheGPo1" - }, - "ServiceAgreementV1": { - "evmAddress": "0x0ddF30cd61c0b26A20b4b1eDf1922EcC28d12538", - "substrateAddress": "5EMjsczNxLsP15k2U8dMfQh22SQxGQRaxiVJRu2tSSFT93Dv", - "version": "1.1.1", - "gitBranch": "main", - "gitCommitHash": "cdd09025ee035eb72c4322639cefe1848dd90ecb", - "deploymentBlock": 4786023, - "deploymentTimestamp": 1713972578993, - "deployed": true - }, - "ShardingTable": { - "evmAddress": "0xF1932C7f8282C750A46Db5F8c9BA49D7d869732e", - "substrateAddress": "5EMjsd1AadDnKpqtuQTkWusfAUoU9LjJdwBNxFRMSG8b42Xx", - "version": "2.0.1", - "gitBranch": "mainnet-deployment/4.2.7", - "gitCommitHash": "8839a0e5c92a413b06d20fa15335950bb625f890", - "deploymentBlock": 4790850, - "deploymentTimestamp": 1714058535983, - "deployed": true - }, - "StakingStorage": { - "deployed": true, - "evmAddress": "0x207a5Ce5BC0a36753C3436eE108221187B20103F", - "substrateAddress": "5EMjsczSgaRrqbK2ao5fT5Z8f8kTRz14Qv8bHEV7jpdrEeK3" - }, - "Token": { - "deployed": true, - "evmAddress": "0xFfFFFFff00000000000000000000000000000001", - "substrateAddress": "5EMjsd1DUGXmZiLinvCzc3vG9GVfE5dE1TMBYKR5LMVDrVvU" - }, - "UnfinalizedStateStorage": { - "deployed": true, - "evmAddress": "0x7034BAAba9eEcFd7887e4aC5Ba9FB2bEf3b9B15d", - "substrateAddress": "5EMjsczif9UDkoxrU89gVE2ohdjxgja5ibKceJzSVJnzZqR7" - }, - "WhitelistStorage": { - "deployed": true, - "evmAddress": "0x6c54ddBF7887c306d253F0fd3d9CaB6da969Ac58", - "substrateAddress": "5EMjsczht7sKQb2oGkuGwKi9WBeinEB1mJ6bWkGLyApmUV1a" - }, - "ScoringProxy": { - "evmAddress": "0xBC6202F16F4110654F1DDd057B87eA47c464d2bF", - "substrateAddress": "5EMjsczyvSsKR7gTEfREkZcEvXNaeQFNJwnh2UxFciXjKaUG", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "cdd09025ee035eb72c4322639cefe1848dd90ecb", - "deploymentBlock": 4785986, - "deploymentTimestamp": 1713972053812, - "deployed": true - }, - "Log2PLDSF": { - "evmAddress": "0xdC83953Cb453a1059D7F2de8922ce982e2CDe9b5", - "substrateAddress": "5EMjsd16Ms21KRDRoSN7Z5uwmXgBQpouYGnhtm43mgQmEgau", - "version": null, - "gitBranch": "main", - "gitCommitHash": "cdd09025ee035eb72c4322639cefe1848dd90ecb", - "deploymentBlock": 4785987, - "deploymentTimestamp": 1713972075390, - "deployed": true - }, - "LinearSum": { - "evmAddress": "0xd83feed1818Def1D820FfC3aA6d1EB16a096Dd07", - "substrateAddress": "5EMjsd15WJg4ackfycBNGv1KYsjAgETaYxGRtrHpq1HZ7sRE", - "version": null, - "gitBranch": "main", - "gitCommitHash": "cdd09025ee035eb72c4322639cefe1848dd90ecb", - "deploymentBlock": 4785989, - "deploymentTimestamp": 1713972097517, - "deployed": true - }, - "NodeOperatorFeesStorage": { - "evmAddress": "0xe761209C8598a933b0F2CE3BdA11a9850Ca320BA", - "substrateAddress": "5EMjsd18Y8u6kqeznzaNcWNy4XpuX6TJTqvxsPRstGK1FMJb", - "version": "2.0.2", - "gitBranch": "operatorFee-fixes-2", - "gitCommitHash": "38d7bc4595f2ff59bf0d3d11efd291241ecc992f", - "deploymentBlock": 5035511, - "deploymentTimestamp": 1717062664410, - "deployed": true - }, - "Staking": { - "evmAddress": "0x666B604B1b32ca467a6eEF3257475D32f8ADD04b", - "substrateAddress": "5EMjsczghQorAAxG77BAa4V9YSAkJ8TfGRJsvaARzTNHdDgn", - "version": "2.2.0", - "gitBranch": "main", - "gitCommitHash": "b9e7dede2a75acf193272f84b1a5ce155210e47a", - "deploymentBlock": 5672930, - "deploymentTimestamp": 1724834500366, - "deployed": true - }, - "CommitManagerV1": { - "evmAddress": "0xc80dBd1982B7ce459c274DCd414FFc24B0C3AEDa", - "substrateAddress": "5EMjsd12G5divNiKte3z4Yb1wveejzvmc3aBkC21R9Jje4W3", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "cdd09025ee035eb72c4322639cefe1848dd90ecb", - "deploymentBlock": 4786003, - "deploymentTimestamp": 1713972293955, - "deployed": true - }, - "CommitManagerV1U1": { - "evmAddress": "0x100d8467f3872fCa0fE08907B7C765e628F57684", - "substrateAddress": "5EMjsczPPgxXnxUYvULykJTkSnBVu1LZfEqpNhxpAxsTt9at", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "cdd09025ee035eb72c4322639cefe1848dd90ecb", - "deploymentBlock": 4786005, - "deploymentTimestamp": 1713972328170, - "deployed": true - }, - "ContentAsset": { - "evmAddress": "0x56d9703DB8cb92aC63C0ac8E7e453C614214c964", - "substrateAddress": "5EMjsczdaTjArjC39ynKYksLNfstjJgQ5vVMcYm6CBmejcpR", - "version": "2.1.0", - "gitBranch": "deployment/4.3.0", - "gitCommitHash": "7bd7fcbc9d5e8bfa5eb47573d57b0958515aca00", - "deploymentBlock": 5134302, - "deploymentTimestamp": 1718285506531, - "deployed": true - }, - "ShardingTableStorage": { - "evmAddress": "0x729D2061Ce1c3B4ee5E5346f2FBd591c869e08Da", - "substrateAddress": "5EMjsczj98TgBeMsvGQ2QQJNS2JfgJk9HpbzziFZKHKb51QL", - "version": "2.0.0", - "gitBranch": "mainnet-deployment/4.2.7", - "gitCommitHash": "8839a0e5c92a413b06d20fa15335950bb625f890", - "deploymentBlock": 4790848, - "deploymentTimestamp": 1714058510226, - "deployed": true - }, - "ParanetsRegistry": { - "evmAddress": "0x9fB1f78A1fC627FEF61C88bF464F24Df52a78912", - "substrateAddress": "5EMjscztB3oVxfFhfgLRi5LDQR969k1vH9HroQoSYJhgrrsh", - "version": "2.1.0", - "gitBranch": "deployment/4.3.0", - "gitCommitHash": "7bd7fcbc9d5e8bfa5eb47573d57b0958515aca00", - "deploymentBlock": 5134290, - "deploymentTimestamp": 1718285361116, - "deployed": true - }, - "ParanetServicesRegistry": { - "evmAddress": "0x1aAaB7a4024B7208A40c8D13A05B685015f4581f", - "substrateAddress": "5EMjsczRX3RFW5iQovQuGjCS1HR1rmbsjrWp7YmZQpRzq6xg", - "version": "2.1.0", - "gitBranch": "deployment/4.3.0", - "gitCommitHash": "7bd7fcbc9d5e8bfa5eb47573d57b0958515aca00", - "deploymentBlock": 5134292, - "deploymentTimestamp": 1718285386068, - "deployed": true - }, - "ParanetKnowledgeAssetsRegistry": { - "evmAddress": "0x5bDA3b6220eE7aC0E5A4bA6D79B0a8d0C7145c67", - "substrateAddress": "5EMjsczeac6G6cR4UWqm6FqQKSa2TWfjYnanfYXe6pffvjpy", - "version": "2.0.0", - "gitBranch": "deployment/4.3.0", - "gitCommitHash": "7bd7fcbc9d5e8bfa5eb47573d57b0958515aca00", - "deploymentBlock": 5134294, - "deploymentTimestamp": 1718285410925, - "deployed": true - }, - "ParanetKnowledgeMinersRegistry": { - "evmAddress": "0xC766c36675913460EB0E6a09dbf5Dd515Ef3a0E3", - "substrateAddress": "5EMjsd128Vyz5bJS6jc7tbzviRosjdbcWAQ1jfy6cAuwsUuS", - "version": "2.0.1", - "gitBranch": "deployment/4.3.0", - "gitCommitHash": "7bd7fcbc9d5e8bfa5eb47573d57b0958515aca00", - "deploymentBlock": 5134296, - "deploymentTimestamp": 1718285432004, - "deployed": true - }, - "Paranet": { - "evmAddress": "0xAC2504326F31429938A890FC7847968874faAf71", - "substrateAddress": "5EMjsczvfjPWsLX4vm26dLoNTyKvMa3M7zpg1arxLY6Syxm6", - "version": "2.1.3", - "gitBranch": "improvement/paranet-incentives-additional-getters", - "gitCommitHash": "4cef06a0b27b03e64d68215f5b3df091b73e31e2", - "deploymentBlock": 5162780, - "deploymentTimestamp": 1718631412679, - "deployed": true - }, - "ParanetIncentivesPoolFactory": { - "evmAddress": "0x7749834AB8152de91B9b3252Da7750247F52F495", - "substrateAddress": "5EMjsczk5SaUrPcwJmAgXPbxqdWmWduN6z3JV6tSJAReRtJx", - "version": "2.0.0", - "gitBranch": "improvement/paranet-incentives-additional-getters", - "gitCommitHash": "4cef06a0b27b03e64d68215f5b3df091b73e31e2", - "deploymentBlock": 5162782, - "deploymentTimestamp": 1718631441728, - "deployed": true - } - }, - "deployedTimestamp": 1689935103953 -} diff --git a/deployments/otp_testnet_contracts.json b/deployments/otp_testnet_contracts.json deleted file mode 100644 index 290c012d..00000000 --- a/deployments/otp_testnet_contracts.json +++ /dev/null @@ -1,310 +0,0 @@ -{ - "contracts": { - "Assertion": { - "deployed": true, - "deploymentTimestamp": 1701860811955, - "evmAddress": "0xf305D2d97C7201Cea2A54A2B074baC2EdfCE7E45", - "gitBranch": "main", - "gitCommitHash": "b34eab2f67543ed17ca054d3fe7b79bb039a660d", - "substrateAddress": "5EMjsd1AsT9mmo58SwbNTadGtevCeGC4cwtFsezNmJKNaXKu", - "version": "1.0.1" - }, - "AssertionStorage": { - "deployed": true, - "evmAddress": "0x804C989a09F232fa77b3CC916c7882c8e96e883A", - "substrateAddress": "5EMjsczmtBByLwPDvM6M5C72wGLSAvv78T3sKeCQQ5vKEYR5" - }, - "ContentAsset": { - "evmAddress": "0x6077E732f2e3f1d009541c32dFD0fC93ed83b1Bf", - "substrateAddress": "5EMjsczfWFTpkW2r6gN1xrwpopLmZDYis5JHAAEjKVFocEHD", - "version": "2.1.0", - "gitBranch": "feature/paranets", - "gitCommitHash": "2844cf44e6a69c17a8e2a60b42167386373ee0c2", - "deploymentBlock": 4060910, - "deploymentTimestamp": 1717577677145, - "deployed": true - }, - "ContentAssetStorage": { - "deployed": true, - "evmAddress": "0x1A061136Ed9f5eD69395f18961a0a535EF4B3E5f", - "substrateAddress": "5EMjsczRPZtctbBNQ9SJnYHKkHYM6B2mKsj3aogYvuqhKV6q" - }, - "HashingProxy": { - "deployed": true, - "deploymentTimestamp": 1701860714494, - "evmAddress": "0x1DF7cfb6a3e1f1a22056467A341E6aa9D763539b", - "gitBranch": "main", - "gitCommitHash": "b34eab2f67543ed17ca054d3fe7b79bb039a660d", - "substrateAddress": "5EMjsczSBQaFdDWwPEdjoCSh937hcDphWhX7we4jRNPJHVuK", - "version": "1.0.1" - }, - "Hub": { - "deployed": true, - "evmAddress": "0xBbfF7Ea6b2Addc1f38A0798329e12C08f03750A6", - "substrateAddress": "5EMjsczyqyUGy4GyPPQa1fcyf4L3y3T5KWARhoMy4WejKxvY" - }, - "HubController": { - "deployed": true, - "evmAddress": "0x591575F5DC9d2FD6C68603E85Bfe0365bEDf11AB", - "substrateAddress": "5EMjscze2RssuPD9NTzW845nJ71CrxUNPNZqL9b1JFjmmpv4" - }, - "Identity": { - "evmAddress": "0xd3F06FFb6d69053276b2Ef35E5a9b185C3544Bb8", - "substrateAddress": "5EMjsd14eD99Mgcyssc26iJsQznQMPHSqFknLSAxycW4up5Q", - "version": "1.1.0", - "gitBranch": "chore/gnosis-testnet-redeployment", - "gitCommitHash": "92c82236385a86519dff966741b9dca15ab444b9", - "deploymentTimestamp": 1707499371301, - "deployed": true - }, - "IdentityStorage": { - "deployed": true, - "evmAddress": "0x50D592fEf72F1C98A83e5DAA07fC057889430f03", - "substrateAddress": "5EMjsczcNZDxEpTQCZzpfnvLMNf8mFToRoSJttr8rxSnRGpG" - }, - "ParametersStorage": { - "evmAddress": "0xe0358F4B95b66516c921F25b8BF997713c1eA807", - "substrateAddress": "5EMjsd176ooNehXAc1qNhNgSVYzgyorjVshHEYBHmN4nkBGn", - "version": "1.1.1", - "gitBranch": "chore/gnosis-testnet-redeployment", - "gitCommitHash": "92c82236385a86519dff966741b9dca15ab444b9", - "deploymentTimestamp": 1707499341954, - "deployed": true - }, - "Profile": { - "evmAddress": "0x7b4724736826a508bb29C5ff59f0FDB5406Da5Ca", - "substrateAddress": "5EMjsczkspZCTh7QDsaQimHFkR4gJrMt45bxsvxuQsSN8ZHo", - "version": "1.2.0", - "gitBranch": "feature/paranets", - "gitCommitHash": "2844cf44e6a69c17a8e2a60b42167386373ee0c2", - "deploymentBlock": 4060908, - "deploymentTimestamp": 1717577649034, - "deployed": true - }, - "ProfileStorage": { - "deployed": true, - "evmAddress": "0xf4d8fE67a28745aD3fb598e5D5060267CB3Dc2e7", - "substrateAddress": "5EMjsd1BEfDvDV8eWCT7JcroK4r6nEFyBUsvqkXxFtMm7ewv" - }, - "ProofManagerV1": { - "evmAddress": "0x39C94BD8021D5E73Cef763e68240Dc09B28Ebfc1", - "substrateAddress": "5EMjsczXkhdkS3tQVb67GvuMH6Dpa2PEvGVR4MxpVzvmxe2d", - "version": "1.0.3", - "gitBranch": "main", - "gitCommitHash": "f24cfc30b52b30b9dcacccb2c9468e6a43e490b2", - "deploymentBlock": 3836985, - "deploymentTimestamp": 1713961994863, - "deployed": true - }, - "ProofManagerV1U1": { - "evmAddress": "0xE1fFa42c9bCd365A6397A2522bEf5B5259eb80fB", - "substrateAddress": "5EMjsd17TbwYz6aqNjTbkogfKG8NAFeYLAy1PqBaaj7hdzZK", - "version": "1.0.3", - "gitBranch": "main", - "gitCommitHash": "f24cfc30b52b30b9dcacccb2c9468e6a43e490b2", - "deploymentBlock": 3836987, - "deploymentTimestamp": 1713962017206, - "deployed": true - }, - "SHA256": { - "deployed": true, - "deploymentTimestamp": 1701860738766, - "evmAddress": "0xB6631C6DFb76Ca92CB14D38e57Ba9B891439E3a0", - "gitBranch": "main", - "gitCommitHash": "b34eab2f67543ed17ca054d3fe7b79bb039a660d", - "substrateAddress": "5EMjsczximS9dHgYr7MewJMud7vbcQx396pkHuZ89SEU99AR", - "version": null - }, - "ServiceAgreementStorageProxy": { - "deployed": true, - "evmAddress": "0x6E658f58E94960cb4B6E57616a705c30D894E59a", - "substrateAddress": "5EMjscziJ7w5MCKxeWHf94zZNNJwFdE8wmCGkAupQUu6YNtq" - }, - "ServiceAgreementStorageV1": { - "deployed": true, - "evmAddress": "0xF43B6A63f3f6479c8f972D95858a1684d5f129F5", - "substrateAddress": "5EMjsd1B7WKHA36XCAHdovQhUph9JANA9Ji9paoRFQ1Sxx7R" - }, - "ServiceAgreementStorageV1U1": { - "deployed": true, - "evmAddress": "0x4eFBa4d271B1daB62D4488A8892869b196FC611C", - "substrateAddress": "5EMjsczc13MR43nqy41bJhHyPQFRFCFjmyDAYJq755TsWsSG" - }, - "ServiceAgreementV1": { - "deployed": true, - "evmAddress": "0x082AC991000F6e8aF99679f5A2F46cB2Be4E101B", - "substrateAddress": "5EMjsczMp3b67s4P5JcMTZ4h4osrTNMQLG4LsbCNsiEJ5CPn" - }, - "ShardingTable": { - "evmAddress": "0xdebabbbe844b0363B776456bc7872024b12FA8e2", - "substrateAddress": "5EMjsd16ocLhJHEYqAuuKPxqo9cyhWhuq2xHt12jmH2jVNZo", - "version": "2.0.1", - "gitBranch": "main", - "gitCommitHash": "ce3b55f823e0c2163b7e2a0b4ab227c3fd334a7b", - "deploymentBlock": 3801218, - "deploymentTimestamp": 1713445999399, - "deployed": true - }, - "StakingStorage": { - "deployed": true, - "evmAddress": "0x0F2F3dEac4bB44342881bE4CE9556DabC396411A", - "substrateAddress": "5EMjsczPDbhdT5zdGoxywZu8GhLJN2RKkCLvLYUjAKyr2Gc4" - }, - "Token": { - "deployed": true, - "evmAddress": "0xffffffff00000000000000000000000000000001", - "substrateAddress": "5EMjsd1DUGXmZiLinvCzc3vG9GVfE5dE1TMBYKR5LMVDrVvU" - }, - "UnfinalizedStateStorage": { - "deployed": true, - "evmAddress": "0x79eE7E39cAC5C11C57cDe4672e36869fB4877b29", - "substrateAddress": "5EMjsczkcB5tSTpqRedXUoZo7FHvXCGGBL8qyutVQosJooGn" - }, - "WhitelistStorage": { - "deployed": true, - "evmAddress": "0xC539d3BCe5c8CD39Ad0fdaCF7f580e7F4A5CF958", - "substrateAddress": "5EMjsd11hDZAj6HGYQuJyUiEbE2hYHJLHzWz4GSVfiemQN4K" - }, - "ShardingTableStorage": { - "evmAddress": "0x40B32E43c806C6E8702d9069EE79F897A281D573", - "substrateAddress": "5EMjsczZ93ndbo4AEciSWzXRpvJfodkV1fKyRp3F9EsR4CMm", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "ce3b55f823e0c2163b7e2a0b4ab227c3fd334a7b", - "deploymentBlock": 3801215, - "deploymentTimestamp": 1713445959828, - "deployed": true - }, - "NodeOperatorFeesStorage": { - "evmAddress": "0xb3803E859d6f31a8107A575B014063cd0aF07698", - "substrateAddress": "5EMjsczx9DyhD3UfbjYrjcPVALvEhCpkYb8BX9Jb3otsSqkD", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "26d06f055165991b60936cad3dfb14ba3b2afe9b", - "deploymentBlock": 3831272, - "deploymentTimestamp": 1713883609933, - "deployed": true - }, - "ScoringProxy": { - "evmAddress": "0xFf31DA33e5B62729E31e5fC01f8282D8F33D854E", - "substrateAddress": "5EMjsd1DJujpWaetwF1rPGHe3GM31yq4EDPvyW1EHVmxPPPn", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "8dec09dc2f081aba8736e42a180d8fb94a997588", - "deploymentBlock": 3824599, - "deploymentTimestamp": 1713791772811, - "deployed": true - }, - "Log2PLDSF": { - "evmAddress": "0xa9DBf9Eb1c65b639DcB098c1a03686d9740670Db", - "substrateAddress": "5EMjsczvDAxnYdSd7ywYJepFvXc8sJjbQq1UQir1apo2e1WF", - "version": null, - "gitBranch": "deployment/4.2.7", - "gitCommitHash": "e6a543a215e0738289587300f1793ada8a6f3f34", - "deploymentBlock": 3830957, - "deploymentTimestamp": 1713879038211, - "deployed": true - }, - "LinearSum": { - "evmAddress": "0x6051E661cd914279336602a4F36532d3124a5d37", - "substrateAddress": "5EMjsczfUXQ9QYNYKZgFmBPE1MftHDgb1JwuFnRBFZMaHWBR", - "version": null, - "gitBranch": "main", - "gitCommitHash": "8dec09dc2f081aba8736e42a180d8fb94a997588", - "deploymentBlock": 3824603, - "deploymentTimestamp": 1713791859640, - "deployed": true - }, - "Staking": { - "evmAddress": "0x873d2Ac030ba5cb14184E6Af3152fcfF7555b432", - "substrateAddress": "5EMjsczoGpwyeX7YPDeYFej1RGnqi8CeW6b6Vw5xA4P6pN3k", - "version": "2.2.0", - "gitBranch": "main", - "gitCommitHash": "b9e7dede2a75acf193272f84b1a5ce155210e47a", - "deploymentBlock": 4354638, - "deploymentTimestamp": 1724854704943, - "deployed": true - }, - "CommitManagerV1": { - "evmAddress": "0x75213EB2F05576a2eA019bD67796a9Ee2556bcC5", - "substrateAddress": "5EMjsczjeNSaSkeHA9NfWJnbYC4vP2cmXe2f6RzfwmFJMS9q", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "8dec09dc2f081aba8736e42a180d8fb94a997588", - "deploymentBlock": 3824610, - "deploymentTimestamp": 1713791919341, - "deployed": true - }, - "CommitManagerV1U1": { - "evmAddress": "0xA1E3bc1D6686d9322e790B33940d1e7e1Cb2e10c", - "substrateAddress": "5EMjscztcYxC2cKKLB9VF8VFX8Hy2PsVeDKdc97muMEApjYy", - "version": "2.0.0", - "gitBranch": "main", - "gitCommitHash": "8dec09dc2f081aba8736e42a180d8fb94a997588", - "deploymentBlock": 3824612, - "deploymentTimestamp": 1713791941365, - "deployed": true - }, - "ParanetsRegistry": { - "evmAddress": "0xF8C8FDE0931710e08e48Cb74d08cd6cb21512B71", - "substrateAddress": "5EMjsd1C2RJt1M4Wc4nYX1js3udvzYTdox43bgCQ1H9PSdfY", - "version": "2.1.0", - "gitBranch": "improvement/paranet-incentives-calculation", - "gitCommitHash": "f52e4b5ec305ec0bc4f7652f406f081c07d6010c", - "deploymentBlock": 4095337, - "deploymentTimestamp": 1718280121450, - "deployed": true - }, - "ParanetServicesRegistry": { - "evmAddress": "0xfD791291D8E853311c022927f79853C8d441E7cE", - "substrateAddress": "5EMjsd1Cxu9tPixbWUwC6JxtUhDgHcKZVxt97j9En9oaNfvA", - "version": "2.1.0", - "gitBranch": "improvement/paranet-incentives-calculation", - "gitCommitHash": "f52e4b5ec305ec0bc4f7652f406f081c07d6010c", - "deploymentBlock": 4095339, - "deploymentTimestamp": 1718280147149, - "deployed": true - }, - "ParanetKnowledgeAssetsRegistry": { - "evmAddress": "0x70cBC936E327c9527087e506cFe39e009B5d1eA9", - "substrateAddress": "5EMjsczin1CwmqQUpzAXE32KLE4FmPCpJMF5jpQ4SG3ZXBnm", - "version": "2.0.0", - "gitBranch": "improvement/paranet-incentives-calculation", - "gitCommitHash": "f52e4b5ec305ec0bc4f7652f406f081c07d6010c", - "deploymentBlock": 4095341, - "deploymentTimestamp": 1718280196318, - "deployed": true - }, - "ParanetKnowledgeMinersRegistry": { - "evmAddress": "0xA1058709c3c9F38C042702BF352B6f072A25435C", - "substrateAddress": "5EMjscztSTsg9LrkSz5nigv7Eh5C3MkR9D9seeG9GGH6udUD", - "version": "2.0.1", - "gitBranch": "improvement/paranet-incentives-calculation", - "gitCommitHash": "f52e4b5ec305ec0bc4f7652f406f081c07d6010c", - "deploymentBlock": 4095342, - "deploymentTimestamp": 1718280217666, - "deployed": true - }, - "Paranet": { - "evmAddress": "0x4751B9C2Beaea2555c7331F46c12D11E27Bfb1f2", - "substrateAddress": "5EMjsczaTyZzYUkgqsZn2CjR1XJQyNA1EZDFni7dZGQYrAfi", - "version": "2.1.3", - "gitBranch": "improvement/paranet-incentives-additional-getters", - "gitCommitHash": "bbf78d963b46a63c4c55fd6a82fc0bbdb59c40bc", - "deploymentBlock": 4108246, - "deploymentTimestamp": 1718630775260, - "deployed": true - }, - "ParanetIncentivesPoolFactory": { - "evmAddress": "0x043F6aBBfd8882acb4f71C49E7f4Bd71271d5FD0", - "substrateAddress": "5EMjsczM2VgpRxsY2B7g23uW33fR21633UMZZUxA6owKPXt6", - "version": "2.0.0", - "gitBranch": "improvement/paranet-incentives-additional-getters", - "gitCommitHash": "bbf78d963b46a63c4c55fd6a82fc0bbdb59c40bc", - "deploymentBlock": 4108247, - "deploymentTimestamp": 1718630808590, - "deployed": true - } - }, - "deployedTimestamp": 1689931970523 -} diff --git a/package-lock.json b/package-lock.json index 79f0f33c..9bf2ec13 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dkg-evm-module", - "version": "8.0.0-alpha.0", + "version": "8.0.1-alpha.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "dkg-evm-module", - "version": "8.0.0-alpha.0", + "version": "8.0.1-alpha.0", "license": "Apache-2.0", "dependencies": { "@openzeppelin/contracts": "^4.9.3", diff --git a/package.json b/package.json index b52428b2..dd246827 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dkg-evm-module", - "version": "8.0.0-alpha.0", + "version": "8.0.1-alpha.0", "description": "Smart contracts for OriginTrail V6", "main": "index.ts", "files": [ diff --git a/test/v1/unit/AssertionStorage.test.ts b/test/v1/unit/AssertionStorage.test.ts deleted file mode 100644 index 7fed7ed1..00000000 --- a/test/v1/unit/AssertionStorage.test.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; -import { expect } from 'chai'; -import hre from 'hardhat'; -import { SignerWithAddress } from 'hardhat-deploy-ethers/signers'; - -import { AssertionStorage, HubController } from '../../../typechain'; - -type AssertionStorageFixture = { - accounts: SignerWithAddress[]; - AssertionStorage: AssertionStorage; -}; - -describe('@v1 @unit AssertionStorage contract', function () { - const assertionId = '0x74657374696e6720617373657274696f6e2069640209100f5047b080c0440ae1'; - const nonExistingAssertionId = '0x23457374696e6720617373657274696f6e2069640209100f5047b080c0440ae1'; - const size = 20; - const triplesNumber = 10; - const chunksNumber = 3; - let accounts: SignerWithAddress[]; - let AssertionStorage: AssertionStorage; - - async function deployAssertionStorageFixture(): Promise { - await hre.deployments.fixture(['AssertionStorage']); - AssertionStorage = await hre.ethers.getContract('AssertionStorage'); - const HubController = await hre.ethers.getContract('HubController'); - accounts = await hre.ethers.getSigners(); - await HubController.setContractAddress('HubOwner', accounts[0].address); - - return { accounts, AssertionStorage }; - } - - beforeEach(async () => { - hre.helpers.resetDeploymentsJson(); - ({ accounts, AssertionStorage } = await loadFixture(deployAssertionStorageFixture)); - }); - - it('The contract is named "AssertionStorage"', async () => { - expect(await AssertionStorage.name()).to.equal('AssertionStorage'); - }); - - it('The contract is version "1.0.0"', async () => { - expect(await AssertionStorage.version()).to.equal('1.0.0'); - }); - - it('Create an assertion with non owner, expect to fail', async () => { - const AssertionStorageWithNonOwnerAsSigner = AssertionStorage.connect(accounts[1]); - - await expect( - AssertionStorageWithNonOwnerAsSigner.createAssertion(assertionId, size, triplesNumber, chunksNumber), - ).to.be.revertedWith('Fn can only be called by the hub'); - }); - - it('Create an assertion with owner, expect to pass', async () => { - await AssertionStorage.createAssertion(assertionId, size, triplesNumber, chunksNumber); - - const getAssertionResponse = await AssertionStorage.getAssertion(assertionId); - expect(getAssertionResponse.size).to.equal(size); - expect(getAssertionResponse.triplesNumber).to.equal(triplesNumber); - expect(getAssertionResponse.chunksNumber).to.equal(chunksNumber); - }); - - it('Create an assertion from non-owner wallet, expect to revert', async () => { - const AssertionStorageWithNonOwnerAsSigner = AssertionStorage.connect(accounts[1]); - - await expect( - AssertionStorageWithNonOwnerAsSigner.createAssertion(assertionId, size, triplesNumber, chunksNumber), - ).to.be.revertedWith('Fn can only be called by the hub'); - }); - - it('Get assertion for non-existing assertionId, expect to get 0', async () => { - const getAssertionResponse = await AssertionStorage.getAssertion(nonExistingAssertionId); - - getAssertionResponse.forEach((e) => { - expect(e).to.equal(0); - }); - }); - - it('Get assertion timestamp, size, triples/chunks number for non-existing assertionId, expect to get 0', async () => { - const getTimestampResult = await AssertionStorage.getAssertionTimestamp(nonExistingAssertionId); - const getSizeResult = await AssertionStorage.getAssertionSize(nonExistingAssertionId); - const getTriplesNumber = await AssertionStorage.getAssertionTriplesNumber(nonExistingAssertionId); - const getChunksNumber = await AssertionStorage.getAssertionChunksNumber(nonExistingAssertionId); - - expect(getTimestampResult).to.equal(0); - expect(getSizeResult).to.equal(0); - expect(getTriplesNumber).to.equal(0); - expect(getChunksNumber).to.equal(0); - }); - - it('Get the assertion timestamp for valid assertion id, expect to pass', async () => { - await AssertionStorage.createAssertion(assertionId, size, triplesNumber, chunksNumber); - const getTimestampResult = await AssertionStorage.getAssertionTimestamp(assertionId); - - expect(getTimestampResult).to.not.equal(0); - }); - - it('Get the assertion size for valid assertion id, expect to pass', async () => { - await AssertionStorage.createAssertion(assertionId, size, triplesNumber, chunksNumber); - const getSizeResult = await AssertionStorage.getAssertionSize(assertionId); - - expect(getSizeResult).to.equal(size); - expect(getSizeResult).to.not.equal(0); - }); - - it('Get the assertion triple number for valid assertion id, expect to pass', async () => { - await AssertionStorage.createAssertion(assertionId, size, triplesNumber, chunksNumber); - const getTriplesNumber = await AssertionStorage.getAssertionTriplesNumber(assertionId); - - expect(getTriplesNumber).to.equal(triplesNumber); - expect(getTriplesNumber).to.not.equal(0); - }); - - it('Get the assertion chunks number for valid assertion id, expect to pass', async () => { - await AssertionStorage.createAssertion(assertionId, size, triplesNumber, chunksNumber); - const getChunksNumber = await AssertionStorage.getAssertionChunksNumber(assertionId); - - expect(getChunksNumber).to.equal(chunksNumber); - expect(getChunksNumber).to.not.equal(0); - }); - - it('Validate that assertion exists with valid assertion id, expect to pass', async () => { - await AssertionStorage.createAssertion(assertionId, size, triplesNumber, chunksNumber); - const isAssertionExist = await AssertionStorage.assertionExists(assertionId); - - expect(isAssertionExist).to.equal(true); - }); - - it('Validate that assertion can be deleted, expect to pass', async () => { - await AssertionStorage.createAssertion(assertionId, size, triplesNumber, chunksNumber); - const isAssertionExist = await AssertionStorage.assertionExists(assertionId); - - expect(isAssertionExist).to.equal(true); - - await AssertionStorage.deleteAssertion(assertionId); - const checkAssertion = await AssertionStorage.assertionExists(assertionId); - - expect(checkAssertion).to.equal(false); - }); -}); diff --git a/test/v1/unit/CommitManagerV1.test.ts b/test/v1/unit/CommitManagerV1.test.ts deleted file mode 100644 index 26dec816..00000000 --- a/test/v1/unit/CommitManagerV1.test.ts +++ /dev/null @@ -1,194 +0,0 @@ -import { randomBytes } from 'crypto'; - -import { loadFixture, time } from '@nomicfoundation/hardhat-network-helpers'; -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import { expect } from 'chai'; -import { BytesLike } from 'ethers'; -import hre from 'hardhat'; -import { SignerWithAddress } from 'hardhat-deploy-ethers/signers'; - -import { - CommitManagerV1, - ContentAsset, - ContentAssetStorage, - ParametersStorage, - Profile, - ServiceAgreementV1, - Staking, - Token, -} from '../../../typechain'; -import { ContentAssetStructs } from '../../../typechain/contracts/v1/assets/ContentAsset'; -import { ServiceAgreementStructsV1 } from '../../../typechain/contracts/v1/CommitManagerV1'; - -type CommitManagerV1Fixture = { - accounts: SignerWithAddress[]; - CommitManagerV1: CommitManagerV1; -}; - -describe('@v1 @unit CommitManagerV1 contract', function () { - let accounts: SignerWithAddress[]; - let Token: Token; - let ServiceAgreementV1: ServiceAgreementV1; - let ContentAsset: ContentAsset; - let ContentAssetStorage: ContentAssetStorage; - let CommitManagerV1: CommitManagerV1; - let ParametersStorage: ParametersStorage; - let Profile: Profile; - let Staking: Staking; - - const assetInputStruct: ContentAssetStructs.AssetInputArgsStruct = { - assertionId: '0x' + randomBytes(32).toString('hex'), - size: 1000, - triplesNumber: 10, - chunksNumber: 10, - epochsNumber: 5, - tokenAmount: hre.ethers.utils.parseEther('250'), - scoreFunctionId: 1, - immutable_: false, - }; - let commitInputArgs: ServiceAgreementStructsV1.CommitInputArgsStruct; - - async function createAsset(): Promise<{ tokenId: number; keyword: BytesLike; agreementId: BytesLike }> { - await Token.increaseAllowance(ServiceAgreementV1.address, assetInputStruct.tokenAmount); - const receipt = await (await ContentAsset.createAsset(assetInputStruct)).wait(); - - const tokenId = Number(receipt.logs[0].topics[3]); - const keyword = hre.ethers.utils.solidityPack( - ['address', 'bytes32'], - [ContentAssetStorage.address, assetInputStruct.assertionId], - ); - const agreementId = hre.ethers.utils.soliditySha256( - ['address', 'uint256', 'bytes'], - [ContentAssetStorage.address, tokenId, keyword], - ); - - return { tokenId, keyword, agreementId }; - } - - async function createProfile(operational: SignerWithAddress, admin: SignerWithAddress): Promise { - const OperationalProfile = Profile.connect(operational); - - const receipt = await ( - await OperationalProfile.createProfile( - admin.address, - [], - '0x' + randomBytes(32).toString('hex'), - randomBytes(3).toString('hex'), - randomBytes(2).toString('hex'), - 0, - ) - ).wait(); - const identityId = Number(receipt.logs[0].topics[1]); - - await OperationalProfile.setAsk(identityId, hre.ethers.utils.parseEther('0.25')); - - const stakeAmount = hre.ethers.utils.parseEther('50000'); - await Token.connect(admin).increaseAllowance(Staking.address, stakeAmount); - await Staking.connect(admin)['addStake(uint72,uint96)'](identityId, stakeAmount); - - return identityId; - } - - async function deployCommitManagerV1Fixture(): Promise { - await hre.deployments.fixture(['ContentAsset', 'CommitManagerV1', 'Profile']); - Token = await hre.ethers.getContract('Token'); - ServiceAgreementV1 = await hre.ethers.getContract('ServiceAgreementV1'); - ContentAsset = await hre.ethers.getContract('ContentAsset'); - ContentAssetStorage = await hre.ethers.getContract('ContentAssetStorage'); - CommitManagerV1 = await hre.ethers.getContract('CommitManagerV1'); - ParametersStorage = await hre.ethers.getContract('ParametersStorage'); - Profile = await hre.ethers.getContract('Profile'); - Staking = await hre.ethers.getContract('Staking'); - accounts = await hre.ethers.getSigners(); - - return { accounts, CommitManagerV1 }; - } - - beforeEach(async () => { - hre.helpers.resetDeploymentsJson(); - ({ accounts, CommitManagerV1 } = await loadFixture(deployCommitManagerV1Fixture)); - }); - - it('The contract is named "CommitManagerV1"', async () => { - expect(await CommitManagerV1.name()).to.equal('CommitManagerV1'); - }); - - it('The contract is version "1.0.2"', async () => { - expect(await CommitManagerV1.version()).to.equal('1.0.2'); - }); - - it('Create new asset, check if commit window is open, expect to be true', async () => { - const { agreementId } = await createAsset(); - - expect(await CommitManagerV1.isCommitWindowOpen(agreementId, 0)).to.eql(true); - }); - - it('Create new asset, teleport to the end of commit phase and check if commit window is open, expect to be false', async () => { - const { agreementId } = await createAsset(); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const commitWindowDurationPerc = await ParametersStorage.commitWindowDurationPerc(); - const commitWindowDuration = (epochLength * commitWindowDurationPerc) / 100; - - await time.increase(commitWindowDuration + 1); - - expect(await CommitManagerV1.isCommitWindowOpen(agreementId, 0)).to.eql(false); - }); - - it('Create new asset, teleport to second epoch and check if commit window is open, expect to be true', async () => { - const { agreementId } = await createAsset(); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - await time.increase(epochLength); - - expect(await CommitManagerV1.isCommitWindowOpen(agreementId, 1)).to.eql(true); - }); - - it('Create new asset, submit commit, expect CommitSubmitted event', async () => { - await createProfile(accounts[0], accounts[1]); - - const { tokenId, keyword } = await createAsset(); - - commitInputArgs = { - assetContract: ContentAssetStorage.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - }; - - await expect(CommitManagerV1.submitCommit(commitInputArgs)).to.emit(CommitManagerV1, 'CommitSubmitted'); - }); - - it('Create new asset, submit R0 commits, expect R0 commits to be returned', async () => { - const r0 = await ParametersStorage.r0(); - - const identityIds = []; - for (let i = 0; i < r0; i++) { - identityIds.push(await createProfile(accounts[i], accounts[accounts.length - 1])); - } - - const { tokenId, keyword, agreementId } = await createAsset(); - - commitInputArgs = { - assetContract: ContentAssetStorage.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - }; - - for (let i = 0; i < r0; i++) { - await expect(CommitManagerV1.connect(accounts[i]).submitCommit(commitInputArgs)).to.emit( - CommitManagerV1, - 'CommitSubmitted', - ); - } - - const topCommits = await CommitManagerV1.getTopCommitSubmissions(agreementId, 0); - - expect(topCommits.map((arr) => arr[0])).to.have.deep.members( - identityIds.map((identityId) => hre.ethers.BigNumber.from(identityId)), - ); - }); -}); diff --git a/test/v1/unit/CommitManagerV1U1.test.ts b/test/v1/unit/CommitManagerV1U1.test.ts deleted file mode 100644 index e5eed5bb..00000000 --- a/test/v1/unit/CommitManagerV1U1.test.ts +++ /dev/null @@ -1,343 +0,0 @@ -import { randomBytes } from 'crypto'; - -import { loadFixture, time } from '@nomicfoundation/hardhat-network-helpers'; -import { expect } from 'chai'; -import { BytesLike } from 'ethers'; -import hre from 'hardhat'; -import { SignerWithAddress } from 'hardhat-deploy-ethers/signers'; - -import { - CommitManagerV1, - CommitManagerV1U1, - ContentAsset, - ContentAssetStorage, - ParametersStorage, - Profile, - ServiceAgreementV1, - Staking, - Token, -} from '../../../typechain'; -import { ContentAssetStructs } from '../../../typechain/contracts/v1/assets/ContentAsset'; -import { ServiceAgreementStructsV1 } from '../../../typechain/contracts/v1/CommitManagerV1U1'; - -type CommitManagerV1U1Fixture = { - accounts: SignerWithAddress[]; - CommitManagerV1: CommitManagerV1; - CommitManagerV1U1: CommitManagerV1U1; - ParametersStorage: ParametersStorage; -}; - -describe('@v1 @unit CommitManagerV1U1 contract', function () { - let accounts: SignerWithAddress[]; - let Token: Token; - let ServiceAgreementV1: ServiceAgreementV1; - let ContentAsset: ContentAsset; - let ContentAssetStorage: ContentAssetStorage; - let CommitManagerV1: CommitManagerV1; - let CommitManagerV1U1: CommitManagerV1U1; - let ParametersStorage: ParametersStorage; - let Profile: Profile; - let Staking: Staking; - - const assetInputStruct: ContentAssetStructs.AssetInputArgsStruct = { - assertionId: '0x' + randomBytes(32).toString('hex'), - size: 1000, - triplesNumber: 10, - chunksNumber: 10, - epochsNumber: 5, - tokenAmount: hre.ethers.utils.parseEther('250'), - scoreFunctionId: 1, - immutable_: false, - }; - const assetUpdateArgs = { - assertionId: '0x' + randomBytes(32).toString('hex'), - size: 2000, - triplesNumber: 20, - chunksNumber: 20, - tokenAmount: hre.ethers.utils.parseEther('500'), - }; - let commitInputArgs: ServiceAgreementStructsV1.CommitInputArgsStruct; - - async function createAsset(): Promise<{ tokenId: number; keyword: BytesLike; agreementId: BytesLike }> { - await Token.increaseAllowance(ServiceAgreementV1.address, assetInputStruct.tokenAmount); - const receipt = await (await ContentAsset.createAsset(assetInputStruct)).wait(); - - const tokenId = Number(receipt.logs[0].topics[3]); - const keyword = hre.ethers.utils.solidityPack( - ['address', 'bytes32'], - [ContentAssetStorage.address, assetInputStruct.assertionId], - ); - const agreementId = hre.ethers.utils.soliditySha256( - ['address', 'uint256', 'bytes'], - [ContentAssetStorage.address, tokenId, keyword], - ); - - return { tokenId, keyword, agreementId }; - } - - async function updateAsset(tokenId: number) { - await Token.increaseAllowance(ServiceAgreementV1.address, assetUpdateArgs.tokenAmount); - await ContentAsset.updateAssetState( - tokenId, - assetUpdateArgs.assertionId, - assetUpdateArgs.size, - assetUpdateArgs.triplesNumber, - assetUpdateArgs.chunksNumber, - assetUpdateArgs.tokenAmount, - ); - } - - async function finalizeUpdate(tokenId: number, keyword: BytesLike): Promise { - const finalizationRequirement = await ParametersStorage.finalizationCommitsNumber(); - - const identityIds = []; - for (let i = 0; i < finalizationRequirement; i++) { - identityIds.push(await createProfile(accounts[i], accounts[accounts.length - 1])); - } - - commitInputArgs = { - assetContract: ContentAssetStorage.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - }; - - for (let i = 0; i < finalizationRequirement; i++) { - await expect(CommitManagerV1U1.connect(accounts[i]).submitUpdateCommit(commitInputArgs)).to.emit( - CommitManagerV1U1, - 'CommitSubmitted', - ); - } - - return identityIds; - } - - async function createProfile(operational: SignerWithAddress, admin: SignerWithAddress): Promise { - const OperationalProfile = Profile.connect(operational); - - const receipt = await ( - await OperationalProfile.createProfile( - admin.address, - [], - '0x' + randomBytes(32).toString('hex'), - randomBytes(3).toString('hex'), - randomBytes(2).toString('hex'), - 0, - ) - ).wait(); - const identityId = Number(receipt.logs[0].topics[1]); - - await OperationalProfile.setAsk(identityId, hre.ethers.utils.parseEther('0.25')); - - const stakeAmount = hre.ethers.utils.parseEther('50000'); - await Token.connect(admin).increaseAllowance(Staking.address, stakeAmount); - await Staking.connect(admin)['addStake(uint72,uint96)'](identityId, stakeAmount); - - return identityId; - } - - async function deployCommitManagerV1U1Fixture(): Promise { - await hre.deployments.fixture(['ContentAsset', 'CommitManagerV1', 'CommitManagerV1U1', 'Profile']); - Token = await hre.ethers.getContract('Token'); - ServiceAgreementV1 = await hre.ethers.getContract('ServiceAgreementV1'); - ContentAsset = await hre.ethers.getContract('ContentAsset'); - ContentAssetStorage = await hre.ethers.getContract('ContentAssetStorage'); - CommitManagerV1 = await hre.ethers.getContract('CommitManagerV1'); - CommitManagerV1U1 = await hre.ethers.getContract('CommitManagerV1U1'); - ParametersStorage = await hre.ethers.getContract('ParametersStorage'); - Profile = await hre.ethers.getContract('Profile'); - Staking = await hre.ethers.getContract('Staking'); - accounts = await hre.ethers.getSigners(); - - return { accounts, CommitManagerV1, CommitManagerV1U1, ParametersStorage }; - } - - beforeEach(async () => { - hre.helpers.resetDeploymentsJson(); - ({ accounts, CommitManagerV1U1 } = await loadFixture(deployCommitManagerV1U1Fixture)); - }); - - it('The contract is named "CommitManagerV1U1"', async () => { - expect(await CommitManagerV1U1.name()).to.equal('CommitManagerV1U1'); - }); - - it('The contract is version "1.0.2"', async () => { - expect(await CommitManagerV1U1.version()).to.equal('1.0.2'); - }); - - it('Create new asset, update and finalize update, check if commit window is open, expect to be true', async () => { - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - await finalizeUpdate(tokenId, keyword); - - await expect(CommitManagerV1.isCommitWindowOpen(agreementId, 0)).to.be.revertedWithCustomError( - CommitManagerV1, - 'ServiceAgreementDoesntExist', - ); - expect(await CommitManagerV1U1.isCommitWindowOpen(agreementId, 0)).to.eql(true); - }); - - it('Create new asset, update and finalize update, teleport to the end of commit phase and check if commit window is open, expect to be false', async () => { - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - await finalizeUpdate(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const commitWindowDurationPerc = await ParametersStorage.commitWindowDurationPerc(); - const commitWindowDuration = (epochLength * commitWindowDurationPerc) / 100; - - await time.increase(commitWindowDuration + 1); - - await expect(CommitManagerV1.isCommitWindowOpen(agreementId, 0)).to.be.revertedWithCustomError( - CommitManagerV1, - 'ServiceAgreementDoesntExist', - ); - expect(await CommitManagerV1U1.isCommitWindowOpen(agreementId, 0)).to.eql(false); - }); - - it('Create new asset, update and finalize update, teleport to second epoch and check if commit window is open, expect to be true', async () => { - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - await finalizeUpdate(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - await time.increase(epochLength); - - await expect(CommitManagerV1.isCommitWindowOpen(agreementId, 1)).to.be.revertedWithCustomError( - CommitManagerV1, - 'ServiceAgreementDoesntExist', - ); - expect(await CommitManagerV1U1.isCommitWindowOpen(agreementId, 1)).to.eql(true); - }); - - it('Create new asset, update it, check if update commit window is open, expect to be true', async () => { - const { tokenId, agreementId } = await createAsset(); - await updateAsset(tokenId); - - expect(await CommitManagerV1U1.isUpdateCommitWindowOpen(agreementId, 0, 1)).to.eql(true); - }); - - it('Create new asset, update it, teleport to the end of update commit window and check if its open, expect to be false', async () => { - const { tokenId, agreementId } = await createAsset(); - await updateAsset(tokenId); - - const updateCommitWindowDuration = await ParametersStorage.updateCommitWindowDuration(); - await time.increase(updateCommitWindowDuration); - - expect(await CommitManagerV1U1.isUpdateCommitWindowOpen(agreementId, 0, 1)).to.eql(false); - }); - - it('Create new asset, update finalize update, teleport to the second epoch, submit commit, expect CommitSubmitted event', async () => { - const { tokenId, keyword } = await createAsset(); - await updateAsset(tokenId); - await finalizeUpdate(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - await time.increase(epochLength); - - commitInputArgs = { - assetContract: ContentAssetStorage.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 1, - }; - - await expect(CommitManagerV1.submitCommit(commitInputArgs)).to.be.revertedWithCustomError( - CommitManagerV1, - 'ServiceAgreementDoesntExist', - ); - await expect(CommitManagerV1U1.submitCommit(commitInputArgs)).to.emit(CommitManagerV1U1, 'CommitSubmitted'); - }); - - it('Create new asset, update it, finalize update, teleport to the second epoch, submit R0 commits, expect R0 commits to be returned', async () => { - const r0 = await ParametersStorage.r0(); - - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - const identityIds = await finalizeUpdate(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - await time.increase(epochLength); - - commitInputArgs = { - assetContract: ContentAssetStorage.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 1, - }; - - for (let i = 0; i < r0; i++) { - await expect(CommitManagerV1.connect(accounts[i]).submitCommit(commitInputArgs)).to.be.revertedWithCustomError( - CommitManagerV1, - 'ServiceAgreementDoesntExist', - ); - await expect(CommitManagerV1U1.connect(accounts[i]).submitCommit(commitInputArgs)).to.emit( - CommitManagerV1U1, - 'CommitSubmitted', - ); - } - - await expect(CommitManagerV1.getTopCommitSubmissions(agreementId, 1)).to.be.revertedWithCustomError( - CommitManagerV1, - 'ServiceAgreementDoesntExist', - ); - const topCommits = await CommitManagerV1U1.getTopCommitSubmissions(agreementId, 1, 1); - - expect(topCommits.map((arr) => arr[0])).to.have.deep.members( - identityIds.map((identityId) => hre.ethers.BigNumber.from(identityId)), - ); - }); - - it('Create new asset, update asset, submit update commit, expect CommitSubmitted event', async () => { - await createProfile(accounts[0], accounts[1]); - - const { tokenId, keyword } = await createAsset(); - await updateAsset(tokenId); - - commitInputArgs = { - assetContract: ContentAssetStorage.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - }; - - await expect(CommitManagerV1U1.submitUpdateCommit(commitInputArgs)).to.emit(CommitManagerV1U1, 'CommitSubmitted'); - }); - - it('Create new asset, update it and submit update commits, expect StateFinalized event', async () => { - const finalizationRequirement = await ParametersStorage.finalizationCommitsNumber(); - - const identityIds = []; - for (let i = 0; i < finalizationRequirement; i++) { - identityIds.push(await createProfile(accounts[i], accounts[accounts.length - 1])); - } - - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - - commitInputArgs = { - assetContract: ContentAssetStorage.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - }; - for (let i = 0; i < finalizationRequirement - 1; i++) { - await expect(CommitManagerV1U1.connect(accounts[i]).submitUpdateCommit(commitInputArgs)).to.emit( - CommitManagerV1U1, - 'CommitSubmitted', - ); - } - await expect( - CommitManagerV1U1.connect(accounts[identityIds.length - 1]).submitUpdateCommit(commitInputArgs), - ).to.emit(CommitManagerV1U1, 'StateFinalized'); - const topCommits = await CommitManagerV1U1.getTopCommitSubmissions(agreementId, 0, 1); - expect(topCommits.map((arr) => arr[0])).to.include.deep.members( - identityIds.map((identityId) => hre.ethers.BigNumber.from(identityId)), - ); - }); -}); diff --git a/test/v1/unit/ProofManagerV1.test.ts b/test/v1/unit/ProofManagerV1.test.ts deleted file mode 100644 index f6f9bcbe..00000000 --- a/test/v1/unit/ProofManagerV1.test.ts +++ /dev/null @@ -1,591 +0,0 @@ -import { randomBytes } from 'crypto'; - -import { loadFixture, time } from '@nomicfoundation/hardhat-network-helpers'; -import { calculateRoot, getMerkleProof } from 'assertion-tools'; -import { expect } from 'chai'; -import { BytesLike, BigNumber } from 'ethers'; -import hre from 'hardhat'; -import { SignerWithAddress } from 'hardhat-deploy-ethers/signers'; - -import { - CommitManagerV1, - ContentAsset, - ContentAssetStorage, - ParametersStorage, - Profile, - ProofManagerV1, - ServiceAgreementStorageProxy, - ServiceAgreementV1, - Staking, - StakingStorage, - Token, -} from '../../../typechain'; -import { ContentAssetStructs } from '../../../typechain/contracts/v1/assets/ContentAsset'; -import { ServiceAgreementStructsV1 as CommitStructs } from '../../../typechain/contracts/v1/CommitManagerV1'; -import { ServiceAgreementStructsV1 as ProofStructs } from '../../../typechain/contracts/v1/ProofManagerV1'; - -type ProofManagerV1Fixture = { - accounts: SignerWithAddress[]; - ServiceAgreementStorageProxy: ServiceAgreementStorageProxy; - CommitManagerV1: CommitManagerV1; - ProofManagerV1: ProofManagerV1; - ParametersStorage: ParametersStorage; -}; - -describe('@v1 @unit ProofManagerV1 contract', function () { - let accounts: SignerWithAddress[]; - let Token: Token; - let ServiceAgreementV1: ServiceAgreementV1; - let ServiceAgreementStorageProxy: ServiceAgreementStorageProxy; - let ContentAsset: ContentAsset; - let ContentAssetStorage: ContentAssetStorage; - let CommitManagerV1: CommitManagerV1; - let ProofManagerV1: ProofManagerV1; - let ParametersStorage: ParametersStorage; - let Profile: Profile; - let Staking: Staking; - let StakingStorage: StakingStorage; - - const nQuads = [ - ' "1940-10-09"^^ .', - ' .', - ' "John Lennon" .', - ]; - const assetInputStruct: ContentAssetStructs.AssetInputArgsStruct = { - assertionId: calculateRoot(nQuads), - size: 1000, - triplesNumber: nQuads.length, - chunksNumber: nQuads.length, - epochsNumber: 5, - tokenAmount: hre.ethers.utils.parseEther('250'), - scoreFunctionId: 1, - immutable_: false, - }; - let proofInputArgs: ProofStructs.ProofInputArgsStruct; - - async function createAsset(): Promise<{ tokenId: number; keyword: BytesLike; agreementId: BytesLike }> { - await Token.increaseAllowance(ServiceAgreementV1.address, assetInputStruct.tokenAmount); - const receipt = await (await ContentAsset.createAsset(assetInputStruct)).wait(); - - const tokenId = Number(receipt.logs[0].topics[3]); - const keyword = hre.ethers.utils.solidityPack( - ['address', 'bytes32'], - [ContentAssetStorage.address, assetInputStruct.assertionId], - ); - const agreementId = hre.ethers.utils.soliditySha256( - ['address', 'uint256', 'bytes'], - [ContentAssetStorage.address, tokenId, keyword], - ); - - return { tokenId, keyword, agreementId }; - } - - async function submitCommit(operational: SignerWithAddress, tokenId: number, keyword: BytesLike, epoch = 0) { - const commitInputArgs: CommitStructs.CommitInputArgsStruct = { - assetContract: ContentAssetStorage.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch, - }; - - await CommitManagerV1.connect(operational).submitCommit(commitInputArgs); - } - - async function createProfile(operational: SignerWithAddress, admin: SignerWithAddress): Promise { - const OperationalProfile = Profile.connect(operational); - - const receipt = await ( - await OperationalProfile.createProfile( - admin.address, - [], - '0x' + randomBytes(32).toString('hex'), - randomBytes(3).toString('hex'), - randomBytes(2).toString('hex'), - 0, - ) - ).wait(); - const identityId = Number(receipt.logs[0].topics[1]); - - await OperationalProfile.setAsk(identityId, hre.ethers.utils.parseEther('0.25')); - - const stakeAmount = hre.ethers.utils.parseEther('50000'); - await Token.connect(admin).increaseAllowance(Staking.address, stakeAmount); - await Staking.connect(admin)['addStake(uint72,uint96)'](identityId, stakeAmount); - - return identityId; - } - - async function deployProofManagerV1Fixture(): Promise { - await hre.deployments.fixture(['ContentAsset', 'CommitManagerV1', 'ProofManagerV1', 'Profile']); - Token = await hre.ethers.getContract('Token'); - ServiceAgreementV1 = await hre.ethers.getContract('ServiceAgreementV1'); - ServiceAgreementStorageProxy = await hre.ethers.getContract( - 'ServiceAgreementStorageProxy', - ); - ContentAsset = await hre.ethers.getContract('ContentAsset'); - ContentAssetStorage = await hre.ethers.getContract('ContentAssetStorage'); - CommitManagerV1 = await hre.ethers.getContract('CommitManagerV1'); - ProofManagerV1 = await hre.ethers.getContract('ProofManagerV1'); - ParametersStorage = await hre.ethers.getContract('ParametersStorage'); - Profile = await hre.ethers.getContract('Profile'); - Staking = await hre.ethers.getContract('Staking'); - StakingStorage = await hre.ethers.getContract('StakingStorage'); - accounts = await hre.ethers.getSigners(); - - return { accounts, ServiceAgreementStorageProxy, CommitManagerV1, ProofManagerV1, ParametersStorage }; - } - - async function submitProofAndReturnReward( - identityId: number, - account: SignerWithAddress, - tokenId: number, - keyword: BytesLike, - epoch: number, - ) { - const challenge = await ProofManagerV1.getChallenge(account.address, ContentAssetStorage.address, tokenId, epoch); - const { proof, leaf } = getMerkleProof(nQuads, challenge[1].toNumber()); - - const proofInputArgs = { - assetContract: ContentAssetStorage.address, - tokenId, - keyword, - hashFunctionId: 1, - epoch, - proof, - chunkHash: leaf, - }; - - await ProofManagerV1.connect(account).sendProof(proofInputArgs); - const filter = Staking.filters.StakeIncreased(identityId); - const event = (await Staking.queryFilter(filter)).pop(); - if (!event) throw new Error(`Event is undefined for account ${account}`); - return event.args.newStake.sub(event.args.oldStake); - } - - beforeEach(async () => { - hre.helpers.resetDeploymentsJson(); - ({ accounts, ServiceAgreementStorageProxy, CommitManagerV1, CommitManagerV1, ParametersStorage } = - await loadFixture(deployProofManagerV1Fixture)); - }); - - it('The contract is named "ProofManagerV1"', async () => { - expect(await ProofManagerV1.name()).to.equal('ProofManagerV1'); - }); - - it('The contract is version "1.0.3"', async () => { - expect(await ProofManagerV1.version()).to.equal('1.0.3'); - }); - - it('Create a new asset, teleport to the proof phase and check if window is open, expect true', async () => { - const { agreementId } = await createAsset(); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - - await time.increase(delay); - - expect(await ProofManagerV1.isProofWindowOpen(agreementId, 0)).to.eql(true); - }); - - it('Create a new asset, teleport to the moment before proof phase and check if window is open, expect false', async () => { - const { agreementId } = await createAsset(); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - - await time.increase(delay - 1); - - expect(await ProofManagerV1.isProofWindowOpen(agreementId, 0)).to.eql(false); - }); - - it('Create a new asset, teleport to the moment after proof phase and check if window is open, expect false', async () => { - const { agreementId } = await createAsset(); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const proofWindowDurationPerc = await ParametersStorage.proofWindowDurationPerc(); - const delay = (epochLength * (proofWindowOffsetPerc + proofWindowDurationPerc)) / 100; - - await time.increase(delay); - - expect(await ProofManagerV1.isProofWindowOpen(agreementId, 0)).to.eql(false); - }); - - it('Create a new asset, send commit, teleport and send proof, expect ProofSent event and reward received', async () => { - const identityId = await createProfile(accounts[0], accounts[1]); - const { tokenId, keyword, agreementId } = await createAsset(); - await submitCommit(accounts[0], tokenId, keyword); - - const commitId = hre.ethers.utils.solidityKeccak256( - ['bytes32', 'uint16', 'uint256', 'uint96'], - [agreementId, 0, 0, identityId], - ); - - const challenge = await ProofManagerV1.getChallenge(accounts[0].address, ContentAssetStorage.address, tokenId, 0); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - - await time.increase(delay); - - const { proof, leaf } = getMerkleProof(nQuads, challenge[1].toNumber()); - proofInputArgs = { - assetContract: ContentAssetStorage.address, - tokenId, - keyword, - hashFunctionId: 1, - epoch: 0, - proof, - chunkHash: leaf, - }; - - const initialStake = await StakingStorage.totalStakes(identityId); - const initialAssetReward = await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId); - - await expect(ProofManagerV1.sendProof(proofInputArgs)).to.emit(ProofManagerV1, 'ProofSubmitted'); - - const endAssetReward = await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId); - expect(await StakingStorage.totalStakes(identityId)).to.equal( - initialStake.add(initialAssetReward).sub(endAssetReward), - ); - - expect(await ServiceAgreementStorageProxy.getCommitSubmissionScore(commitId)).to.equal(0); - }); - - it('Create a new asset and get challenge, expect challenge to be valid', async () => { - const { tokenId } = await createAsset(); - - const challenge = await ProofManagerV1.getChallenge(accounts[0].address, ContentAssetStorage.address, tokenId, 0); - - expect(challenge[0]).to.equal(assetInputStruct.assertionId); - expect(challenge[1]).to.be.within(0, nQuads.length - 1); - }); - - it('Create a new asset, send commit, teleport and send 2 proofs, expect second proof to be reverted', async () => { - await createProfile(accounts[0], accounts[1]); - const { tokenId, keyword, agreementId } = await createAsset(); - await submitCommit(accounts[0], tokenId, keyword); - - const challenge = await ProofManagerV1.getChallenge(accounts[0].address, ContentAssetStorage.address, tokenId, 0); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - - await time.increase(delay); - - const { proof, leaf } = getMerkleProof(nQuads, challenge[1].toNumber()); - proofInputArgs = { - assetContract: ContentAssetStorage.address, - tokenId, - keyword, - hashFunctionId: 1, - epoch: 0, - proof, - chunkHash: leaf, - }; - - await expect(ProofManagerV1.sendProof(proofInputArgs)).to.emit(ProofManagerV1, 'ProofSubmitted'); - await expect(ProofManagerV1.sendProof(proofInputArgs)).to.be.revertedWithCustomError( - ProofManagerV1, - 'NodeAlreadyRewarded', - ); - }); - - it('Create a new asset, 3 nodes send commit, teleport to proof phase, send 3 proofs and check that reward is equal for all 3 nodes', async () => { - const operationalWallets = [accounts[0], accounts[2], accounts[3]]; - const identities = []; - const rewards = []; - - const { tokenId, keyword, agreementId } = await createAsset(); - - // All nodes submit their commits - for (const operationalWallet of operationalWallets) { - const identity = await createProfile(operationalWallet, accounts[1]); - identities.push(identity); - await submitCommit(operationalWallet, tokenId, keyword); - } - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - await time.increase(delay); - - // All nodes submit their proofs and store the rewards received - for (const i in operationalWallets) { - const reward = await submitProofAndReturnReward(identities[i], operationalWallets[i], tokenId, keyword, 0); - rewards.push(reward); - } - - // Check that all nodes received the same reward (or the discrepancy is less than or equal to 1 wei) - for (let i = 0; i < rewards.length - 1; i++) { - expect( - rewards[i] - .sub(rewards[i + 1]) - .abs() - .lte(1), - ).to.be.true; - } - }); - - it('Create a new asset, 2 nodes send commit, teleport to proof phase, send 2 proofs and check that reward for the next epoch has increased', async () => { - const operationalWallets = [accounts[0], accounts[2], accounts[3]]; - const identities = []; - const rewards: BigNumber[][] = [[], [], []]; - - const { tokenId, keyword, agreementId } = await createAsset(); - - for (let i = 0; i < operationalWallets.length; i++) { - const identity = await createProfile(operationalWallets[i], accounts[1]); - identities.push(identity); - } - - let epoch = 0; - for (let i = 0; i < 2; i++) { - // Only the first two nodes submit their commits - await submitCommit(operationalWallets[i], tokenId, keyword, epoch); - } - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - - await time.increase(delay); - - for (let i = 0; i < 2; i++) { - // First two nodes submit their proofs - const reward = await submitProofAndReturnReward(identities[i], operationalWallets[i], tokenId, keyword, epoch); - rewards[i].push(reward); - } - rewards[2].push(hre.ethers.BigNumber.from(0)); - - await time.increase(epochLength - delay); // Increase time to the second epoch - - epoch = 1; - for (let i = 0; i < operationalWallets.length; i++) { - // All nodes submit their commits for the second epoch - await submitCommit(operationalWallets[i], tokenId, keyword, epoch); - } - - await time.increase(delay); // increase time to proof window - - for (let i = 0; i < operationalWallets.length; i++) { - // All nodes submit their proofs for the second epoch - const reward = await submitProofAndReturnReward(identities[i], operationalWallets[i], tokenId, keyword, epoch); - rewards[i].push(reward); - } - - // Check that the reward for the second epoch is greater than for the first epoch - for (let i = 0; i < 2; i++) { - expect(rewards[i][1].gt(rewards[i][0])).to.be.true; - } - - // Check that all nodes received the same reward for the second epoch - for (let i = 0; i < rewards.length - 1; i++) { - expect( - rewards[i][1] - .sub(rewards[i + 1][1]) - .abs() - .lte(1), - ).to.be.true; - } - }); - - it('Rewards are equal for all nodes in each epoch, including when some nodes miss commits or proofs', async () => { - const operationalWallets = [accounts[0], accounts[2], accounts[3]]; - const identities = []; - const rewards: BigNumber[][] = [[], [], []]; - - const { tokenId, keyword, agreementId } = await createAsset(); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - - for (let i = 0; i < operationalWallets.length; i++) { - const identity = await createProfile(operationalWallets[i], accounts[1]); - identities.push(identity); - } - - for (let epoch = 0; epoch < 5; epoch++) { - const shouldCommit = [epoch !== 1 && epoch !== 3, true, true]; - const shouldProve = [epoch !== 1 && epoch !== 3, epoch !== 3 && epoch !== 4, true]; - - for (let i = 0; i < operationalWallets.length; i++) { - if (shouldCommit[i]) { - await submitCommit(operationalWallets[i], tokenId, keyword, epoch); - } - } - - await time.increase(delay); - - for (let i = 0; i < operationalWallets.length; i++) { - if (shouldProve[i]) { - const reward = await submitProofAndReturnReward( - identities[i], - operationalWallets[i], - tokenId, - keyword, - epoch, - ); - rewards[i].push(reward); - } else { - rewards[i].push(hre.ethers.BigNumber.from(0)); - } - } - - await time.increase(epochLength - delay); - } - // Check that all nodes received the same reward for each epoch they submitted proofs - for (let epoch = 0; epoch < 5; epoch++) { - const epochRewards = rewards.map((r) => r[epoch]); - for (let i = 0; i < epochRewards.length - 1; i++) { - if (epochRewards[i].isZero() || epochRewards[i + 1].isZero()) continue; - expect( - epochRewards[i] - .sub(epochRewards[i + 1]) - .abs() - .lte(1), - ).to.be.true; - } - } - }); - - it('Each node submits commits and proofs for each epoch, verify all rewards in all epochs are the same, and total rewards equals initial token amount in service agreement', async () => { - const operationalWallets = [accounts[0], accounts[2], accounts[3]]; - const identities = []; - let rewards: BigNumber[] = []; - const totalEpochs = 5; - - for (const operationalWallet of operationalWallets) { - const identity = await createProfile(operationalWallet, accounts[1]); - identities.push(identity); - } - - const { tokenId, keyword, agreementId } = await createAsset(); - const initialTokenAmount = await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId); - - let totalReward = BigNumber.from(0); - // Run through each epoch - for (let epoch = 0; epoch < totalEpochs; epoch++) { - // All nodes submit their commits - for (const operationalWallet of operationalWallets) { - await submitCommit(operationalWallet, tokenId, keyword, epoch); - } - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - await time.increase(delay); - - // All nodes submit their proofs and store the rewards received - for (const i in operationalWallets) { - const reward = await submitProofAndReturnReward(identities[i], operationalWallets[i], tokenId, keyword, epoch); - rewards.push(reward); - } - - // Check that all nodes received the same reward (or the discrepancy is less than or equal to 1 wei) - for (let i = 0; i < rewards.length - 1; i++) { - expect( - rewards[i] - .sub(rewards[i + 1]) - .abs() - .lte(1), - ).to.be.true; - } - - await time.increase(epochLength - delay); - // Calculate total reward and reset rewards for next epoch - totalReward = rewards.reduce((total, reward) => total.add(reward), totalReward); - rewards = []; // Reset rewards for next epoch - } - - expect(totalReward.eq(initialTokenAmount)).to.be.true; - - // Check that the token amount stored in the service agreement at the end of the test is 0 - const finalTokenAmount = await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId); - expect(finalTokenAmount.eq(0)).to.be.true; - }); - it('Variable number of nodes send commits and proofs each epoch, verify all rewards in all epochs are the same, and total rewards equals initial token amount in service agreement', async () => { - const operationalWallets = [accounts[0], accounts[1], accounts[2], accounts[3], accounts[4], accounts[5]]; - const identities = []; - let rewards = []; - const totalEpochs = 5; - - for (const operationalWallet of operationalWallets) { - const identity = await createProfile(operationalWallet, accounts[6]); - identities.push(identity); - } - - const { tokenId, keyword, agreementId } = await createAsset(); - const initialTokenAmount = await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId); - - let totalReward = BigNumber.from(0); - - // Define wallet subsets for commit and proof phases for each epoch - const walletSubsetsForCommit = [ - operationalWallets.slice(0, 3), // 3 nodes send commits - operationalWallets.slice(0, 2), // less than 3 nodes send commits - operationalWallets.slice(0, 3), // 3 nodes send commits - operationalWallets.slice(0, 3), // 3 nodes send commits - operationalWallets.slice(0, 3), // 3 nodes send commits - ]; - - const walletSubsetsForProof = [ - operationalWallets.slice(0, 3), // 3 nodes send proofs - operationalWallets.slice(0, 2), // Less than 3 nodes send proofs - operationalWallets.slice(0, 2), // Less than 3 nodes send proofs - operationalWallets.slice(0, 3), // 3 nodes send proofs - operationalWallets.slice(0, 3), // 3 nodes send proofs - ]; - - // Run through each epoch - for (let epoch = 0; epoch < totalEpochs; epoch++) { - const currentWalletSubsetForCommit = walletSubsetsForCommit[epoch]; - const currentWalletSubsetForProof = walletSubsetsForProof[epoch]; - - // Subset of nodes submit their commits - for (const operationalWallet of currentWalletSubsetForCommit) { - await submitCommit(operationalWallet, tokenId, keyword, epoch); - } - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - await time.increase(delay); - - // Subset of nodes submit their proofs and store the rewards received - for (const operationalWallet of currentWalletSubsetForProof) { - const identity = identities[operationalWallets.indexOf(operationalWallet)]; - const reward = await submitProofAndReturnReward(identity, operationalWallet, tokenId, keyword, epoch); - rewards.push(reward); - } - - // Check that all nodes received the same reward (or the discrepancy is less than or equal to 1 wei) - for (let i = 0; i < rewards.length - 1; i++) { - expect( - rewards[i] - .sub(rewards[i + 1]) - .abs() - .lte(1), - ).to.be.true; - } - - await time.increase(epochLength - delay); - - // Calculate total reward and reset rewards for next epoch - totalReward = rewards.reduce((total, reward) => total.add(reward), totalReward); - rewards = []; // Reset rewards for next epoch - } - - expect(totalReward.eq(initialTokenAmount)).to.be.true; - - // Check that the token amount stored in the service agreement at the end of the test is 0 - const finalTokenAmount = await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId); - expect(finalTokenAmount.eq(0)).to.be.true; - }); -}); diff --git a/test/v1/unit/ProofManagerV1U1.test.ts b/test/v1/unit/ProofManagerV1U1.test.ts deleted file mode 100644 index 55f1bb42..00000000 --- a/test/v1/unit/ProofManagerV1U1.test.ts +++ /dev/null @@ -1,753 +0,0 @@ -import { randomBytes } from 'crypto'; - -import { loadFixture, time } from '@nomicfoundation/hardhat-network-helpers'; -import { calculateRoot, getMerkleProof } from 'assertion-tools'; -import { expect } from 'chai'; -import { BigNumber, BytesLike } from 'ethers'; -import hre from 'hardhat'; -import { SignerWithAddress } from 'hardhat-deploy-ethers/signers'; - -import { - CommitManagerV1, - CommitManagerV1U1, - ContentAsset, - ContentAssetStorage, - IdentityStorage, - ParametersStorage, - Profile, - ProofManagerV1, - ProofManagerV1U1, - ServiceAgreementStorageProxy, - ServiceAgreementV1, - Staking, - StakingStorage, - Token, -} from '../../../typechain'; -import { ContentAssetStructs } from '../../../typechain/contracts/v1/assets/ContentAsset'; -import { ServiceAgreementStructsV1 as CommitStructs } from '../../../typechain/contracts/v1/CommitManagerV1U1'; -import { ServiceAgreementStructsV1 as ProofStructs } from '../../../typechain/contracts/v1/ProofManagerV1U1'; - -type ProofManagerV1U1Fixture = { - accounts: SignerWithAddress[]; - ServiceAgreementStorageProxy: ServiceAgreementStorageProxy; - CommitManagerV1: CommitManagerV1; - CommitManagerV1U1: CommitManagerV1U1; - ProofManagerV1: ProofManagerV1; - ProofManagerV1U1: ProofManagerV1U1; - ParametersStorage: ParametersStorage; - IdentityStorage: IdentityStorage; -}; - -describe('@v1 @unit ProofManagerV1U1 contract', function () { - let accounts: SignerWithAddress[]; - let Token: Token; - let ServiceAgreementV1: ServiceAgreementV1; - let ServiceAgreementStorageProxy: ServiceAgreementStorageProxy; - let ContentAsset: ContentAsset; - let ContentAssetStorage: ContentAssetStorage; - let CommitManagerV1: CommitManagerV1; - let CommitManagerV1U1: CommitManagerV1U1; - let ProofManagerV1: ProofManagerV1; - let ProofManagerV1U1: ProofManagerV1U1; - let ParametersStorage: ParametersStorage; - let IdentityStorage: IdentityStorage; - let Profile: Profile; - let Staking: Staking; - let StakingStorage: StakingStorage; - - const nQuadsCreate = [ - ' "1879-03-14"^^ .', - ' .', - ' "Albert Einstein" .', - ]; - const nQuadsUpdate = [ - ' "1940-10-09"^^ .', - ' .', - ' "John Lennon" .', - ]; - const assetInputStruct: ContentAssetStructs.AssetInputArgsStruct = { - assertionId: calculateRoot(nQuadsCreate), - size: 1000, - triplesNumber: nQuadsCreate.length, - chunksNumber: nQuadsCreate.length, - epochsNumber: 5, - tokenAmount: hre.ethers.utils.parseEther('250'), - scoreFunctionId: 1, - immutable_: false, - }; - const assetUpdateArgs = { - assertionId: calculateRoot(nQuadsUpdate), - size: 2000, - triplesNumber: nQuadsUpdate.length, - chunksNumber: nQuadsUpdate.length, - tokenAmount: hre.ethers.utils.parseEther('500'), - }; - let commitInputArgs: CommitStructs.CommitInputArgsStruct; - let proofInputArgs: ProofStructs.ProofInputArgsStruct; - - async function createAsset(): Promise<{ tokenId: number; keyword: BytesLike; agreementId: BytesLike }> { - await Token.increaseAllowance(ServiceAgreementV1.address, assetInputStruct.tokenAmount); - const receipt = await (await ContentAsset.createAsset(assetInputStruct)).wait(); - - const tokenId = Number(receipt.logs[0].topics[3]); - const keyword = hre.ethers.utils.solidityPack( - ['address', 'bytes32'], - [ContentAssetStorage.address, assetInputStruct.assertionId], - ); - const agreementId = hre.ethers.utils.soliditySha256( - ['address', 'uint256', 'bytes'], - [ContentAssetStorage.address, tokenId, keyword], - ); - - return { tokenId, keyword, agreementId }; - } - - async function updateAsset(tokenId: number) { - await Token.increaseAllowance(ServiceAgreementV1.address, assetUpdateArgs.tokenAmount); - await ContentAsset.updateAssetState( - tokenId, - assetUpdateArgs.assertionId, - assetUpdateArgs.size, - assetUpdateArgs.triplesNumber, - assetUpdateArgs.chunksNumber, - assetUpdateArgs.tokenAmount, - ); - } - - async function finalizeUpdate(tokenId: number, keyword: BytesLike): Promise { - const finalizationRequirement = await ParametersStorage.finalizationCommitsNumber(); - - const identityIds = []; - for (let i = 0; i < finalizationRequirement; i++) { - identityIds.push(await createProfile(accounts[i], accounts[accounts.length - 1])); - } - - commitInputArgs = { - assetContract: ContentAssetStorage.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - }; - - for (let i = 0; i < finalizationRequirement; i++) { - await expect(CommitManagerV1U1.connect(accounts[i]).submitUpdateCommit(commitInputArgs)).to.emit( - CommitManagerV1U1, - 'CommitSubmitted', - ); - } - - return identityIds; - } - - async function submitCommitV1U1(operational: SignerWithAddress, tokenId: number, keyword: BytesLike, epoch: number) { - const commitInputArgs: CommitStructs.CommitInputArgsStruct = { - assetContract: ContentAssetStorage.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch, - }; - - await expect(CommitManagerV1.connect(operational).submitCommit(commitInputArgs)).to.be.revertedWithCustomError( - CommitManagerV1, - 'ServiceAgreementDoesntExist', - ); - await CommitManagerV1U1.connect(operational).submitCommit(commitInputArgs); - } - - async function createProfile(operational: SignerWithAddress, admin: SignerWithAddress): Promise { - const OperationalProfile = Profile.connect(operational); - - let identityId = (await IdentityStorage.getIdentityId(operational.address)).toNumber(); - const profileExists = identityId !== 0; - - if (!profileExists) { - const receipt = await ( - await OperationalProfile.createProfile( - admin.address, - [], - '0x' + randomBytes(32).toString('hex'), - randomBytes(3).toString('hex'), - randomBytes(2).toString('hex'), - 0, - ) - ).wait(); - identityId = Number(receipt.logs[0].topics[1]); - } - - await OperationalProfile.setAsk(identityId, hre.ethers.utils.parseEther('0.25')); - - const stakeAmount = hre.ethers.utils.parseEther('50000'); - await Token.connect(admin).increaseAllowance(Staking.address, stakeAmount); - await Staking.connect(admin)['addStake(uint72,uint96)'](identityId, stakeAmount); - - return identityId; - } - - async function deployProofManagerV1U1Fixture(): Promise { - await hre.deployments.fixture(['ContentAsset', 'CommitManagerV1U1', 'ProofManagerV1U1', 'Profile']); - Token = await hre.ethers.getContract('Token'); - ServiceAgreementV1 = await hre.ethers.getContract('ServiceAgreementV1'); - ServiceAgreementStorageProxy = await hre.ethers.getContract( - 'ServiceAgreementStorageProxy', - ); - ContentAsset = await hre.ethers.getContract('ContentAsset'); - ContentAssetStorage = await hre.ethers.getContract('ContentAssetStorage'); - CommitManagerV1 = await hre.ethers.getContract('CommitManagerV1'); - CommitManagerV1U1 = await hre.ethers.getContract('CommitManagerV1U1'); - ProofManagerV1 = await hre.ethers.getContract('ProofManagerV1'); - ProofManagerV1U1 = await hre.ethers.getContract('ProofManagerV1U1'); - ParametersStorage = await hre.ethers.getContract('ParametersStorage'); - IdentityStorage = await hre.ethers.getContract('IdentityStorage'); - Profile = await hre.ethers.getContract('Profile'); - Staking = await hre.ethers.getContract('Staking'); - StakingStorage = await hre.ethers.getContract('StakingStorage'); - accounts = await hre.ethers.getSigners(); - - return { - accounts, - ServiceAgreementStorageProxy, - CommitManagerV1, - CommitManagerV1U1, - ProofManagerV1, - ProofManagerV1U1, - ParametersStorage, - IdentityStorage, - }; - } - - async function submitProofV1U1AndReturnReward( - identityId: number, - account: SignerWithAddress, - tokenId: number, - keyword: BytesLike, - epoch: number, - ) { - const challenge = await ProofManagerV1U1.connect(account).getChallenge(ContentAssetStorage.address, tokenId, epoch); - const { proof, leaf } = getMerkleProof(nQuadsUpdate, challenge[1].toNumber()); - - const proofInputArgs = { - assetContract: ContentAssetStorage.address, - tokenId, - keyword, - hashFunctionId: 1, - epoch, - proof, - chunkHash: leaf, - }; - - await expect(ProofManagerV1.connect(account).sendProof(proofInputArgs)).to.be.revertedWithCustomError( - ProofManagerV1, - 'ServiceAgreementDoesntExist', - ); - await ProofManagerV1U1.connect(account).sendProof(proofInputArgs); - const filter = Staking.filters.StakeIncreased(identityId); - const event = (await Staking.queryFilter(filter)).pop(); - if (!event) throw new Error(`Event is undefined for account ${account}`); - return event.args.newStake.sub(event.args.oldStake); - } - - beforeEach(async () => { - hre.helpers.resetDeploymentsJson(); - ({ accounts, ServiceAgreementStorageProxy, CommitManagerV1U1, CommitManagerV1U1, ParametersStorage } = - await loadFixture(deployProofManagerV1U1Fixture)); - }); - - it('The contract is named "ProofManagerV1U1"', async () => { - expect(await ProofManagerV1U1.name()).to.equal('ProofManagerV1U1'); - }); - - it('The contract is version "1.0.3"', async () => { - expect(await ProofManagerV1U1.version()).to.equal('1.0.3'); - }); - - it('Create a new asset, update and finalize update, teleport to the proof phase and check if window is open, expect true', async () => { - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - await finalizeUpdate(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - - await time.increase(delay); - - await expect(ProofManagerV1.isProofWindowOpen(agreementId, 0)).to.be.revertedWithCustomError( - ProofManagerV1, - 'ServiceAgreementDoesntExist', - ); - expect(await ProofManagerV1U1.isProofWindowOpen(agreementId, 0)).to.eql(true); - }); - - it('Create a new asset, update and finalize update, teleport to the moment before proof phase and check if window is open, expect false', async () => { - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - await finalizeUpdate(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const startTime = (await ServiceAgreementStorageProxy.getAgreementStartTime(agreementId)).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const proofWindowStart = startTime + (epochLength * proofWindowOffsetPerc) / 100; - - await time.increaseTo(proofWindowStart - 1); - - await expect(ProofManagerV1.isProofWindowOpen(agreementId, 0)).to.be.revertedWithCustomError( - ProofManagerV1, - 'ServiceAgreementDoesntExist', - ); - expect(await ProofManagerV1U1.isProofWindowOpen(agreementId, 0)).to.eql(false); - }); - - it('Create a new asset, update and finalize update, teleport to the moment after proof phase and check if window is open, expect false', async () => { - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - await finalizeUpdate(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const startTime = (await ServiceAgreementStorageProxy.getAgreementStartTime(agreementId)).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const proofWindowDurationPerc = await ParametersStorage.proofWindowDurationPerc(); - const proofWindowEnd = startTime + (epochLength * (proofWindowOffsetPerc + proofWindowDurationPerc)) / 100; - - await time.increaseTo(proofWindowEnd); - - await expect(ProofManagerV1.isProofWindowOpen(agreementId, 0)).to.be.revertedWithCustomError( - ProofManagerV1, - 'ServiceAgreementDoesntExist', - ); - expect(await ProofManagerV1U1.isProofWindowOpen(agreementId, 0)).to.eql(false); - }); - - it('Create a new asset, update and finalize update, teleport to the second epoch, send commit, teleport and send proof, expect ProofSent event and reward received', async () => { - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - const identityIds = await finalizeUpdate(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - await time.increase(epochLength); - - await submitCommitV1U1(accounts[0], tokenId, keyword, 1); - - const commitId = hre.ethers.utils.solidityKeccak256( - ['bytes32', 'uint16', 'uint256', 'uint96'], - [agreementId, 1, 1, identityIds[0]], - ); - - const challenge = await ProofManagerV1U1.getChallenge(ContentAssetStorage.address, tokenId, 1); - - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - - await time.increase(delay); - - const { proof, leaf } = getMerkleProof(nQuadsUpdate, challenge[1].toNumber()); - proofInputArgs = { - assetContract: ContentAssetStorage.address, - tokenId, - keyword, - hashFunctionId: 1, - epoch: 1, - proof, - chunkHash: leaf, - }; - - const initialStake = await StakingStorage.totalStakes(identityIds[0]); - const initialAssetReward = await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId); - - await expect(ProofManagerV1.sendProof(proofInputArgs)).to.be.revertedWithCustomError( - ProofManagerV1, - 'ServiceAgreementDoesntExist', - ); - await expect(ProofManagerV1U1.sendProof(proofInputArgs)).to.emit(ProofManagerV1U1, 'ProofSubmitted'); - - const endAssetReward = await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId); - expect(await StakingStorage.totalStakes(identityIds[0])).to.equal( - initialStake.add(initialAssetReward).sub(endAssetReward), - ); - - expect(await ServiceAgreementStorageProxy.getCommitSubmissionScore(commitId)).to.equal(0); - }); - - it('Create a new asset, update and finalize update, get challenge, expect challenge to be valid', async () => { - const { tokenId, keyword } = await createAsset(); - await updateAsset(tokenId); - await finalizeUpdate(tokenId, keyword); - - const challenge = await ProofManagerV1U1.getChallenge(ContentAssetStorage.address, tokenId, 1); - - expect(challenge[0]).to.equal(assetUpdateArgs.assertionId); - expect(challenge[1]).to.be.within(0, nQuadsUpdate.length - 1); - }); - - it('Create a new asset, update and finalize update, teleport to the second epoch, send commit, teleport and send 2 proofs, expect second proof to be reverted', async () => { - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - await finalizeUpdate(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - - await time.increase(epochLength); - - await submitCommitV1U1(accounts[0], tokenId, keyword, 1); - - const challenge = await ProofManagerV1U1.getChallenge(ContentAssetStorage.address, tokenId, 1); - - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - - await time.increase(delay); - - const { proof, leaf } = getMerkleProof(nQuadsUpdate, challenge[1].toNumber()); - proofInputArgs = { - assetContract: ContentAssetStorage.address, - tokenId, - keyword, - hashFunctionId: 1, - epoch: 1, - proof, - chunkHash: leaf, - }; - - await expect(ProofManagerV1.sendProof(proofInputArgs)).to.be.revertedWithCustomError( - ProofManagerV1, - 'ServiceAgreementDoesntExist', - ); - await expect(ProofManagerV1U1.sendProof(proofInputArgs)).to.emit(ProofManagerV1U1, 'ProofSubmitted'); - await expect(ProofManagerV1U1.sendProof(proofInputArgs)).to.be.revertedWithCustomError( - ProofManagerV1U1, - 'NodeAlreadyRewarded', - ); - }); - - it('Create a new asset, update and finalize update, teleport to the second epoch, 3 nodes send commit, teleport to proof phase, send 3 proofs and check that reward is equal for all 3 nodes', async () => { - const rewards = []; - - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - const identityIds = await finalizeUpdate(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - - await time.increase(epochLength); - - // All nodes submit their commits - for (let i = 0; i < identityIds.length; i++) { - await submitCommitV1U1(accounts[i], tokenId, keyword, 1); - } - - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - await time.increase(delay); - - // All nodes submit their proofs and store the rewards received - for (const [i, identityId] of identityIds.entries()) { - const reward = await submitProofV1U1AndReturnReward(identityId, accounts[i], tokenId, keyword, 1); - rewards.push(reward); - } - - // Check that all nodes received the same reward (or the discrepancy is less than or equal to 1 wei) - for (let i = 0; i < rewards.length - 1; i++) { - expect( - rewards[i] - .sub(rewards[i + 1]) - .abs() - .lte(1), - ).to.be.true; - } - }); - - it('Create a new asset, update and finalize it, teleport to the second epoch, 2 nodes send commit, teleport to proof phase, send 2 proofs and check that reward for the next epoch has increased', async () => { - const rewards: BigNumber[][] = [[], [], []]; - - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - const identityIds = await finalizeUpdate(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - - await time.increase(epochLength); - - let epoch = 1; - for (let i = 0; i < 2; i++) { - await submitCommitV1U1(accounts[i], tokenId, keyword, 1); - } - - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - - await time.increase(delay); - - for (let i = 0; i < 2; i++) { - // First two nodes submit their proofs - const reward = await submitProofV1U1AndReturnReward(identityIds[i], accounts[i], tokenId, keyword, epoch); - rewards[i].push(reward); - } - rewards[2].push(hre.ethers.BigNumber.from(0)); - - await time.increase(epochLength - delay); // Increase time to the third epoch - - epoch = 2; - for (let i = 0; i < identityIds.length; i++) { - // All nodes submit their commits for the second epoch - await submitCommitV1U1(accounts[i], tokenId, keyword, epoch); - } - - await time.increase(delay); // increase time to proof window - - for (let i = 0; i < identityIds.length; i++) { - // All nodes submit their proofs for the second epoch - const reward = await submitProofV1U1AndReturnReward(identityIds[i], accounts[i], tokenId, keyword, epoch); - rewards[i].push(reward); - } - - // Check that the reward for the second epoch is greater than for the first epoch - for (let i = 0; i < 2; i++) { - expect(rewards[i][1].gt(rewards[i][0])).to.be.true; - } - - // Check that all nodes received the same reward for the second epoch - for (let i = 0; i < rewards.length - 1; i++) { - expect( - rewards[i][1] - .sub(rewards[i + 1][1]) - .abs() - .lte(1), - ).to.be.true; - } - }); - - it('Rewards are equal for all nodes in each epoch, including when some nodes miss commits or proofs', async () => { - const rewards: BigNumber[][] = [[], [], []]; - - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - const identityIds = await finalizeUpdate(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - - await time.increase(delay); - - for (let i = 0; i < identityIds.length; i++) { - const reward = await submitProofV1U1AndReturnReward(identityIds[i], accounts[i], tokenId, keyword, 0); - rewards[i].push(reward); - } - - await time.increase(epochLength - delay); - - for (let epoch = 1; epoch < 5; epoch++) { - const shouldCommit = [epoch !== 1 && epoch !== 3, true, true]; - const shouldProve = [epoch !== 1 && epoch !== 3, epoch !== 3 && epoch !== 4, true]; - - for (let i = 0; i < identityIds.length; i++) { - if (shouldCommit[i]) { - await submitCommitV1U1(accounts[i], tokenId, keyword, epoch); - } - } - - await time.increase(delay); - - for (let i = 0; i < identityIds.length; i++) { - if (shouldProve[i]) { - const reward = await submitProofV1U1AndReturnReward(identityIds[i], accounts[i], tokenId, keyword, epoch); - rewards[i].push(reward); - } else { - rewards[i].push(hre.ethers.BigNumber.from(0)); - } - } - - await time.increase(epochLength - delay); - } - // Check that all nodes received the same reward for each epoch they submitted proofs - for (let epoch = 0; epoch < 5; epoch++) { - const epochRewards = rewards.map((r) => r[epoch]); - for (let i = 0; i < epochRewards.length - 1; i++) { - if (epochRewards[i].isZero() || epochRewards[i + 1].isZero()) continue; - expect( - epochRewards[i] - .sub(epochRewards[i + 1]) - .abs() - .lte(1), - ).to.be.true; - } - } - }); - - it('Each node submits commits and proofs for each epoch, verify all rewards in all epochs are the same, and total rewards equals initial token amount in service agreement', async () => { - let rewards: BigNumber[] = []; - const totalEpochs = 5; - - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - const identityIds = await finalizeUpdate(tokenId, keyword); - - const initialTokenAmount = await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - - await time.increase(delay); - - for (let i = 0; i < identityIds.length; i++) { - const reward = await submitProofV1U1AndReturnReward(identityIds[i], accounts[i], tokenId, keyword, 0); - rewards.push(reward); - } - - for (let i = 0; i < rewards.length - 1; i++) { - expect( - rewards[i] - .sub(rewards[i + 1]) - .abs() - .lte(1), - ).to.be.true; - } - - await time.increase(epochLength - delay); - - let totalReward = BigNumber.from(0); - totalReward = rewards.reduce((total, reward) => total.add(reward), totalReward); - rewards = []; - - // Run through each epoch - for (let epoch = 1; epoch < totalEpochs; epoch++) { - // All nodes submit their commits - for (let i = 0; i < identityIds.length; i++) { - await submitCommitV1U1(accounts[i], tokenId, keyword, epoch); - } - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - await time.increase(delay); - - // All nodes submit their proofs and store the rewards received - for (const [i, identityId] of identityIds.entries()) { - const reward = await submitProofV1U1AndReturnReward(identityId, accounts[i], tokenId, keyword, epoch); - rewards.push(reward); - } - - // Check that all nodes received the same reward (or the discrepancy is less than or equal to 1 wei) - for (let i = 0; i < rewards.length - 1; i++) { - expect( - rewards[i] - .sub(rewards[i + 1]) - .abs() - .lte(1), - ).to.be.true; - } - - await time.increase(epochLength - delay); - // Calculate total reward and reset rewards for next epoch - totalReward = rewards.reduce((total, reward) => total.add(reward), totalReward); - rewards = []; // Reset rewards for next epoch - } - - expect(totalReward.eq(initialTokenAmount)).to.be.true; - - // Check that the token amount stored in the service agreement at the end of the test is 0 - const finalTokenAmount = await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId); - expect(finalTokenAmount.eq(0)).to.be.true; - }); - - it('Variable number of nodes send commits and proofs each epoch, verify all rewards in all epochs are the same, and total rewards equals initial token amount in service agreement', async () => { - let rewards = []; - const totalEpochs = 5; - - const { tokenId, keyword, agreementId } = await createAsset(); - await updateAsset(tokenId); - const identityIds = await finalizeUpdate(tokenId, keyword); - - const initialTokenAmount = await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - - await time.increase(delay); - - for (let i = 0; i < identityIds.length; i++) { - const reward = await submitProofV1U1AndReturnReward(identityIds[i], accounts[i], tokenId, keyword, 0); - rewards.push(reward); - } - - for (let i = 0; i < rewards.length - 1; i++) { - expect( - rewards[i] - .sub(rewards[i + 1]) - .abs() - .lte(1), - ).to.be.true; - } - - await time.increase(epochLength - delay); - - let totalReward = BigNumber.from(0); - totalReward = rewards.reduce((total, reward) => total.add(reward), totalReward); - rewards = []; // Reset rewards for next epoch - - // Define wallet subsets for commit and proof phases for each epoch - const walletSubsetsForCommit = [ - [], - accounts.slice(0, 2), // less than 3 nodes send commits - accounts.slice(0, 3), // 3 nodes send commits - accounts.slice(0, 3), // 3 nodes send commits - accounts.slice(0, 3), // 3 nodes send commits - ]; - - const walletSubsetsForProof = [ - [], - accounts.slice(0, 2), // Less than 3 nodes send proofs - accounts.slice(0, 2), // Less than 3 nodes send proofs - accounts.slice(0, 3), // 3 nodes send proofs - accounts.slice(0, 3), // 3 nodes send proofs - ]; - - // Run through each epoch - for (let epoch = 1; epoch < totalEpochs; epoch++) { - const currentWalletSubsetForCommit = walletSubsetsForCommit[epoch]; - const currentWalletSubsetForProof = walletSubsetsForProof[epoch]; - - // Subset of nodes submit their commits - for (const operationalWallet of currentWalletSubsetForCommit) { - await submitCommitV1U1(operationalWallet, tokenId, keyword, epoch); - } - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const proofWindowOffsetPerc = await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId); - const delay = (epochLength * proofWindowOffsetPerc) / 100; - await time.increase(delay); - - // Subset of nodes submit their proofs and store the rewards received - for (const operationalWallet of currentWalletSubsetForProof) { - const identity = identityIds[accounts.indexOf(operationalWallet)]; - const reward = await submitProofV1U1AndReturnReward(identity, operationalWallet, tokenId, keyword, epoch); - rewards.push(reward); - } - - // Check that all nodes received the same reward (or the discrepancy is less than or equal to 1 wei) - for (let i = 0; i < rewards.length - 1; i++) { - expect( - rewards[i] - .sub(rewards[i + 1]) - .abs() - .lte(1), - ).to.be.true; - } - - await time.increase(epochLength - delay); - - // Calculate total reward and reset rewards for next epoch - totalReward = rewards.reduce((total, reward) => total.add(reward), totalReward); - rewards = []; // Reset rewards for next epoch - } - - expect(totalReward.eq(initialTokenAmount)).to.be.true; - - // Check that the token amount stored in the service agreement at the end of the test is 0 - const finalTokenAmount = await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId); - expect(finalTokenAmount.eq(0)).to.be.true; - }); -}); diff --git a/test/v1/unit/ServiceAgreementStorageProxy.test.ts b/test/v1/unit/ServiceAgreementStorageProxy.test.ts deleted file mode 100644 index 503b7501..00000000 --- a/test/v1/unit/ServiceAgreementStorageProxy.test.ts +++ /dev/null @@ -1,373 +0,0 @@ -import { randomBytes } from 'crypto'; - -import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; -import { expect } from 'chai'; -import hre from 'hardhat'; -import { SignerWithAddress } from 'hardhat-deploy-ethers/signers'; - -import { Token, ServiceAgreementStorageProxy, HubController } from '../../../typechain'; - -type ServiceAgreementStorageProxyFixture = { - accounts: SignerWithAddress[]; - ServiceAgreementStorageProxy: ServiceAgreementStorageProxy; - Token: Token; -}; - -describe('@v1 @unit ServiceAgreementStorageProxy contract', function () { - const agreementId = '0x' + randomBytes(32).toString('hex'); - const newAgreementId = '0x' + randomBytes(32).toString('hex'); - const startTime = Math.floor(Date.now() / 1000).toString(); - const epochsNumber = 5; - const epochLength = 10; - const tokenAmount = hre.ethers.utils.parseEther('100'); - const scoreFunctionId = 0; - const proofWindowOffsetPerc = 10; - - let accounts: SignerWithAddress[]; - let ServiceAgreementStorageProxy: ServiceAgreementStorageProxy; - let Token: Token; - - async function deployServiceAgreementStorageProxyFixture(): Promise { - await hre.deployments.fixture(['ServiceAgreementStorageProxy']); - accounts = await hre.ethers.getSigners(); - ServiceAgreementStorageProxy = await hre.ethers.getContract( - 'ServiceAgreementStorageProxy', - ); - Token = await hre.ethers.getContract('Token'); - const HubController = await hre.ethers.getContract('HubController'); - await HubController.setContractAddress('HubOwner', accounts[0].address); - - return { accounts, ServiceAgreementStorageProxy, Token }; - } - - async function createV1ServiceAgreement() { - await ServiceAgreementStorageProxy.createV1ServiceAgreementObject( - agreementId, - epochsNumber, - epochLength, - tokenAmount, - scoreFunctionId, - proofWindowOffsetPerc, - ); - } - - async function createV1U1ServiceAgreement() { - await ServiceAgreementStorageProxy.createV1U1ServiceAgreementObject( - agreementId, - startTime, - epochsNumber, - epochLength, - tokenAmount, - scoreFunctionId, - proofWindowOffsetPerc, - ); - } - - beforeEach(async () => { - hre.helpers.resetDeploymentsJson(); - ({ accounts, ServiceAgreementStorageProxy, Token } = await loadFixture(deployServiceAgreementStorageProxyFixture)); - }); - - it('The contract is named "ServiceAgreementStorageProxy"', async () => { - expect(await ServiceAgreementStorageProxy.name()).to.equal('ServiceAgreementStorageProxy'); - }); - - it('The contract is version "1.0.0"', async () => { - expect(await ServiceAgreementStorageProxy.version()).to.equal('1.0.0'); - }); - - it('Should allow creating V1 service agreement object', async () => { - await createV1ServiceAgreement(); - - const blockNumber = await hre.ethers.provider.getBlockNumber(); - const blockTimestamp = (await hre.ethers.provider.getBlock(blockNumber)).timestamp; - - const agreementData = await ServiceAgreementStorageProxy.getAgreementData(agreementId); - - expect(agreementData).to.deep.equal([ - blockTimestamp, - epochsNumber, - epochLength, - [tokenAmount, 0], - [scoreFunctionId, proofWindowOffsetPerc], - ]); - }); - - it('Should allow deleting V1 service agreement object', async () => { - await createV1ServiceAgreement(); - - await ServiceAgreementStorageProxy.deleteServiceAgreementObject(agreementId); - - const agreementData = await ServiceAgreementStorageProxy.getAgreementData(agreementId); - - expect(agreementData).to.deep.equal([0, 0, 0, [0, 0], [0, 0]]); - }); - - it('Should allow updating V1 service agreement data using get and set', async () => { - await createV1ServiceAgreement(); - - const blockNumber = await hre.ethers.provider.getBlockNumber(); - const blockTimestamp = (await hre.ethers.provider.getBlock(blockNumber)).timestamp; - const newBlockTimestamp = blockTimestamp + 1; - const newEpochsNumber = 10; - const newEpochLength = 15; - const newTokenAmount = hre.ethers.utils.parseEther('200'); - const newScoreFunctionId = 1; - const newProofWindowOffsetPerc = 20; - const agreementEpochSubmissionHead = '0x' + randomBytes(32).toString('hex'); - - await ServiceAgreementStorageProxy.setAgreementStartTime(agreementId, newBlockTimestamp); - expect(await ServiceAgreementStorageProxy.getAgreementStartTime(agreementId)).to.equal(newBlockTimestamp); - - await ServiceAgreementStorageProxy.setAgreementEpochsNumber(agreementId, newEpochsNumber); - expect(await ServiceAgreementStorageProxy.getAgreementEpochsNumber(agreementId)).to.equal(newEpochsNumber); - - await ServiceAgreementStorageProxy.setAgreementEpochLength(agreementId, newEpochLength); - expect(await ServiceAgreementStorageProxy.getAgreementEpochLength(agreementId)).to.equal(newEpochLength); - - await ServiceAgreementStorageProxy.setAgreementTokenAmount(agreementId, newTokenAmount); - expect(await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId)).to.equal(newTokenAmount); - - await ServiceAgreementStorageProxy.setAgreementScoreFunctionId(agreementId, newScoreFunctionId); - expect(await ServiceAgreementStorageProxy.getAgreementScoreFunctionId(agreementId)).to.equal(newScoreFunctionId); - - await ServiceAgreementStorageProxy.setAgreementProofWindowOffsetPerc(agreementId, newProofWindowOffsetPerc); - expect(await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId)).to.equal( - newProofWindowOffsetPerc, - ); - - await ServiceAgreementStorageProxy.setV1AgreementEpochSubmissionHead(agreementId, 0, agreementEpochSubmissionHead); - expect(await ServiceAgreementStorageProxy.getV1AgreementEpochSubmissionHead(agreementId, 0)).to.equal( - agreementEpochSubmissionHead, - ); - }); - - it('Should allow incrementing/decrementing/setting/deleting agreement rewarded number for V1 SA', async () => { - await createV1ServiceAgreement(); - - const initialNodesNumber = await ServiceAgreementStorageProxy.getAgreementRewardedNodesNumber(agreementId, 0); - - await ServiceAgreementStorageProxy.incrementAgreementRewardedNodesNumber(agreementId, 0); - expect(await ServiceAgreementStorageProxy.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal( - initialNodesNumber + 1, - ); - - await ServiceAgreementStorageProxy.decrementAgreementRewardedNodesNumber(agreementId, 0); - expect(await ServiceAgreementStorageProxy.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal( - initialNodesNumber, - ); - - const nodesNumber = 5; - await ServiceAgreementStorageProxy.setAgreementRewardedNodesNumber(agreementId, 0, nodesNumber); - expect(await ServiceAgreementStorageProxy.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal(nodesNumber); - - await ServiceAgreementStorageProxy.deleteAgreementRewardedNodesNumber(agreementId, 0); - expect(await ServiceAgreementStorageProxy.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal(0); - }); - - it('Service agreement exists should return true for existing V1U1 agreement', async () => { - await createV1U1ServiceAgreement(); - - expect(await ServiceAgreementStorageProxy.serviceAgreementExists(agreementId)).to.equal(true); - expect(await ServiceAgreementStorageProxy.serviceAgreementExists(newAgreementId)).to.equal(false); - }); - - it('Should allow creating/deleting commit submission object for V1 SA', async () => { - const commitId = '0x' + randomBytes(32).toString('hex'); - const identityId = 2; - const prevIdentityId = 1; - const nextIdentityId = 3; - const score = 5; - - await ServiceAgreementStorageProxy.createV1CommitSubmissionObject( - commitId, - identityId, - prevIdentityId, - nextIdentityId, - score, - ); - let commitSubmission = await ServiceAgreementStorageProxy.getCommitSubmission(commitId); - - expect(commitSubmission).to.deep.equal([identityId, prevIdentityId, nextIdentityId, score]); - - await ServiceAgreementStorageProxy.deleteCommitSubmissionsObject(commitId); - commitSubmission = await ServiceAgreementStorageProxy.getCommitSubmission(commitId); - - expect(commitSubmission).to.deep.equal([0, 0, 0, 0]); - }); - - it('Should allow creating V1U1 service agreement object', async () => { - await createV1U1ServiceAgreement(); - - const agreementData = await ServiceAgreementStorageProxy.getAgreementData(agreementId); - - expect(agreementData).to.deep.equal([ - startTime, - epochsNumber, - epochLength, - [tokenAmount, 0], - [scoreFunctionId, proofWindowOffsetPerc], - ]); - }); - - it('Should allow deleting V1U1 service agreement object', async () => { - await createV1U1ServiceAgreement(); - - await ServiceAgreementStorageProxy.deleteServiceAgreementObject(agreementId); - - const agreementData = await ServiceAgreementStorageProxy.getAgreementData(agreementId); - - expect(agreementData).to.deep.equal([0, 0, 0, [0, 0], [0, 0]]); - }); - - it('Should allow updating V1U1 service agreement data using get and set', async () => { - await createV1U1ServiceAgreement(); - - const blockNumber = await hre.ethers.provider.getBlockNumber(); - const blockTimestamp = (await hre.ethers.provider.getBlock(blockNumber)).timestamp; - const newBlockTimestamp = blockTimestamp + 1; - const newEpochsNumber = 10; - const newEpochLength = 15; - const newTokenAmount = hre.ethers.utils.parseEther('200'); - const newUpdateTokenAmount = hre.ethers.utils.parseEther('100'); - const newScoreFunctionId = 1; - const newProofWindowOffsetPerc = 20; - const agreementEpochSubmissionHead = '0x' + randomBytes(32).toString('hex'); - - await ServiceAgreementStorageProxy.setAgreementStartTime(agreementId, newBlockTimestamp); - expect(await ServiceAgreementStorageProxy.getAgreementStartTime(agreementId)).to.equal(newBlockTimestamp); - - await ServiceAgreementStorageProxy.setAgreementEpochsNumber(agreementId, newEpochsNumber); - expect(await ServiceAgreementStorageProxy.getAgreementEpochsNumber(agreementId)).to.equal(newEpochsNumber); - - await ServiceAgreementStorageProxy.setAgreementEpochLength(agreementId, newEpochLength); - expect(await ServiceAgreementStorageProxy.getAgreementEpochLength(agreementId)).to.equal(newEpochLength); - - await ServiceAgreementStorageProxy.setAgreementTokenAmount(agreementId, newTokenAmount); - expect(await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId)).to.equal(newTokenAmount); - - await ServiceAgreementStorageProxy.setAgreementUpdateTokenAmount(agreementId, newUpdateTokenAmount); - expect(await ServiceAgreementStorageProxy.getAgreementUpdateTokenAmount(agreementId)).to.equal( - newUpdateTokenAmount, - ); - - await ServiceAgreementStorageProxy.setAgreementScoreFunctionId(agreementId, newScoreFunctionId); - expect(await ServiceAgreementStorageProxy.getAgreementScoreFunctionId(agreementId)).to.equal(newScoreFunctionId); - - await ServiceAgreementStorageProxy.setAgreementProofWindowOffsetPerc(agreementId, newProofWindowOffsetPerc); - expect(await ServiceAgreementStorageProxy.getAgreementProofWindowOffsetPerc(agreementId)).to.equal( - newProofWindowOffsetPerc, - ); - - await ServiceAgreementStorageProxy.setV1U1AgreementEpochSubmissionHead( - agreementId, - 0, - 0, - agreementEpochSubmissionHead, - ); - expect(await ServiceAgreementStorageProxy.getV1U1AgreementEpochSubmissionHead(agreementId, 0, 0)).to.equal( - agreementEpochSubmissionHead, - ); - }); - - it('Should allow incrementing/decrementing/setting/deleting agreement rewarded number for V1U1 SA', async () => { - await createV1U1ServiceAgreement(); - - const initialNodesNumber = await ServiceAgreementStorageProxy.getAgreementRewardedNodesNumber(agreementId, 0); - - await ServiceAgreementStorageProxy.incrementAgreementRewardedNodesNumber(agreementId, 0); - expect(await ServiceAgreementStorageProxy.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal( - initialNodesNumber + 1, - ); - - await ServiceAgreementStorageProxy.decrementAgreementRewardedNodesNumber(agreementId, 0); - expect(await ServiceAgreementStorageProxy.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal( - initialNodesNumber, - ); - - const nodesNumber = 5; - await ServiceAgreementStorageProxy.setAgreementRewardedNodesNumber(agreementId, 0, nodesNumber); - expect(await ServiceAgreementStorageProxy.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal(nodesNumber); - - await ServiceAgreementStorageProxy.deleteAgreementRewardedNodesNumber(agreementId, 0); - expect(await ServiceAgreementStorageProxy.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal(0); - }); - - it('Service agreement exists should return true for existing V1U1 agreement', async () => { - await createV1U1ServiceAgreement(); - - expect(await ServiceAgreementStorageProxy.serviceAgreementExists(agreementId)).to.equal(true); - expect(await ServiceAgreementStorageProxy.serviceAgreementExists(newAgreementId)).to.equal(false); - }); - - it('Should allow creating/deleting commit submission object for V1U1 SA', async () => { - const commitId = '0x' + randomBytes(32).toString('hex'); - const identityId = 2; - const prevIdentityId = 1; - const nextIdentityId = 3; - const score = 5; - - await ServiceAgreementStorageProxy.createV1U1CommitSubmissionObject( - commitId, - identityId, - prevIdentityId, - nextIdentityId, - score, - ); - let commitSubmission = await ServiceAgreementStorageProxy.getCommitSubmission(commitId); - - expect(commitSubmission).to.deep.equal([identityId, prevIdentityId, nextIdentityId, score]); - - await ServiceAgreementStorageProxy.deleteCommitSubmissionsObject(commitId); - commitSubmission = await ServiceAgreementStorageProxy.getCommitSubmission(commitId); - - expect(commitSubmission).to.deep.equal([0, 0, 0, 0]); - }); - - it('Should allow increasing/deacreasing/deleting epoch state commits count for V1U1 SA', async () => { - await createV1U1ServiceAgreement(); - - const epochStateId = '0x' + randomBytes(32).toString('hex'); - - const initialCommitsNumber = await ServiceAgreementStorageProxy.getCommitsCount(epochStateId); - - await ServiceAgreementStorageProxy.incrementCommitsCount(epochStateId); - expect(await ServiceAgreementStorageProxy.getCommitsCount(epochStateId)).to.equal(initialCommitsNumber + 1); - - await ServiceAgreementStorageProxy.decrementCommitsCount(epochStateId); - expect(await ServiceAgreementStorageProxy.getCommitsCount(epochStateId)).to.equal(initialCommitsNumber); - - const commitsNumber = 5; - await ServiceAgreementStorageProxy.setCommitsCount(epochStateId, commitsNumber); - expect(await ServiceAgreementStorageProxy.getCommitsCount(epochStateId)).to.equal(commitsNumber); - - await ServiceAgreementStorageProxy.deleteCommitsCount(epochStateId); - expect(await ServiceAgreementStorageProxy.getCommitsCount(epochStateId)).to.equal(0); - }); - - it('Should allow setting/deleting update commits deadline for V1U1 SA', async () => { - await createV1U1ServiceAgreement(); - - const blockNumber = await hre.ethers.provider.getBlockNumber(); - const blockTimestamp = (await hre.ethers.provider.getBlock(blockNumber)).timestamp; - - const stateId = '0x' + randomBytes(32).toString('hex'); - const deadline = blockTimestamp + 1000; - - await ServiceAgreementStorageProxy.setUpdateCommitsDeadline(stateId, deadline); - expect(await ServiceAgreementStorageProxy.getUpdateCommitsDeadline(stateId)).to.equal(deadline); - - await ServiceAgreementStorageProxy.deleteUpdateCommitsDeadline(stateId); - expect(await ServiceAgreementStorageProxy.getUpdateCommitsDeadline(stateId)).to.equal(0); - }); - - it('Should allow transferring reward for V1U1 SA', async () => { - const transferAmount = hre.ethers.utils.parseEther('100'); - const receiver = accounts[1].address; - await Token.mint(await ServiceAgreementStorageProxy.agreementV1U1StorageAddress(), transferAmount); - - const initialReceiverBalance = await Token.balanceOf(receiver); - await ServiceAgreementStorageProxy.transferV1U1AgreementTokens(receiver, transferAmount); - expect(await Token.balanceOf(receiver)).to.equal(initialReceiverBalance.add(transferAmount)); - }); -}); diff --git a/test/v1/unit/ServiceAgreementStorageV1.test.ts b/test/v1/unit/ServiceAgreementStorageV1.test.ts deleted file mode 100644 index a3d88cd0..00000000 --- a/test/v1/unit/ServiceAgreementStorageV1.test.ts +++ /dev/null @@ -1,176 +0,0 @@ -import { randomBytes } from 'crypto'; - -import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; -import { expect } from 'chai'; -import hre from 'hardhat'; -import { SignerWithAddress } from 'hardhat-deploy-ethers/signers'; - -import { Token, ServiceAgreementStorageV1, HubController } from '../../../typechain'; - -type ServiceAgreementStorageV1Fixture = { - accounts: SignerWithAddress[]; - ServiceAgreementStorageV1: ServiceAgreementStorageV1; - Token: Token; -}; - -describe('@v1 @unit ServiceAgreementStorageV1 contract', function () { - const agreementId = '0x' + randomBytes(32).toString('hex'); - const newAgreementId = '0x' + randomBytes(32).toString('hex'); - const epochsNumber = 5; - const epochLength = 10; - const tokenAmount = hre.ethers.utils.parseEther('100'); - const scoreFunctionId = 0; - const proofWindowOffsetPerc = 10; - - let accounts: SignerWithAddress[]; - let ServiceAgreementStorageV1: ServiceAgreementStorageV1; - let Token: Token; - - async function deployServiceAgreementStorageV1Fixture(): Promise { - await hre.deployments.fixture(['ServiceAgreementStorageV1']); - accounts = await hre.ethers.getSigners(); - ServiceAgreementStorageV1 = await hre.ethers.getContract('ServiceAgreementStorageV1'); - Token = await hre.ethers.getContract('Token'); - const HubController = await hre.ethers.getContract('HubController'); - await HubController.setContractAddress('HubOwner', accounts[0].address); - - return { accounts, ServiceAgreementStorageV1, Token }; - } - - async function createServiceAgreement() { - await ServiceAgreementStorageV1.createServiceAgreementObject( - agreementId, - epochsNumber, - epochLength, - tokenAmount, - scoreFunctionId, - proofWindowOffsetPerc, - ); - } - - beforeEach(async () => { - hre.helpers.resetDeploymentsJson(); - ({ accounts, ServiceAgreementStorageV1, Token } = await loadFixture(deployServiceAgreementStorageV1Fixture)); - }); - - it('The contract is named "ServiceAgreementStorageV1"', async () => { - expect(await ServiceAgreementStorageV1.name()).to.equal('ServiceAgreementStorageV1'); - }); - - it('The contract is version "1.0.0"', async () => { - expect(await ServiceAgreementStorageV1.version()).to.equal('1.0.0'); - }); - - it('Should allow creating service agreement object', async () => { - await createServiceAgreement(); - - const blockNumber = await hre.ethers.provider.getBlockNumber(); - const blockTimestamp = (await hre.ethers.provider.getBlock(blockNumber)).timestamp; - - const agreementData = await ServiceAgreementStorageV1.getAgreementData(agreementId); - - expect(agreementData).to.deep.equal([ - blockTimestamp, - epochsNumber, - epochLength, - tokenAmount, - [scoreFunctionId, proofWindowOffsetPerc], - ]); - }); - - it('Should allow updating service agreement data using get and set', async () => { - await createServiceAgreement(); - - const blockNumber = await hre.ethers.provider.getBlockNumber(); - const blockTimestamp = (await hre.ethers.provider.getBlock(blockNumber)).timestamp; - const newBlockTimestamp = blockTimestamp + 1; - const newEpochsNumber = 10; - const newEpochLength = 15; - const newTokenAmount = hre.ethers.utils.parseEther('200'); - const newScoreFunctionId = 1; - const newProofWindowOffsetPerc = 20; - const agreementEpochSubmissionHead = '0x' + randomBytes(32).toString('hex'); - - await ServiceAgreementStorageV1.setAgreementStartTime(agreementId, newBlockTimestamp); - expect(await ServiceAgreementStorageV1.getAgreementStartTime(agreementId)).to.equal(newBlockTimestamp); - - await ServiceAgreementStorageV1.setAgreementEpochsNumber(agreementId, newEpochsNumber); - expect(await ServiceAgreementStorageV1.getAgreementEpochsNumber(agreementId)).to.equal(newEpochsNumber); - - await ServiceAgreementStorageV1.setAgreementEpochLength(agreementId, newEpochLength); - expect(await ServiceAgreementStorageV1.getAgreementEpochLength(agreementId)).to.equal(newEpochLength); - - await ServiceAgreementStorageV1.setAgreementTokenAmount(agreementId, newTokenAmount); - expect(await ServiceAgreementStorageV1.getAgreementTokenAmount(agreementId)).to.equal(newTokenAmount); - - await ServiceAgreementStorageV1.setAgreementScoreFunctionId(agreementId, newScoreFunctionId); - expect(await ServiceAgreementStorageV1.getAgreementScoreFunctionId(agreementId)).to.equal(newScoreFunctionId); - - await ServiceAgreementStorageV1.setAgreementProofWindowOffsetPerc(agreementId, newProofWindowOffsetPerc); - expect(await ServiceAgreementStorageV1.getAgreementProofWindowOffsetPerc(agreementId)).to.equal( - newProofWindowOffsetPerc, - ); - - await ServiceAgreementStorageV1.setAgreementEpochSubmissionHead(agreementId, 0, agreementEpochSubmissionHead); - expect(await ServiceAgreementStorageV1.getAgreementEpochSubmissionHead(agreementId, 0)).to.equal( - agreementEpochSubmissionHead, - ); - }); - - it('Should allow increment and decrement agreement rewarded number', async () => { - await createServiceAgreement(); - - const initialNodesNumber = await ServiceAgreementStorageV1.getAgreementRewardedNodesNumber(agreementId, 0); - - await ServiceAgreementStorageV1.incrementAgreementRewardedNodesNumber(agreementId, 0); - expect(await ServiceAgreementStorageV1.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal( - initialNodesNumber + 1, - ); - - await ServiceAgreementStorageV1.decrementAgreementRewardedNodesNumber(agreementId, 0); - expect(await ServiceAgreementStorageV1.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal( - initialNodesNumber, - ); - - const nodesNumber = 5; - await ServiceAgreementStorageV1.setAgreementRewardedNodesNumber(agreementId, 0, nodesNumber); - expect(await ServiceAgreementStorageV1.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal(nodesNumber); - }); - - it('Service agreement exists should return true for existing agreement', async () => { - await createServiceAgreement(); - - expect(await ServiceAgreementStorageV1.serviceAgreementExists(agreementId)).to.equal(true); - expect(await ServiceAgreementStorageV1.serviceAgreementExists(newAgreementId)).to.equal(false); - }); - - it('Should allow creating commit submission object', async () => { - const commitId = '0x' + randomBytes(32).toString('hex'); - const identityId = 2; - const prevIdentityId = 1; - const nextIdentityId = 3; - const score = 5; - - await ServiceAgreementStorageV1.createCommitSubmissionObject( - commitId, - identityId, - prevIdentityId, - nextIdentityId, - score, - ); - - const commitSubmission = await ServiceAgreementStorageV1.getCommitSubmission(commitId); - - expect(commitSubmission).to.deep.equal([identityId, prevIdentityId, nextIdentityId, score]); - }); - - it('Should allow transferring reward', async () => { - const transferAmount = hre.ethers.utils.parseEther('100'); - const receiver = accounts[1].address; - await Token.mint(ServiceAgreementStorageV1.address, transferAmount); - - const initialReceiverBalance = await Token.balanceOf(receiver); - await ServiceAgreementStorageV1.transferAgreementTokens(receiver, transferAmount); - expect(await Token.balanceOf(receiver)).to.equal(initialReceiverBalance.add(transferAmount)); - }); -}); diff --git a/test/v1/unit/ServiceAgreementStorageV1U1.test.ts b/test/v1/unit/ServiceAgreementStorageV1U1.test.ts deleted file mode 100644 index 633d6462..00000000 --- a/test/v1/unit/ServiceAgreementStorageV1U1.test.ts +++ /dev/null @@ -1,237 +0,0 @@ -import { randomBytes } from 'crypto'; - -import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; -import { expect } from 'chai'; -import hre from 'hardhat'; -import { SignerWithAddress } from 'hardhat-deploy-ethers/signers'; - -import { Token, ServiceAgreementStorageV1U1, HubController } from '../../../typechain'; - -type ServiceAgreementStorageV1U1Fixture = { - accounts: SignerWithAddress[]; - ServiceAgreementStorageV1U1: ServiceAgreementStorageV1U1; - Token: Token; -}; - -describe('@v1 @unit ServiceAgreementStorageV1U1 contract', function () { - const agreementId = '0x' + randomBytes(32).toString('hex'); - const newAgreementId = '0x' + randomBytes(32).toString('hex'); - const startTime = Math.floor(Date.now() / 1000).toString(); - const epochsNumber = 5; - const epochLength = 10; - const tokenAmount = hre.ethers.utils.parseEther('100'); - const scoreFunctionId = 0; - const proofWindowOffsetPerc = 10; - - let accounts: SignerWithAddress[]; - let ServiceAgreementStorageV1U1: ServiceAgreementStorageV1U1; - let Token: Token; - - async function deployServiceAgreementStorageV1U1Fixture(): Promise { - await hre.deployments.fixture(['ServiceAgreementStorageV1U1']); - accounts = await hre.ethers.getSigners(); - ServiceAgreementStorageV1U1 = await hre.ethers.getContract( - 'ServiceAgreementStorageV1U1', - ); - Token = await hre.ethers.getContract('Token'); - const HubController = await hre.ethers.getContract('HubController'); - await HubController.setContractAddress('HubOwner', accounts[0].address); - - return { accounts, ServiceAgreementStorageV1U1, Token }; - } - - async function createServiceAgreement() { - await ServiceAgreementStorageV1U1.createServiceAgreementObject( - agreementId, - startTime, - epochsNumber, - epochLength, - tokenAmount, - scoreFunctionId, - proofWindowOffsetPerc, - ); - } - - beforeEach(async () => { - hre.helpers.resetDeploymentsJson(); - ({ accounts, ServiceAgreementStorageV1U1, Token } = await loadFixture(deployServiceAgreementStorageV1U1Fixture)); - }); - - it('The contract is named "ServiceAgreementStorageV1U1"', async () => { - expect(await ServiceAgreementStorageV1U1.name()).to.equal('ServiceAgreementStorageV1U1'); - }); - - it('The contract is version "1.0.0"', async () => { - expect(await ServiceAgreementStorageV1U1.version()).to.equal('1.0.0'); - }); - - it('Should allow creating service agreement object', async () => { - await createServiceAgreement(); - - const agreementData = await ServiceAgreementStorageV1U1.getAgreementData(agreementId); - - expect(agreementData).to.deep.equal([ - startTime, - epochsNumber, - epochLength, - [tokenAmount, 0], - [scoreFunctionId, proofWindowOffsetPerc], - ]); - }); - - it('Should allow deleting service agreement object', async () => { - await createServiceAgreement(); - - await ServiceAgreementStorageV1U1.deleteServiceAgreementObject(agreementId); - - const agreementData = await ServiceAgreementStorageV1U1.getAgreementData(agreementId); - - expect(agreementData).to.deep.equal([0, 0, 0, [0, 0], [0, 0]]); - }); - - it('Should allow updating service agreement data using get and set', async () => { - await createServiceAgreement(); - - const blockNumber = await hre.ethers.provider.getBlockNumber(); - const blockTimestamp = (await hre.ethers.provider.getBlock(blockNumber)).timestamp; - const newBlockTimestamp = blockTimestamp + 1; - const newEpochsNumber = 10; - const newEpochLength = 15; - const newTokenAmount = hre.ethers.utils.parseEther('200'); - const newUpdateTokenAmount = hre.ethers.utils.parseEther('100'); - const newScoreFunctionId = 1; - const newProofWindowOffsetPerc = 20; - const agreementEpochSubmissionHead = '0x' + randomBytes(32).toString('hex'); - - await ServiceAgreementStorageV1U1.setAgreementStartTime(agreementId, newBlockTimestamp); - expect(await ServiceAgreementStorageV1U1.getAgreementStartTime(agreementId)).to.equal(newBlockTimestamp); - - await ServiceAgreementStorageV1U1.setAgreementEpochsNumber(agreementId, newEpochsNumber); - expect(await ServiceAgreementStorageV1U1.getAgreementEpochsNumber(agreementId)).to.equal(newEpochsNumber); - - await ServiceAgreementStorageV1U1.setAgreementEpochLength(agreementId, newEpochLength); - expect(await ServiceAgreementStorageV1U1.getAgreementEpochLength(agreementId)).to.equal(newEpochLength); - - await ServiceAgreementStorageV1U1.setAgreementTokenAmount(agreementId, newTokenAmount); - expect(await ServiceAgreementStorageV1U1.getAgreementTokenAmount(agreementId)).to.equal(newTokenAmount); - - await ServiceAgreementStorageV1U1.setAgreementUpdateTokenAmount(agreementId, newUpdateTokenAmount); - expect(await ServiceAgreementStorageV1U1.getAgreementUpdateTokenAmount(agreementId)).to.equal(newUpdateTokenAmount); - - await ServiceAgreementStorageV1U1.setAgreementScoreFunctionId(agreementId, newScoreFunctionId); - expect(await ServiceAgreementStorageV1U1.getAgreementScoreFunctionId(agreementId)).to.equal(newScoreFunctionId); - - await ServiceAgreementStorageV1U1.setAgreementProofWindowOffsetPerc(agreementId, newProofWindowOffsetPerc); - expect(await ServiceAgreementStorageV1U1.getAgreementProofWindowOffsetPerc(agreementId)).to.equal( - newProofWindowOffsetPerc, - ); - - await ServiceAgreementStorageV1U1.setAgreementEpochSubmissionHead(agreementId, 0, 0, agreementEpochSubmissionHead); - expect(await ServiceAgreementStorageV1U1.getAgreementEpochSubmissionHead(agreementId, 0, 0)).to.equal( - agreementEpochSubmissionHead, - ); - }); - - it('Should allow incrementing/decrementing/setting/deleting agreement rewarded number', async () => { - await createServiceAgreement(); - - const initialNodesNumber = await ServiceAgreementStorageV1U1.getAgreementRewardedNodesNumber(agreementId, 0); - - await ServiceAgreementStorageV1U1.incrementAgreementRewardedNodesNumber(agreementId, 0); - expect(await ServiceAgreementStorageV1U1.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal( - initialNodesNumber + 1, - ); - - await ServiceAgreementStorageV1U1.decrementAgreementRewardedNodesNumber(agreementId, 0); - expect(await ServiceAgreementStorageV1U1.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal( - initialNodesNumber, - ); - - const nodesNumber = 5; - await ServiceAgreementStorageV1U1.setAgreementRewardedNodesNumber(agreementId, 0, nodesNumber); - expect(await ServiceAgreementStorageV1U1.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal(nodesNumber); - - await ServiceAgreementStorageV1U1.deleteAgreementRewardedNodesNumber(agreementId, 0); - expect(await ServiceAgreementStorageV1U1.getAgreementRewardedNodesNumber(agreementId, 0)).to.equal(0); - }); - - it('Service agreement exists should return true for existing agreement', async () => { - await createServiceAgreement(); - - expect(await ServiceAgreementStorageV1U1.serviceAgreementExists(agreementId)).to.equal(true); - expect(await ServiceAgreementStorageV1U1.serviceAgreementExists(newAgreementId)).to.equal(false); - }); - - it('Should allow creating/deleting commit submission object', async () => { - const commitId = '0x' + randomBytes(32).toString('hex'); - const identityId = 2; - const prevIdentityId = 1; - const nextIdentityId = 3; - const score = 5; - - await ServiceAgreementStorageV1U1.createEpochStateCommitSubmissionObject( - commitId, - identityId, - prevIdentityId, - nextIdentityId, - score, - ); - let commitSubmission = await ServiceAgreementStorageV1U1.getEpochStateCommitSubmission(commitId); - - expect(commitSubmission).to.deep.equal([identityId, prevIdentityId, nextIdentityId, score]); - - await ServiceAgreementStorageV1U1.deleteEpochStateCommitSubmissionsObject(commitId); - commitSubmission = await ServiceAgreementStorageV1U1.getEpochStateCommitSubmission(commitId); - - expect(commitSubmission).to.deep.equal([0, 0, 0, 0]); - }); - - it('Should allow increasing/deacreasing/deleting epoch state commits count', async () => { - await createServiceAgreement(); - - const epochStateId = '0x' + randomBytes(32).toString('hex'); - - const initialCommitsNumber = await ServiceAgreementStorageV1U1.getEpochStateCommitsCount(epochStateId); - - await ServiceAgreementStorageV1U1.incrementEpochStateCommitsCount(epochStateId); - expect(await ServiceAgreementStorageV1U1.getEpochStateCommitsCount(epochStateId)).to.equal( - initialCommitsNumber + 1, - ); - - await ServiceAgreementStorageV1U1.decrementEpochStateCommitsCount(epochStateId); - expect(await ServiceAgreementStorageV1U1.getEpochStateCommitsCount(epochStateId)).to.equal(initialCommitsNumber); - - const commitsNumber = 5; - await ServiceAgreementStorageV1U1.setEpochStateCommitsCount(epochStateId, commitsNumber); - expect(await ServiceAgreementStorageV1U1.getEpochStateCommitsCount(epochStateId)).to.equal(commitsNumber); - - await ServiceAgreementStorageV1U1.deleteEpochStateCommitsCount(epochStateId); - expect(await ServiceAgreementStorageV1U1.getEpochStateCommitsCount(epochStateId)).to.equal(0); - }); - - it('Should allow setting/deleting update commits deadline', async () => { - await createServiceAgreement(); - - const blockNumber = await hre.ethers.provider.getBlockNumber(); - const blockTimestamp = (await hre.ethers.provider.getBlock(blockNumber)).timestamp; - - const stateId = '0x' + randomBytes(32).toString('hex'); - const deadline = blockTimestamp + 1000; - - await ServiceAgreementStorageV1U1.setUpdateCommitsDeadline(stateId, deadline); - expect(await ServiceAgreementStorageV1U1.getUpdateCommitsDeadline(stateId)).to.equal(deadline); - - await ServiceAgreementStorageV1U1.deleteUpdateCommitsDeadline(stateId); - expect(await ServiceAgreementStorageV1U1.getUpdateCommitsDeadline(stateId)).to.equal(0); - }); - - it('Should allow transferring reward', async () => { - const transferAmount = hre.ethers.utils.parseEther('100'); - const receiver = accounts[1].address; - await Token.mint(ServiceAgreementStorageV1U1.address, transferAmount); - - const initialReceiverBalance = await Token.balanceOf(receiver); - await ServiceAgreementStorageV1U1.transferAgreementTokens(receiver, transferAmount); - expect(await Token.balanceOf(receiver)).to.equal(initialReceiverBalance.add(transferAmount)); - }); -}); diff --git a/test/v1/unit/ServiceAgreementV1.test.ts b/test/v1/unit/ServiceAgreementV1.test.ts deleted file mode 100644 index 803fac73..00000000 --- a/test/v1/unit/ServiceAgreementV1.test.ts +++ /dev/null @@ -1,229 +0,0 @@ -import { randomBytes } from 'crypto'; - -import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; -import { expect } from 'chai'; -import { BigNumber } from 'ethers'; -import hre from 'hardhat'; -import { SignerWithAddress } from 'hardhat-deploy-ethers/signers'; - -import { - ContentAssetStorage, - Token, - ParametersStorage, - ServiceAgreementV1, - ServiceAgreementStorageProxy, - HubController, -} from '../../../typechain'; -import { ServiceAgreementStructsV1 } from '../../../typechain/contracts/v1/ServiceAgreementV1'; - -type ServiceAgreementV1Fixture = { - accounts: SignerWithAddress[]; - ContentAssetStorage: ContentAssetStorage; - ParametersStorage: ParametersStorage; - ServiceAgreementStorageProxy: ServiceAgreementStorageProxy; - ServiceAgreementV1: ServiceAgreementV1; - Token: Token; -}; - -describe('@v1 @unit ServiceAgreementV1 contract', function () { - let accounts: SignerWithAddress[]; - let ContentAssetStorage: ContentAssetStorage; - let ParametersStorage: ParametersStorage; - let ServiceAgreementStorageProxy: ServiceAgreementStorageProxy; - let ServiceAgreementV1: ServiceAgreementV1; - let Token: Token; - - const serviceAgreementInputArgs: ServiceAgreementStructsV1.ServiceAgreementInputArgsStruct = { - assetCreator: '', - assetContract: '', - tokenId: 1, - keyword: '0x' + randomBytes(32).toString('hex'), - hashFunctionId: 1, - epochsNumber: 10, - tokenAmount: hre.ethers.utils.parseEther('10'), - scoreFunctionId: 1, - }; - - async function createServiceAgreement(): Promise { - await Token.increaseAllowance(ServiceAgreementV1.address, serviceAgreementInputArgs.tokenAmount); - - const blockNumber = await hre.ethers.provider.getBlockNumber(); - - await expect(ServiceAgreementV1.createServiceAgreement(serviceAgreementInputArgs)) - .to.emit(ServiceAgreementV1, 'ServiceAgreementV1Created') - .withArgs( - serviceAgreementInputArgs.assetContract, - serviceAgreementInputArgs.tokenId, - serviceAgreementInputArgs.keyword, - serviceAgreementInputArgs.hashFunctionId, - (await hre.ethers.provider.getBlock(blockNumber)).timestamp + 1, - serviceAgreementInputArgs.epochsNumber, - await ParametersStorage.epochLength(), - serviceAgreementInputArgs.tokenAmount, - ); - - return hre.ethers.utils.soliditySha256( - ['address', 'uint256', 'bytes'], - [ContentAssetStorage.address, serviceAgreementInputArgs.tokenId, serviceAgreementInputArgs.keyword], - ); - } - - async function deployServiceAgreementV1Fixture(): Promise { - await hre.deployments.fixture(['ServiceAgreementStorageProxy', 'ServiceAgreementV1', 'ContentAssetStorage']); - accounts = await hre.ethers.getSigners(); - ServiceAgreementStorageProxy = await hre.ethers.getContract( - 'ServiceAgreementStorageProxy', - ); - ServiceAgreementV1 = await hre.ethers.getContract('ServiceAgreementV1'); - Token = await hre.ethers.getContract('Token'); - ParametersStorage = await hre.ethers.getContract('ParametersStorage'); - const HubController = await hre.ethers.getContract('HubController'); - ContentAssetStorage = await hre.ethers.getContract('ContentAssetStorage'); - - await HubController.setContractAddress('HubOwner', accounts[0].address); - - serviceAgreementInputArgs.assetCreator = accounts[0].address; - serviceAgreementInputArgs.assetContract = ContentAssetStorage.address; - - const ParametersStorageInterface = new hre.ethers.utils.Interface(hre.helpers.getAbi('ParametersStorage')); - HubController.forwardCall( - ParametersStorage.address, - ParametersStorageInterface.encodeFunctionData('setEpochLength', [60 * 60]), // 60 minutes - ); - HubController.forwardCall( - ParametersStorage.address, - ParametersStorageInterface.encodeFunctionData('setCommitWindowDurationPerc', [25]), // 25% (15 minutes) - ); - HubController.forwardCall( - ParametersStorage.address, - ParametersStorageInterface.encodeFunctionData('setMinProofWindowOffsetPerc', [50]), // range from 50% - ); - HubController.forwardCall( - ParametersStorage.address, - ParametersStorageInterface.encodeFunctionData('setMaxProofWindowOffsetPerc', [75]), // range to 75% - ); - HubController.forwardCall( - ParametersStorage.address, - ParametersStorageInterface.encodeFunctionData('setProofWindowDurationPerc', [25]), // 25% (15 minutes) - ); - - return { - accounts, - ContentAssetStorage, - ParametersStorage, - ServiceAgreementStorageProxy, - ServiceAgreementV1, - Token, - }; - } - - beforeEach(async () => { - hre.helpers.resetDeploymentsJson(); - ({ accounts, ContentAssetStorage, ParametersStorage, ServiceAgreementV1, Token } = await loadFixture( - deployServiceAgreementV1Fixture, - )); - }); - - it('The contract is named "ServiceAgreementV1"', async () => { - expect(await ServiceAgreementV1.name()).to.equal('ServiceAgreementV1'); - }); - - it('The contract is version "1.1.1"', async () => { - expect(await ServiceAgreementV1.version()).to.equal('1.1.1'); - }); - - it('Create old SA with valid input args; await all parameters to be set up', async () => { - await createServiceAgreement(); - }); - - it('Create old SA and terminate it, expect SA to be terminated', async () => { - const agreementId = await createServiceAgreement(); - - expect(await ServiceAgreementStorageProxy.serviceAgreementExists(agreementId)).to.eql(true); - - await expect(ServiceAgreementV1.terminateAgreement(serviceAgreementInputArgs.assetCreator, agreementId)).to.emit( - ServiceAgreementV1, - 'ServiceAgreementV1Terminated', - ); - - expect(await ServiceAgreementStorageProxy.serviceAgreementExists(agreementId)).to.eql(false); - }); - - it('Create old SA and extend storing period, expect epochs number to be increased', async () => { - const agreementId = await createServiceAgreement(); - - const oldEpochsNumber = Number(serviceAgreementInputArgs.epochsNumber); - const oldTokenAmount: BigNumber = hre.ethers.utils.parseEther( - hre.ethers.utils.formatEther(await serviceAgreementInputArgs.tokenAmount), - ); - - expect(await ServiceAgreementStorageProxy.getAgreementEpochsNumber(agreementId)).to.equal(oldEpochsNumber); - expect(await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId)).to.equal(oldTokenAmount); - - const additionalEpochsNumber = 5; - const additionalTokenAmount = hre.ethers.utils.parseEther('10'); - - await Token.increaseAllowance(ServiceAgreementV1.address, additionalTokenAmount); - await expect( - ServiceAgreementV1.extendStoringPeriod( - serviceAgreementInputArgs.assetCreator, - agreementId, - additionalEpochsNumber, - additionalTokenAmount, - ), - ).to.emit(ServiceAgreementV1, 'ServiceAgreementV1Extended'); - - expect(await ServiceAgreementStorageProxy.getAgreementEpochsNumber(agreementId)).to.equal( - oldEpochsNumber + additionalEpochsNumber, - ); - expect(await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId)).to.equal( - oldTokenAmount.add(additionalTokenAmount), - ); - }); - - it('Create old SA and add tokens, expect token amount to be increased', async () => { - const agreementId = await createServiceAgreement(); - - const oldTokenAmount: BigNumber = hre.ethers.utils.parseEther( - hre.ethers.utils.formatEther(await serviceAgreementInputArgs.tokenAmount), - ); - - expect(await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId)).to.equal(oldTokenAmount); - - const additionalTokenAmount = hre.ethers.utils.parseEther('10'); - - await Token.increaseAllowance(ServiceAgreementV1.address, additionalTokenAmount); - await expect( - ServiceAgreementV1.addTokens(serviceAgreementInputArgs.assetCreator, agreementId, additionalTokenAmount), - ).to.emit(ServiceAgreementV1, 'ServiceAgreementV1RewardRaised'); - - expect(await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId)).to.equal( - oldTokenAmount.add(additionalTokenAmount), - ); - }); - - it('Create old SA and add update tokens, expect update token amount to be increased', async () => { - const agreementId = await createServiceAgreement(); - - const oldUpdateTokenAmount: BigNumber = hre.ethers.utils.parseEther('0'); - - expect(await ServiceAgreementStorageProxy.getAgreementUpdateTokenAmount(agreementId)).to.equal( - oldUpdateTokenAmount, - ); - - const additionalUpdateTokenAmount = hre.ethers.utils.parseEther('10'); - - await Token.increaseAllowance(ServiceAgreementV1.address, additionalUpdateTokenAmount); - await expect( - ServiceAgreementV1.addUpdateTokens( - serviceAgreementInputArgs.assetCreator, - agreementId, - additionalUpdateTokenAmount, - ), - ).to.emit(ServiceAgreementV1, 'ServiceAgreementV1UpdateRewardRaised'); - - expect(await ServiceAgreementStorageProxy.getAgreementTokenAmount(agreementId)).to.equal( - oldUpdateTokenAmount.add(additionalUpdateTokenAmount), - ); - }); -}); diff --git a/test/v1/unit/UnfinalizedStateStorage.test.ts b/test/v1/unit/UnfinalizedStateStorage.test.ts deleted file mode 100644 index 1c00db4d..00000000 --- a/test/v1/unit/UnfinalizedStateStorage.test.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; -import { expect } from 'chai'; -import hre from 'hardhat'; -import { SignerWithAddress } from 'hardhat-deploy-ethers/signers'; - -import { HubController, UnfinalizedStateStorage } from '../../../typechain'; -import { ZERO_ADDRESS, ZERO_BYTES32 } from '../../helpers/constants'; - -type UnfinalizedStateStorageFixture = { - accounts: SignerWithAddress[]; - UnfinalizedStateStorage: UnfinalizedStateStorage; -}; - -describe('@v1 @unit UnfinalizedStateStorage contract', function () { - let accounts: SignerWithAddress[]; - let UnfinalizedStateStorage: UnfinalizedStateStorage; - const assertionId = '0x8cc2117b68bcbb1535205d517cb42ef45f25838add571fce4cfb7de7bd617943'; - - async function deployUnfinalizedStateStorageFixture(): Promise { - await hre.deployments.fixture(['UnfinalizedStateStorage']); - UnfinalizedStateStorage = await hre.ethers.getContract('UnfinalizedStateStorage'); - accounts = await hre.ethers.getSigners(); - const HubController = await hre.ethers.getContract('HubController'); - await HubController.setContractAddress('HubOwner', accounts[0].address); - - return { accounts, UnfinalizedStateStorage }; - } - - beforeEach(async () => { - hre.helpers.resetDeploymentsJson(); - ({ accounts, UnfinalizedStateStorage } = await loadFixture(deployUnfinalizedStateStorageFixture)); - }); - - it('The contract is named "UnfinalizedStateStorage"', async () => { - expect(await UnfinalizedStateStorage.name()).to.equal('UnfinalizedStateStorage'); - }); - - it('The contract is version "1.0.0"', async () => { - expect(await UnfinalizedStateStorage.version()).to.equal('1.0.0'); - }); - - it('Set and get new unfinalized state, expect to get state', async () => { - await UnfinalizedStateStorage.setUnfinalizedState(0, assertionId); - - expect(await UnfinalizedStateStorage.getUnfinalizedState(0)).to.equal(assertionId); - }); - - it('Set and delete unfinalized state, expect state to be deleted', async () => { - await UnfinalizedStateStorage.setUnfinalizedState(0, assertionId); - await UnfinalizedStateStorage.deleteUnfinalizedState(0); - - expect(await UnfinalizedStateStorage.getUnfinalizedState(0)).to.equal(ZERO_BYTES32); - }); - - it('Set and get new issuer, expect to get issuer', async () => { - await UnfinalizedStateStorage.setIssuer(0, accounts[0].address); - - expect(await UnfinalizedStateStorage.getIssuer(0)).to.equal(accounts[0].address); - }); - - it('Set and delete issuer, expect issuer to be deleted', async () => { - await UnfinalizedStateStorage.setIssuer(0, accounts[0].address); - await UnfinalizedStateStorage.deleteIssuer(0); - - expect(await UnfinalizedStateStorage.getIssuer(0)).to.equal(ZERO_ADDRESS); - }); - - it('Set new unfinalized state and check if there is a pending state, expect true', async () => { - await UnfinalizedStateStorage.setUnfinalizedState(0, assertionId); - - expect(await UnfinalizedStateStorage.hasPendingUpdate(0)).to.equal(true); - }); - - it('Check if there is a pending state, expect false', async () => { - expect(await UnfinalizedStateStorage.hasPendingUpdate(0)).to.equal(false); - }); -}); diff --git a/test/v2/unit/CommitManagerV2.test.ts b/test/v2/unit/CommitManagerV2.test.ts deleted file mode 100644 index 5306c31f..00000000 --- a/test/v2/unit/CommitManagerV2.test.ts +++ /dev/null @@ -1,513 +0,0 @@ -import { randomBytes } from 'crypto'; - -import { loadFixture, time } from '@nomicfoundation/hardhat-network-helpers'; -import { expect } from 'chai'; -import { BytesLike, BigNumber } from 'ethers'; -import hre from 'hardhat'; -import { SignerWithAddress } from 'hardhat-deploy-ethers/signers'; - -import { - CommitManagerV2, - ContentAssetV2, - ContentAssetStorageV2, - LinearSum, - ParametersStorage, - Profile, - ProfileStorage, - ServiceAgreementV1, - StakingV2, - Token, -} from '../../../typechain'; -import { ContentAssetStructs } from '../../../typechain/contracts/v1/assets/ContentAsset'; -import { ServiceAgreementStructsV1 } from '../../../typechain/contracts/v1/CommitManagerV1'; -import { ServiceAgreementStructsV2 } from '../../../typechain/contracts/v2/CommitManagerV1.sol/CommitManagerV2'; - -type CommitManagerV2Fixture = { - accounts: SignerWithAddress[]; - CommitManagerV2: CommitManagerV2; -}; - -type Node = { - account: SignerWithAddress; - identityId: number; - nodeId: BytesLike; - sha256: BytesLike; - stake: BigNumber; -}; - -type NodeWithDistance = { - account: SignerWithAddress; - identityId: number; - nodeId: BytesLike; - sha256: BytesLike; - stake: BigNumber; - index: BigNumber; - distance: BigNumber; -}; - -describe('@v2 @unit CommitManagerV2 contract', function () { - const HASH_RING_SIZE = BigNumber.from(2).pow(256).sub(1); - const UINT256_MAX_BN = BigNumber.from(2).pow(256).sub(1); - const UINT64_MAX_BN = BigNumber.from(2).pow(64).sub(1); - const UINT40_MAX_BN = BigNumber.from(2).pow(40).sub(1); - - let accounts: SignerWithAddress[]; - let Token: Token; - let ServiceAgreementV1: ServiceAgreementV1; - let ContentAssetV2: ContentAssetV2; - let ContentAssetStorageV2: ContentAssetStorageV2; - let LinearSum: LinearSum; - let CommitManagerV2: CommitManagerV2; - let ParametersStorage: ParametersStorage; - let ProfileStorage: ProfileStorage; - let Profile: Profile; - let StakingV2: StakingV2; - - let commitV1InputArgs: ServiceAgreementStructsV1.CommitInputArgsStruct; - let commitV2InputArgs: ServiceAgreementStructsV2.CommitInputArgsStruct; - - async function createAsset( - scoreFunctionId = 1, - ): Promise<{ tokenId: number; keyword: BytesLike; agreementId: BytesLike }> { - const assetInputStruct: ContentAssetStructs.AssetInputArgsStruct = { - assertionId: '0x' + randomBytes(32).toString('hex'), - size: 1000, - triplesNumber: 10, - chunksNumber: 10, - epochsNumber: 5, - tokenAmount: hre.ethers.utils.parseEther('250'), - scoreFunctionId, - immutable_: false, - }; - - await Token.increaseAllowance(ServiceAgreementV1.address, assetInputStruct.tokenAmount); - const receipt = await (await ContentAssetV2.createAsset(assetInputStruct)).wait(); - - const tokenId = Number(receipt.logs[0].topics[3]); - const keyword = hre.ethers.utils.solidityPack( - ['address', 'bytes32'], - [ContentAssetStorageV2.address, assetInputStruct.assertionId], - ); - const agreementId = hre.ethers.utils.soliditySha256( - ['address', 'uint256', 'bytes'], - [ContentAssetStorageV2.address, tokenId, keyword], - ); - - return { tokenId, keyword, agreementId }; - } - - async function createProfile(operational: SignerWithAddress, admin: SignerWithAddress): Promise { - const OperationalProfile = Profile.connect(operational); - - const nodeId = '0x' + randomBytes(32).toString('hex'); - const sha256 = hre.ethers.utils.soliditySha256(['bytes'], [nodeId]); - - const receipt = await ( - await OperationalProfile.createProfile( - admin.address, - [], - nodeId, - randomBytes(5).toString('hex'), - randomBytes(3).toString('hex'), - 0, - ) - ).wait(); - const identityId = Number(receipt.logs[0].topics[1]); - const blockchainNodeId = await ProfileStorage.getNodeId(identityId); - const blockchainSha256 = await ProfileStorage.getNodeAddress(identityId, 1); - - expect(blockchainNodeId).to.be.equal(nodeId); - expect(blockchainSha256).to.be.equal(sha256); - - await OperationalProfile.setAsk(identityId, hre.ethers.utils.parseEther('0.25')); - - const minStake = Number(hre.ethers.utils.formatEther(await ParametersStorage.minimumStake())); - const maxStake = Number(hre.ethers.utils.formatEther(await ParametersStorage.maximumStake())); - const stakeAmount = hre.ethers.utils.parseEther( - `${Math.floor(Math.random() * (maxStake - minStake + 1)) + minStake}`, - ); - await Token.connect(admin).increaseAllowance(StakingV2.address, stakeAmount); - await StakingV2.connect(admin)['addStake(uint72,uint96)'](identityId, stakeAmount); - - return { - account: operational, - identityId, - nodeId, - sha256, - stake: stakeAmount, - }; - } - - async function createMultipleProfiles(count = 150): Promise { - const nodes = []; - - for (let i = 0; i < count; i++) { - const node = await createProfile(accounts[i], accounts[i + count]); - nodes.push(node); - } - - return nodes; - } - - function calculateDistance(peerHash: BytesLike, keyHash: BytesLike): BigNumber { - const peerPositionOnHashRing = BigNumber.from(peerHash); - const keyPositionOnHashRing = BigNumber.from(keyHash); - - const directDistance = peerPositionOnHashRing.gt(keyPositionOnHashRing) - ? peerPositionOnHashRing.sub(keyPositionOnHashRing) - : keyPositionOnHashRing.sub(peerPositionOnHashRing); - const wraparoundDistance = HASH_RING_SIZE.sub(directDistance); - - return directDistance.lt(wraparoundDistance) ? directDistance : wraparoundDistance; - } - - function toUint40(value: BigNumber, maxValue: BigNumber): BigNumber { - const result = value.mul(UINT40_MAX_BN).div(maxValue); - return result; - } - - async function calculateScore( - distance: BigNumber, - stake: BigNumber, - maxNeighborhoodDistance: BigNumber, - r2: number, - nodesNumber: number, - minStake: BigNumber, - maxStake: BigNumber, - ): Promise { - const linearSumParams = await LinearSum.getParameters(); - const [distanceScaleFactor, stakeScaleFactor, w1, w2] = linearSumParams; - - const idealMaxDistanceInNeighborhood = HASH_RING_SIZE.div(nodesNumber).mul(Math.ceil(r2 / 2)); - const divisor = - maxNeighborhoodDistance <= idealMaxDistanceInNeighborhood - ? maxNeighborhoodDistance - : idealMaxDistanceInNeighborhood; - - const maxMultiplier = UINT256_MAX_BN.div(distance); - - let scaledDistanceScaleFactor = distanceScaleFactor; - let compensationFactor = BigNumber.from(1); - - if (scaledDistanceScaleFactor.gt(maxMultiplier)) { - compensationFactor = scaledDistanceScaleFactor.div(maxMultiplier); - scaledDistanceScaleFactor = maxMultiplier; - } - - const scaledDistance = distance.mul(scaledDistanceScaleFactor); - const adjustedDivisor = divisor.div(compensationFactor); - - let normalizedDistance = scaledDistance.div(adjustedDivisor); - if (normalizedDistance.gt(UINT64_MAX_BN)) { - normalizedDistance = normalizedDistance.mod(UINT64_MAX_BN.add(1)); - } - - let normalizedStake = stakeScaleFactor.mul(stake.sub(minStake)).div(maxStake.sub(minStake)); - if (normalizedStake.gt(UINT64_MAX_BN)) { - normalizedStake = normalizedStake.mod(UINT64_MAX_BN.add(1)); - } - - const oneEther = BigNumber.from('1000000000000000000'); - - const isProximityScorePositive = oneEther.gte(normalizedDistance); - - const proximityScore = isProximityScorePositive - ? oneEther.sub(normalizedDistance).mul(w1) - : normalizedDistance.sub(oneEther).mul(w1); - const stakeScore = normalizedStake.mul(w2); - - let finalScore; - if (isProximityScorePositive) { - finalScore = proximityScore.add(stakeScore); - } else if (stakeScore.gte(proximityScore)) { - finalScore = stakeScore.sub(proximityScore); - } else { - finalScore = BigNumber.from(0); - } - - finalScore = toUint40(finalScore, oneEther.mul(w1 + w2)); - - return finalScore; - } - - async function getNeighborhood(nodes: Node[], keyHash: BytesLike): Promise { - const nodesWithIndexes = nodes - .sort((a, b) => { - const aBN = BigNumber.from(a.sha256); - const bBN = BigNumber.from(b.sha256); - if (aBN.eq(bBN)) { - return 0; - } - return aBN.lt(bBN) ? -1 : 1; - }) - .map((node, index) => ({ ...node, index: BigNumber.from(index) })); - - const nodesWithDistance = await Promise.all( - nodesWithIndexes.map(async (node) => ({ - node, - distance: calculateDistance(node.sha256, keyHash), - })), - ); - nodesWithDistance.sort((a, b) => { - if (a.distance.eq(b.distance)) { - return 0; - } - return a.distance.lt(b.distance) ? -1 : 1; - }); - return nodesWithDistance.slice(0, 20).map((pd) => ({ ...pd.node, distance: pd.distance })); - } - - async function getNeighborhoodEdgeNodes( - neighborhood: NodeWithDistance[], - keyHash: BytesLike, - ): Promise<{ leftEdgeNode: NodeWithDistance; rightEdgeNode: NodeWithDistance }> { - const assetPositionOnHashRing = BigNumber.from(keyHash); - const hashRing = []; - - const maxDistance = neighborhood[neighborhood.length - 1].distance; - - for (const neighbor of neighborhood) { - const neighborPositionOnHashRing = BigNumber.from(neighbor.sha256); - - if (neighborPositionOnHashRing.lte(assetPositionOnHashRing)) { - if (assetPositionOnHashRing.sub(neighborPositionOnHashRing).lte(maxDistance)) { - hashRing.unshift(neighbor); - } else { - hashRing.push(neighbor); - } - } else { - if (neighborPositionOnHashRing.sub(assetPositionOnHashRing).lte(maxDistance)) { - hashRing.push(neighbor); - } else { - hashRing.unshift(neighbor); - } - } - } - - return { - leftEdgeNode: hashRing[0], - rightEdgeNode: hashRing[hashRing.length - 1], - }; - } - - async function deployCommitManagerV2Fixture(): Promise { - await hre.deployments.fixture([ - 'HubV2', - 'ContentAssetStorageV2', - 'ShardingTableV2', - 'StakingV2', - 'CommitManagerV2', - 'CommitManagerV2U1', - 'ContentAssetV2', - 'Profile', - ]); - Token = await hre.ethers.getContract('Token'); - ServiceAgreementV1 = await hre.ethers.getContract('ServiceAgreementV1'); - ContentAssetV2 = await hre.ethers.getContract('ContentAsset'); - ContentAssetStorageV2 = await hre.ethers.getContract('ContentAssetStorage'); - LinearSum = await hre.ethers.getContract('LinearSum'); - CommitManagerV2 = await hre.ethers.getContract('CommitManagerV1'); - ParametersStorage = await hre.ethers.getContract('ParametersStorage'); - ProfileStorage = await hre.ethers.getContract('ProfileStorage'); - Profile = await hre.ethers.getContract('Profile'); - StakingV2 = await hre.ethers.getContract('Staking'); - accounts = await hre.ethers.getSigners(); - - return { accounts, CommitManagerV2 }; - } - - beforeEach(async () => { - hre.helpers.resetDeploymentsJson(); - ({ accounts, CommitManagerV2 } = await loadFixture(deployCommitManagerV2Fixture)); - }); - - it('The contract is named "CommitManagerV1"', async () => { - expect(await CommitManagerV2.name()).to.equal('CommitManagerV1'); - }); - - it('The contract is version "2.0.0"', async () => { - expect(await CommitManagerV2.version()).to.equal('2.0.0'); - }); - - it('Create new asset, check if commit window is open, expect to be true', async () => { - const { agreementId } = await createAsset(); - - expect(await CommitManagerV2.isCommitWindowOpen(agreementId, 0)).to.eql(true); - }); - - it('Create new asset, teleport to the end of commit phase and check if commit window is open, expect to be false', async () => { - const { agreementId } = await createAsset(); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const commitWindowDurationPerc = await ParametersStorage.commitWindowDurationPerc(); - const commitWindowDuration = (epochLength * commitWindowDurationPerc) / 100; - - await time.increase(commitWindowDuration + 1); - - expect(await CommitManagerV2.isCommitWindowOpen(agreementId, 0)).to.eql(false); - }); - - it('Create new asset, teleport to second epoch and check if commit window is open, expect to be true', async () => { - const { agreementId } = await createAsset(); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - await time.increase(epochLength); - - expect(await CommitManagerV2.isCommitWindowOpen(agreementId, 1)).to.eql(true); - }); - - it('Create new asset with scoreFunction 1, submit commit V1, expect revert InvalidScoreFunctionId', async () => { - await createProfile(accounts[0], accounts[1]); - - const { tokenId, keyword } = await createAsset(); - - commitV1InputArgs = { - assetContract: ContentAssetStorageV2.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - }; - - await expect( - CommitManagerV2['submitCommit((address,uint256,bytes,uint8,uint16))'](commitV1InputArgs), - ).to.be.revertedWithCustomError(CommitManagerV2, 'InvalidScoreFunctionId'); - }); - - it('Create new asset with scoreFunction 2, submit commit V2, expect CommitSubmitted event', async () => { - const nodes = await createMultipleProfiles(30); - - const { tokenId, keyword } = await createAsset(2); - - const keyHash = hre.ethers.utils.soliditySha256(['bytes'], [keyword]); - - const neighborhood = await getNeighborhood(nodes, keyHash); - - const closestNode = neighborhood[0]; - const { leftEdgeNode, rightEdgeNode } = await getNeighborhoodEdgeNodes(neighborhood, keyHash); - - commitV2InputArgs = { - assetContract: ContentAssetStorageV2.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - closestNodeIndex: closestNode.index, - leftEdgeNodeIndex: leftEdgeNode.index, - rightEdgeNodeIndex: rightEdgeNode.index, - }; - - const r2 = await ParametersStorage.r2(); - const minStake = await ParametersStorage.minimumStake(); - const maxStake = await ParametersStorage.maximumStake(); - const score = await calculateScore( - closestNode.distance, - closestNode.stake, - neighborhood[neighborhood.length - 1].distance, - r2, - nodes.length, - minStake, - maxStake, - ); - - await expect( - CommitManagerV2.connect(closestNode.account)[ - 'submitCommit((address,uint256,bytes,uint8,uint16,uint72,uint72,uint72))' - ](commitV2InputArgs), - ) - .to.emit(CommitManagerV2, 'CommitSubmitted') - .withArgs(ContentAssetStorageV2.address, tokenId, keyword, 1, 0, closestNode.identityId, score); - }); - - it('Create new asset with scoreFunction 1, submit R0 V1 commits, expect R0 V1 commits to be reverted with InvalidScoreFunctionId', async () => { - const r0 = await ParametersStorage.r0(); - - const identityIds = []; - for (let i = 0; i < r0; i++) { - const { identityId } = await createProfile(accounts[i], accounts[accounts.length - 1]); - identityIds.push(identityId); - } - - const { tokenId, keyword } = await createAsset(); - - commitV1InputArgs = { - assetContract: ContentAssetStorageV2.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - }; - - for (let i = 0; i < r0; i++) { - await expect( - CommitManagerV2.connect(accounts[i])['submitCommit((address,uint256,bytes,uint8,uint16))'](commitV1InputArgs), - ).to.be.revertedWithCustomError(CommitManagerV2, 'InvalidScoreFunctionId'); - } - }); - - it('Create new asset with scoreFunction 2, submit R0 V2 commits, expect R0 V2 commits to be returned', async () => { - const r0 = await ParametersStorage.r0(); - const r2 = await ParametersStorage.r2(); - const minStake = await ParametersStorage.minimumStake(); - const maxStake = await ParametersStorage.maximumStake(); - const nodes = await createMultipleProfiles(30); - - const { tokenId, keyword, agreementId } = await createAsset(2); - - const keyHash = hre.ethers.utils.soliditySha256(['bytes'], [keyword]); - - const neighborhood = await getNeighborhood(nodes, keyHash); - - const closestNode = neighborhood[0]; - const { leftEdgeNode, rightEdgeNode } = await getNeighborhoodEdgeNodes(neighborhood, keyHash); - - commitV2InputArgs = { - assetContract: ContentAssetStorageV2.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - closestNodeIndex: closestNode.index, - leftEdgeNodeIndex: leftEdgeNode.index, - rightEdgeNodeIndex: rightEdgeNode.index, - }; - - const scoredNeighborhood = await Promise.all( - neighborhood.map(async (node) => ({ - account: node.account, - identityId: node.identityId, - score: ( - await calculateScore( - node.distance, - node.stake, - neighborhood[neighborhood.length - 1].distance, - r2, - nodes.length, - minStake, - maxStake, - ) - ).toNumber(), - })), - ); - - scoredNeighborhood.sort((a, b) => b.score - a.score); - - for (const node of [...scoredNeighborhood].reverse()) { - await expect( - CommitManagerV2.connect(node.account)[ - 'submitCommit((address,uint256,bytes,uint8,uint16,uint72,uint72,uint72))' - ](commitV2InputArgs), - ) - .to.emit(CommitManagerV2, 'CommitSubmitted') - .withArgs(ContentAssetStorageV2.address, tokenId, keyword, 1, 0, node.identityId, node.score); - } - - const topCommits = await CommitManagerV2.getTopCommitSubmissions(agreementId, 0); - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const expectedWinners = scoredNeighborhood.map(({ account, ...rest }) => rest).slice(0, r0); - - expect( - topCommits.map((commit) => ({ identityId: commit.identityId.toNumber(), score: commit.score })), - ).to.have.deep.members(expectedWinners); - }); -}); diff --git a/test/v2/unit/CommitManagerV2U1.test.ts b/test/v2/unit/CommitManagerV2U1.test.ts deleted file mode 100644 index c9975818..00000000 --- a/test/v2/unit/CommitManagerV2U1.test.ts +++ /dev/null @@ -1,713 +0,0 @@ -import { randomBytes } from 'crypto'; - -import { loadFixture, time } from '@nomicfoundation/hardhat-network-helpers'; -import { expect } from 'chai'; -import { BytesLike, BigNumber } from 'ethers'; -import hre from 'hardhat'; -import { SignerWithAddress } from 'hardhat-deploy-ethers/signers'; - -import { - CommitManagerV2, - CommitManagerV2U1, - ContentAssetV2, - ContentAssetStorageV2, - LinearSum, - ParametersStorage, - Profile, - ProfileStorage, - ServiceAgreementV1, - StakingV2, - Token, -} from '../../../typechain'; -import { ContentAssetStructs } from '../../../typechain/contracts/v1/assets/ContentAsset'; -import { ServiceAgreementStructsV1 } from '../../../typechain/contracts/v1/CommitManagerV1U1'; -import { ServiceAgreementStructsV2 } from '../../../typechain/contracts/v2/CommitManagerV1U1.sol/CommitManagerV2U1'; - -const UINT256_MAX_BN = BigNumber.from(2).pow(256).sub(1); -const UINT64_MAX_BN = BigNumber.from(2).pow(64).sub(1); -const UINT40_MAX_BN = BigNumber.from(2).pow(40).sub(1); - -type CommitManagerV2U1Fixture = { - accounts: SignerWithAddress[]; - CommitManagerV2: CommitManagerV2; - CommitManagerV2U1: CommitManagerV2U1; -}; - -type Node = { - account: SignerWithAddress; - identityId: number; - nodeId: BytesLike; - sha256: BytesLike; - stake: BigNumber; -}; - -type NodeWithDistance = { - account: SignerWithAddress; - identityId: number; - nodeId: BytesLike; - sha256: BytesLike; - stake: BigNumber; - index: BigNumber; - distance: BigNumber; -}; - -describe('@v2 @unit CommitManagerV2U1 contract', function () { - const HASH_RING_SIZE = BigNumber.from(2).pow(256); - - let accounts: SignerWithAddress[]; - let Token: Token; - let ServiceAgreementV1: ServiceAgreementV1; - let ContentAssetV2: ContentAssetV2; - let ContentAssetStorageV2: ContentAssetStorageV2; - let LinearSum: LinearSum; - let CommitManagerV2: CommitManagerV2; - let CommitManagerV2U1: CommitManagerV2U1; - let ParametersStorage: ParametersStorage; - let ProfileStorage: ProfileStorage; - let Profile: Profile; - let StakingV2: StakingV2; - - let commitV1InputArgs: ServiceAgreementStructsV1.CommitInputArgsStruct; - let commitV2InputArgs: ServiceAgreementStructsV2.CommitInputArgsStruct; - - async function createAsset( - scoreFunctionId = 1, - ): Promise<{ tokenId: number; keyword: BytesLike; agreementId: BytesLike }> { - const assetInputStruct: ContentAssetStructs.AssetInputArgsStruct = { - assertionId: '0x' + randomBytes(32).toString('hex'), - size: 1000, - triplesNumber: 10, - chunksNumber: 10, - epochsNumber: 5, - tokenAmount: hre.ethers.utils.parseEther('250'), - scoreFunctionId, - immutable_: false, - }; - - await Token.increaseAllowance(ServiceAgreementV1.address, assetInputStruct.tokenAmount); - const receipt = await (await ContentAssetV2.createAsset(assetInputStruct)).wait(); - - const tokenId = Number(receipt.logs[0].topics[3]); - const keyword = hre.ethers.utils.solidityPack( - ['address', 'bytes32'], - [ContentAssetStorageV2.address, assetInputStruct.assertionId], - ); - const agreementId = hre.ethers.utils.soliditySha256( - ['address', 'uint256', 'bytes'], - [ContentAssetStorageV2.address, tokenId, keyword], - ); - - return { tokenId, keyword, agreementId }; - } - - async function updateAsset(tokenId: number) { - const assetUpdateArgs = { - assertionId: '0x' + randomBytes(32).toString('hex'), - size: 2000, - triplesNumber: 20, - chunksNumber: 20, - tokenAmount: hre.ethers.utils.parseEther('500'), - }; - - await Token.increaseAllowance(ServiceAgreementV1.address, assetUpdateArgs.tokenAmount); - await ContentAssetV2.updateAssetState( - tokenId, - assetUpdateArgs.assertionId, - assetUpdateArgs.size, - assetUpdateArgs.triplesNumber, - assetUpdateArgs.chunksNumber, - assetUpdateArgs.tokenAmount, - ); - } - - async function finalizeUpdateV2( - tokenId: number, - keyword: BytesLike, - ): Promise<{ - winners: { account: SignerWithAddress; identityId: number; score: number }[]; - closestNodeIndex: BigNumber; - leftEdgeNodeIndex: BigNumber; - rightEdgeNodeIndex: BigNumber; - }> { - const finalizationRequirement = await ParametersStorage.finalizationCommitsNumber(); - - const r2 = await ParametersStorage.r2(); - const minStake = await ParametersStorage.minimumStake(); - const maxStake = await ParametersStorage.maximumStake(); - const nodes = await createMultipleProfiles(30); - - const keyHash = hre.ethers.utils.soliditySha256(['bytes'], [keyword]); - - const neighborhood = await getNeighborhood(nodes, keyHash); - - const closestNode = neighborhood[0]; - const { leftEdgeNode, rightEdgeNode } = await getNeighborhoodEdgeNodes(neighborhood, keyHash); - - commitV2InputArgs = { - assetContract: ContentAssetStorageV2.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - closestNodeIndex: closestNode.index, - leftEdgeNodeIndex: leftEdgeNode.index, - rightEdgeNodeIndex: rightEdgeNode.index, - }; - - const scoredNeighborhood = await Promise.all( - neighborhood.map(async (node) => ({ - account: node.account, - identityId: node.identityId, - score: ( - await calculateScore( - node.distance, - node.stake, - neighborhood[neighborhood.length - 1].distance, - r2, - nodes.length, - minStake, - maxStake, - ) - ).toNumber(), - })), - ); - - scoredNeighborhood.sort((a, b) => a.score - b.score); - - for (let i = 0; i < finalizationRequirement; i++) { - await expect( - CommitManagerV2U1.connect(scoredNeighborhood[i].account)[ - 'submitUpdateCommit((address,uint256,bytes,uint8,uint16,uint72,uint72,uint72))' - ](commitV2InputArgs), - ).to.emit(CommitManagerV2U1, 'CommitSubmitted'); - } - - return { - winners: scoredNeighborhood.slice(0, finalizationRequirement), - closestNodeIndex: closestNode.index, - leftEdgeNodeIndex: leftEdgeNode.index, - rightEdgeNodeIndex: rightEdgeNode.index, - }; - } - - async function createProfile(operational: SignerWithAddress, admin: SignerWithAddress): Promise { - const { minter } = await hre.getNamedAccounts(); - const OperationalProfile = Profile.connect(operational); - - const nodeId = '0x' + randomBytes(32).toString('hex'); - const sha256 = hre.ethers.utils.soliditySha256(['bytes'], [nodeId]); - - const receipt = await ( - await OperationalProfile.createProfile( - admin.address, - [], - nodeId, - randomBytes(5).toString('hex'), - randomBytes(3).toString('hex'), - 0, - ) - ).wait(); - const identityId = Number(receipt.logs[0].topics[1]); - const blockchainNodeId = await ProfileStorage.getNodeId(identityId); - const blockchainSha256 = await ProfileStorage.getNodeAddress(identityId, 1); - - expect(blockchainNodeId).to.be.equal(nodeId); - expect(blockchainSha256).to.be.equal(sha256); - - await OperationalProfile.setAsk(identityId, hre.ethers.utils.parseEther('0.25')); - - const minStake = Number(hre.ethers.utils.formatEther(await ParametersStorage.minimumStake())); - const maxStake = Number(hre.ethers.utils.formatEther(await ParametersStorage.maximumStake())); - const stakeAmount = hre.ethers.utils.parseEther( - `${Math.floor(Math.random() * (maxStake - minStake + 1)) + minStake}`, - ); - await Token.mint(admin.address, stakeAmount, { from: minter }); - await Token.connect(admin).increaseAllowance(StakingV2.address, stakeAmount); - await StakingV2.connect(admin)['addStake(uint72,uint96)'](identityId, stakeAmount); - - return { - account: operational, - identityId, - nodeId, - sha256, - stake: stakeAmount, - }; - } - - async function createMultipleProfiles(count = 150): Promise { - const nodes = []; - - for (let i = 0; i < count; i++) { - const node = await createProfile(accounts[i], accounts[i + count]); - nodes.push(node); - } - - return nodes; - } - - function calculateDistance(peerHash: BytesLike, keyHash: BytesLike): BigNumber { - const peerPositionOnHashRing = BigNumber.from(peerHash); - const keyPositionOnHashRing = BigNumber.from(keyHash); - - const directDistance = peerPositionOnHashRing.gt(keyPositionOnHashRing) - ? peerPositionOnHashRing.sub(keyPositionOnHashRing) - : keyPositionOnHashRing.sub(peerPositionOnHashRing); - const wraparoundDistance = HASH_RING_SIZE.sub(directDistance); - - return directDistance.lt(wraparoundDistance) ? directDistance : wraparoundDistance; - } - - function toUint40(value: BigNumber, maxValue: BigNumber): BigNumber { - const result = value.mul(UINT40_MAX_BN).div(maxValue); - return result; - } - - async function calculateScore( - distance: BigNumber, - stake: BigNumber, - maxNeighborhoodDistance: BigNumber, - r2: number, - nodesNumber: number, - minStake: BigNumber, - maxStake: BigNumber, - ): Promise { - const linearSumParams = await LinearSum.getParameters(); - const [distanceScaleFactor, stakeScaleFactor, w1, w2] = linearSumParams; - - const idealMaxDistanceInNeighborhood = HASH_RING_SIZE.div(nodesNumber).mul(Math.ceil(r2 / 2)); - const divisor = - maxNeighborhoodDistance <= idealMaxDistanceInNeighborhood - ? maxNeighborhoodDistance - : idealMaxDistanceInNeighborhood; - - const maxMultiplier = UINT256_MAX_BN.div(distance); - - let scaledDistanceScaleFactor = distanceScaleFactor; - let compensationFactor = BigNumber.from(1); - - if (scaledDistanceScaleFactor.gt(maxMultiplier)) { - compensationFactor = scaledDistanceScaleFactor.div(maxMultiplier); - scaledDistanceScaleFactor = maxMultiplier; - } - - const scaledDistance = distance.mul(scaledDistanceScaleFactor); - const adjustedDivisor = divisor.div(compensationFactor); - - let normalizedDistance = scaledDistance.div(adjustedDivisor); - if (normalizedDistance.gt(UINT64_MAX_BN)) { - normalizedDistance = normalizedDistance.mod(UINT64_MAX_BN.add(1)); - } - - let normalizedStake = stakeScaleFactor.mul(stake.sub(minStake)).div(maxStake.sub(minStake)); - if (normalizedStake.gt(UINT64_MAX_BN)) { - normalizedStake = normalizedStake.mod(UINT64_MAX_BN.add(1)); - } - - const oneEther = BigNumber.from('1000000000000000000'); - - const isProximityScorePositive = oneEther.gte(normalizedDistance); - - const proximityScore = isProximityScorePositive - ? oneEther.sub(normalizedDistance).mul(w1) - : normalizedDistance.sub(oneEther).mul(w1); - const stakeScore = normalizedStake.mul(w2); - - let finalScore; - if (isProximityScorePositive) { - finalScore = proximityScore.add(stakeScore); - } else if (stakeScore.gte(proximityScore)) { - finalScore = stakeScore.sub(proximityScore); - } else { - finalScore = BigNumber.from(0); - } - - finalScore = toUint40(finalScore, oneEther.mul(w1 + w2)); - - return finalScore; - } - - async function getNeighborhood(nodes: Node[], keyHash: BytesLike): Promise { - const nodesWithIndexes = nodes - .sort((a, b) => { - const aBN = BigNumber.from(a.sha256); - const bBN = BigNumber.from(b.sha256); - if (aBN.eq(bBN)) { - return 0; - } - return aBN.lt(bBN) ? -1 : 1; - }) - .map((node, index) => ({ ...node, index: BigNumber.from(index) })); - - const nodesWithDistance = await Promise.all( - nodesWithIndexes.map(async (node) => ({ - node, - distance: calculateDistance(node.sha256, keyHash), - })), - ); - nodesWithDistance.sort((a, b) => { - if (a.distance.eq(b.distance)) { - return 0; - } - return a.distance.lt(b.distance) ? -1 : 1; - }); - return nodesWithDistance.slice(0, 20).map((pd) => ({ ...pd.node, distance: pd.distance })); - } - - async function getNeighborhoodEdgeNodes( - neighborhood: NodeWithDistance[], - keyHash: BytesLike, - ): Promise<{ leftEdgeNode: NodeWithDistance; rightEdgeNode: NodeWithDistance }> { - const assetPositionOnHashRing = BigNumber.from(keyHash); - const hashRing = []; - - const maxDistance = neighborhood[neighborhood.length - 1].distance; - - for (const neighbor of neighborhood) { - const neighborPositionOnHashRing = BigNumber.from(neighbor.sha256); - - if (neighborPositionOnHashRing.lte(assetPositionOnHashRing)) { - if (assetPositionOnHashRing.sub(neighborPositionOnHashRing).lte(maxDistance)) { - hashRing.unshift(neighbor); - } else { - hashRing.push(neighbor); - } - } else { - if (neighborPositionOnHashRing.sub(assetPositionOnHashRing).lte(maxDistance)) { - hashRing.push(neighbor); - } else { - hashRing.unshift(neighbor); - } - } - } - - return { - leftEdgeNode: hashRing[0], - rightEdgeNode: hashRing[hashRing.length - 1], - }; - } - - async function deployCommitManagerV2U1Fixture(): Promise { - await hre.deployments.fixture([ - 'HubV2', - 'ContentAssetStorageV2', - 'ShardingTableV2', - 'StakingV2', - 'CommitManagerV2', - 'CommitManagerV2U1', - 'ContentAssetV2', - 'Profile', - ]); - Token = await hre.ethers.getContract('Token'); - ServiceAgreementV1 = await hre.ethers.getContract('ServiceAgreementV1'); - ContentAssetV2 = await hre.ethers.getContract('ContentAsset'); - ContentAssetStorageV2 = await hre.ethers.getContract('ContentAssetStorage'); - LinearSum = await hre.ethers.getContract('LinearSum'); - CommitManagerV2 = await hre.ethers.getContract('CommitManagerV1'); - CommitManagerV2U1 = await hre.ethers.getContract('CommitManagerV1U1'); - ParametersStorage = await hre.ethers.getContract('ParametersStorage'); - ProfileStorage = await hre.ethers.getContract('ProfileStorage'); - Profile = await hre.ethers.getContract('Profile'); - StakingV2 = await hre.ethers.getContract('Staking'); - ContentAssetStorageV2 = await hre.ethers.getContract('ContentAssetStorage'); - accounts = await hre.ethers.getSigners(); - - return { accounts, CommitManagerV2, CommitManagerV2U1 }; - } - - beforeEach(async () => { - hre.helpers.resetDeploymentsJson(); - ({ accounts, CommitManagerV2U1 } = await loadFixture(deployCommitManagerV2U1Fixture)); - }); - - it('The contract is named "CommitManagerV1U1"', async () => { - expect(await CommitManagerV2U1.name()).to.equal('CommitManagerV1U1'); - }); - - it('The contract is version "2.0.0"', async () => { - expect(await CommitManagerV2U1.version()).to.equal('2.0.0'); - }); - - it('Create new asset with proximityScoreFunctionsPair 2, update and finalize V2 update, check if commit window is open, expect to be true', async () => { - const { tokenId, keyword, agreementId } = await createAsset(2); - await updateAsset(tokenId); - await finalizeUpdateV2(tokenId, keyword); - - await expect(CommitManagerV2.isCommitWindowOpen(agreementId, 0)).to.be.revertedWithCustomError( - CommitManagerV2, - 'ServiceAgreementDoesntExist', - ); - expect(await CommitManagerV2U1.isCommitWindowOpen(agreementId, 0)).to.eql(true); - }); - - it('Create new asset with proximityScoreFunctionsPair 2, update and finalize V2 update, teleport to the end of commit phase and check if commit window is open, expect to be false', async () => { - const { tokenId, keyword, agreementId } = await createAsset(2); - await updateAsset(tokenId); - await finalizeUpdateV2(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - const commitWindowDurationPerc = await ParametersStorage.commitWindowDurationPerc(); - const commitWindowDuration = (epochLength * commitWindowDurationPerc) / 100; - - await time.increase(commitWindowDuration + 1); - - await expect(CommitManagerV2.isCommitWindowOpen(agreementId, 0)).to.be.revertedWithCustomError( - CommitManagerV2, - 'ServiceAgreementDoesntExist', - ); - expect(await CommitManagerV2U1.isCommitWindowOpen(agreementId, 0)).to.eql(false); - }); - - it('Create new asset with proximityScoreFunctionsPair 2, update and finalize update V2, teleport to second epoch and check if commit window is open, expect to be true', async () => { - const { tokenId, keyword, agreementId } = await createAsset(2); - await updateAsset(tokenId); - await finalizeUpdateV2(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - await time.increase(epochLength); - - await expect(CommitManagerV2.isCommitWindowOpen(agreementId, 1)).to.be.revertedWithCustomError( - CommitManagerV2, - 'ServiceAgreementDoesntExist', - ); - expect(await CommitManagerV2U1.isCommitWindowOpen(agreementId, 1)).to.eql(true); - }); - - it('Create new asset with proximityScoreFunctionsPair 2, update it, check if update commit window is open, expect to be true', async () => { - const { tokenId, agreementId } = await createAsset(2); - await updateAsset(tokenId); - - expect(await CommitManagerV2U1.isUpdateCommitWindowOpen(agreementId, 0, 1)).to.eql(true); - }); - - it('Create new asset with proximityScoreFunctionsPair 2, update it, teleport to the end of update commit window and check if its open, expect to be false', async () => { - const { tokenId, agreementId } = await createAsset(2); - await updateAsset(tokenId); - - const updateCommitWindowDuration = await ParametersStorage.updateCommitWindowDuration(); - await time.increase(updateCommitWindowDuration); - - expect(await CommitManagerV2U1.isUpdateCommitWindowOpen(agreementId, 0, 1)).to.eql(false); - }); - - it('Create new asset with proximityScoreFunctionsPair 2, update it, finalize V2 update, teleport to the second epoch, submit commit, expect CommitSubmitted event', async () => { - const { tokenId, keyword } = await createAsset(2); - await updateAsset(tokenId); - const { closestNodeIndex, leftEdgeNodeIndex, rightEdgeNodeIndex } = await finalizeUpdateV2(tokenId, keyword); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - await time.increase(epochLength); - - commitV2InputArgs = { - assetContract: ContentAssetStorageV2.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 1, - closestNodeIndex: closestNodeIndex, - leftEdgeNodeIndex: leftEdgeNodeIndex, - rightEdgeNodeIndex: rightEdgeNodeIndex, - }; - - await expect( - CommitManagerV2['submitCommit((address,uint256,bytes,uint8,uint16,uint72,uint72,uint72))'](commitV2InputArgs), - ).to.be.revertedWithCustomError(CommitManagerV2, 'ServiceAgreementDoesntExist'); - await expect( - CommitManagerV2U1['submitCommit((address,uint256,bytes,uint8,uint16,uint72,uint72,uint72))'](commitV2InputArgs), - ).to.emit(CommitManagerV2U1, 'CommitSubmitted'); - }); - - it('Create new asset with proximityScoreFunctionsPair 2, update it, finalize update V2, teleport to the second epoch, submit R0 commits, expect R0 commits to be returned', async () => { - const r0 = await ParametersStorage.r0(); - - const { tokenId, keyword, agreementId } = await createAsset(2); - await updateAsset(tokenId); - const { winners, closestNodeIndex, leftEdgeNodeIndex, rightEdgeNodeIndex } = await finalizeUpdateV2( - tokenId, - keyword, - ); - - const epochLength = (await ParametersStorage.epochLength()).toNumber(); - await time.increase(epochLength); - - commitV2InputArgs = { - assetContract: ContentAssetStorageV2.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 1, - closestNodeIndex: closestNodeIndex, - leftEdgeNodeIndex: leftEdgeNodeIndex, - rightEdgeNodeIndex: rightEdgeNodeIndex, - }; - - for (let i = 0; i < r0; i++) { - await expect( - CommitManagerV2.connect(winners[i].account)[ - 'submitCommit((address,uint256,bytes,uint8,uint16,uint72,uint72,uint72))' - ](commitV2InputArgs), - ).to.be.revertedWithCustomError(CommitManagerV2, 'ServiceAgreementDoesntExist'); - await expect( - CommitManagerV2U1.connect(winners[i].account)[ - 'submitCommit((address,uint256,bytes,uint8,uint16,uint72,uint72,uint72))' - ](commitV2InputArgs), - ).to.emit(CommitManagerV2U1, 'CommitSubmitted'); - } - - await expect(CommitManagerV2.getTopCommitSubmissions(agreementId, 1)).to.be.revertedWithCustomError( - CommitManagerV2, - 'ServiceAgreementDoesntExist', - ); - const topCommits = await CommitManagerV2U1.getTopCommitSubmissions(agreementId, 1, 1); - - expect(topCommits.map((arr) => arr[0])).to.have.deep.members( - winners.map((winner) => hre.ethers.BigNumber.from(winner.identityId)), - ); - }); - - it('Create new asset with proximityScoreFunctionsPair 1, update asset, submit update commit V1, expect revert InvalidScoreFunctionId', async () => { - await createProfile(accounts[0], accounts[1]); - - const { tokenId, keyword } = await createAsset(); - await updateAsset(tokenId); - - commitV1InputArgs = { - assetContract: ContentAssetStorageV2.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - }; - - await expect( - CommitManagerV2U1['submitUpdateCommit((address,uint256,bytes,uint8,uint16))'](commitV1InputArgs), - ).to.be.revertedWithCustomError(CommitManagerV2U1, 'InvalidScoreFunctionId'); - }); - - it('Create new asset with proximityScoreFunctionsPair 2, update asset, submit update commit V2, expect CommitSubmitted event', async () => { - const { tokenId, keyword } = await createAsset(2); - - const nodes = await createMultipleProfiles(30); - - const keyHash = hre.ethers.utils.soliditySha256(['bytes'], [keyword]); - - const neighborhood = await getNeighborhood(nodes, keyHash); - - const closestNode = neighborhood[0]; - const { leftEdgeNode, rightEdgeNode } = await getNeighborhoodEdgeNodes(neighborhood, keyHash); - - commitV2InputArgs = { - assetContract: ContentAssetStorageV2.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - closestNodeIndex: closestNode.index, - leftEdgeNodeIndex: leftEdgeNode.index, - rightEdgeNodeIndex: rightEdgeNode.index, - }; - - await updateAsset(tokenId); - - await expect( - CommitManagerV2U1['submitUpdateCommit((address,uint256,bytes,uint8,uint16,uint72,uint72,uint72))']( - commitV2InputArgs, - ), - ).to.emit(CommitManagerV2U1, 'CommitSubmitted'); - }); - - it('Create new asset with proximityScoreFunctionsPair 1, update it and submit V1 update commits, expect revert InvalidScoreFunctionId', async () => { - const finalizationRequirement = await ParametersStorage.finalizationCommitsNumber(); - - const identityIds = []; - for (let i = 0; i < finalizationRequirement; i++) { - const node = await createProfile(accounts[i], accounts[accounts.length - 1]); - identityIds.push(node.identityId); - } - - const { tokenId, keyword } = await createAsset(); - await updateAsset(tokenId); - - commitV1InputArgs = { - assetContract: ContentAssetStorageV2.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - }; - for (let i = 0; i < finalizationRequirement - 1; i++) { - await expect( - CommitManagerV2U1.connect(accounts[i])['submitUpdateCommit((address,uint256,bytes,uint8,uint16))']( - commitV1InputArgs, - ), - ).to.be.revertedWithCustomError(CommitManagerV2U1, 'InvalidScoreFunctionId'); - } - }); - - it('Create new asset with proximityScoreFunctionsPair 2, update it and submit V2 update commits, expect StateFinalized event', async () => { - const r2 = await ParametersStorage.r2(); - const minStake = await ParametersStorage.minimumStake(); - const maxStake = await ParametersStorage.maximumStake(); - const finalizationRequirement = await ParametersStorage.finalizationCommitsNumber(); - - const { tokenId, keyword, agreementId } = await createAsset(2); - - const nodes = await createMultipleProfiles(30); - - const keyHash = hre.ethers.utils.soliditySha256(['bytes'], [keyword]); - - const neighborhood = await getNeighborhood(nodes, keyHash); - - const closestNode = neighborhood[0]; - const { leftEdgeNode, rightEdgeNode } = await getNeighborhoodEdgeNodes(neighborhood, keyHash); - - await updateAsset(tokenId); - - commitV2InputArgs = { - assetContract: ContentAssetStorageV2.address, - tokenId: tokenId, - keyword: keyword, - hashFunctionId: 1, - epoch: 0, - closestNodeIndex: closestNode.index, - leftEdgeNodeIndex: leftEdgeNode.index, - rightEdgeNodeIndex: rightEdgeNode.index, - }; - - const scoredNeighborhood = await Promise.all( - neighborhood.map(async (node) => ({ - account: node.account, - identityId: node.identityId, - score: ( - await calculateScore( - node.distance, - node.stake, - neighborhood[neighborhood.length - 1].distance, - r2, - nodes.length, - minStake, - maxStake, - ) - ).toNumber(), - })), - ); - - scoredNeighborhood.sort((a, b) => a.score - b.score); - - for (let i = 0; i < finalizationRequirement - 1; i++) { - await expect( - CommitManagerV2U1.connect(scoredNeighborhood[i].account)[ - 'submitUpdateCommit((address,uint256,bytes,uint8,uint16,uint72,uint72,uint72))' - ](commitV2InputArgs), - ).to.emit(CommitManagerV2U1, 'CommitSubmitted'); - } - await expect( - CommitManagerV2U1.connect(scoredNeighborhood[finalizationRequirement - 1].account)[ - 'submitUpdateCommit((address,uint256,bytes,uint8,uint16,uint72,uint72,uint72))' - ](commitV2InputArgs), - ).to.emit(CommitManagerV2U1, 'StateFinalized'); - const topCommits = await CommitManagerV2U1.getTopCommitSubmissions(agreementId, 0, 1); - expect(topCommits.map((arr) => arr[0])).to.include.deep.members( - scoredNeighborhood.slice(0, finalizationRequirement).map((node) => hre.ethers.BigNumber.from(node.identityId)), - ); - }); -}); diff --git a/test/v2/unit/Paranet.test.ts b/test/v2/unit/Paranet.test.ts index 67c4f198..75766d1e 100644 --- a/test/v2/unit/Paranet.test.ts +++ b/test/v2/unit/Paranet.test.ts @@ -127,8 +127,8 @@ describe('@v2 @unit ParanetKnowledgeMinersRegistry contract', function () { expect(await Paranet.name()).to.equal('Paranet'); }); - it('The contract is version "2.2.0"', async () => { - expect(await Paranet.version()).to.equal('2.2.0'); + it('The contract is version "2.2.1"', async () => { + expect(await Paranet.version()).to.equal('2.2.1'); }); it('should register paranet', async () => { diff --git a/test/v2/unit/ParanetsRegistry.test.ts b/test/v2/unit/ParanetsRegistry.test.ts index bf6b1ddb..846d30c1 100644 --- a/test/v2/unit/ParanetsRegistry.test.ts +++ b/test/v2/unit/ParanetsRegistry.test.ts @@ -32,14 +32,19 @@ describe('@v2 @unit ParanetsRegistry contract', function () { return { accounts, ParanetsRegistry }; } - async function createProfile(operational: SignerWithAddress, admin: SignerWithAddress): Promise { + async function createProfile( + operational: SignerWithAddress, + admin: SignerWithAddress, + ): Promise<{ identityId: number; nodeId: string }> { const OperationalProfile = Profile.connect(operational); + const nodeId = '0x' + randomBytes(32).toString('hex'); + const receipt = await ( await OperationalProfile.createProfile( admin.address, [], - '0x' + randomBytes(32).toString('hex'), + nodeId, randomBytes(3).toString('hex'), randomBytes(2).toString('hex'), 0, @@ -53,7 +58,7 @@ describe('@v2 @unit ParanetsRegistry contract', function () { await Token.connect(admin).increaseAllowance(Staking.address, stakeAmount); await Staking.connect(admin)['addStake(uint72,uint96)'](identityId, stakeAmount); - return identityId; + return { identityId, nodeId }; } beforeEach(async () => { @@ -287,17 +292,17 @@ describe('@v2 @unit ParanetsRegistry contract', function () { expect(nodeCount).to.be.equal(0); - const identityId1 = await createProfile(accounts[11], accounts[1]); - const identityId2 = await createProfile(accounts[12], accounts[1]); - const identityId3 = await createProfile(accounts[13], accounts[1]); + const { identityId: identityId1, nodeId: nodeId1 } = await createProfile(accounts[11], accounts[1]); + const { identityId: identityId2, nodeId: nodeId2 } = await createProfile(accounts[12], accounts[1]); + const { identityId: identityId3, nodeId: nodeId3 } = await createProfile(accounts[13], accounts[1]); - const tx1 = await ParanetsRegistry.addCuratedNode(paranetId, identityId1); + const tx1 = await ParanetsRegistry.addCuratedNode(paranetId, identityId1, nodeId1); await tx1.wait(); - const tx2 = await ParanetsRegistry.addCuratedNode(paranetId, identityId2); + const tx2 = await ParanetsRegistry.addCuratedNode(paranetId, identityId2, nodeId2); await tx2.wait(); - const tx3 = await ParanetsRegistry.addCuratedNode(paranetId, identityId3); + const tx3 = await ParanetsRegistry.addCuratedNode(paranetId, identityId3, nodeId3); await tx3.wait(); nodeCount = await ParanetsRegistry.getCuratedNodesCount(paranetId); @@ -324,8 +329,8 @@ describe('@v2 @unit ParanetsRegistry contract', function () { const curatedNodes = await ParanetsRegistry.getCuratedNodes(paranetId); expect(curatedNodes.length).to.be.equal(2); - expect(curatedNodes[0]).to.be.equal(identityId1); - expect(curatedNodes[1]).to.be.equal(identityId3); + expect(curatedNodes[0].identityId).to.be.equal(identityId1); + expect(curatedNodes[1].identityId).to.be.equal(identityId3); }); it('should manipulate Knowledge Miners arrays correctly', async () => { diff --git a/test/v2/unit/StakingV2.test.ts b/test/v2/unit/StakingV2.test.ts index fc9430cf..a4dd1f1f 100644 --- a/test/v2/unit/StakingV2.test.ts +++ b/test/v2/unit/StakingV2.test.ts @@ -16,6 +16,8 @@ import { Shares, ParametersStorage, ProfileStorage, + ShardingTableV2, + ShardingTableStorageV2, } from '../../../typechain'; type StakingFixture = { @@ -25,6 +27,8 @@ type StakingFixture = { ServiceAgreementStorageV1U1: ServiceAgreementStorageV1U1; StakingV2: StakingV2; StakingStorage: StakingStorage; + ShardingTableStorage: ShardingTableStorageV2; + ShardingTable: ShardingTableV2; }; type Node = { @@ -43,6 +47,8 @@ describe('@v2 @unit StakingV2 contract', function () { let Token: Token; let Profile: Profile; let ServiceAgreementStorageV1U1: ServiceAgreementStorageV1U1; + let ShardingTableStorage: ShardingTableStorageV2; + let ShardingTable: ShardingTableV2; const identityId1 = 1; const totalStake = hre.ethers.utils.parseEther('1000'); const operatorFee = hre.ethers.BigNumber.from(10); @@ -50,7 +56,7 @@ describe('@v2 @unit StakingV2 contract', function () { const timestamp = 1674261619; async function deployStakingFixture(): Promise { - await hre.deployments.fixture(['StakingV2', 'Profile']); + await hre.deployments.fixture(['StakingV2', 'Profile', 'ShardingTableStorageV2', 'ShardingTableV2']); ParametersStorage = await hre.ethers.getContract('ParametersStorage'); ProfileStorage = await hre.ethers.getContract('ProfileStorage'); StakingV2 = await hre.ethers.getContract('Staking'); @@ -60,12 +66,23 @@ describe('@v2 @unit StakingV2 contract', function () { ServiceAgreementStorageV1U1 = await hre.ethers.getContract( 'ServiceAgreementStorageV1U1', ); + ShardingTableStorage = await hre.ethers.getContract('ShardingTableStorage'); + ShardingTable = await hre.ethers.getContract('ShardingTable'); accounts = await hre.ethers.getSigners(); const HubController = await hre.ethers.getContract('HubController'); await HubController.setContractAddress('HubOwner', accounts[0].address); await HubController.setContractAddress('NotHubOwner', accounts[1].address); - return { accounts, Token, Profile, ServiceAgreementStorageV1U1, StakingV2, StakingStorage }; + return { + accounts, + Token, + Profile, + ServiceAgreementStorageV1U1, + StakingV2, + StakingStorage, + ShardingTable, + ShardingTableStorage, + }; } async function createProfile(operational: SignerWithAddress, admin: SignerWithAddress): Promise { @@ -121,17 +138,24 @@ describe('@v2 @unit StakingV2 contract', function () { beforeEach(async () => { hre.helpers.resetDeploymentsJson(); - ({ accounts, Token, Profile, ServiceAgreementStorageV1U1, StakingV2, StakingStorage } = await loadFixture( - deployStakingFixture, - )); + ({ + accounts, + Token, + Profile, + ServiceAgreementStorageV1U1, + StakingV2, + StakingStorage, + ShardingTable, + ShardingTableStorage, + } = await loadFixture(deployStakingFixture)); }); it('The contract is named "Staking"', async () => { expect(await StakingV2.name()).to.equal('Staking'); }); - it('The contract is version "2.2.0"', async () => { - expect(await StakingV2.version()).to.equal('2.2.0'); + it('The contract is version "2.3.0"', async () => { + expect(await StakingV2.version()).to.equal('2.3.0'); }); it('Non-Contract should not be able to setTotalStake; expect to fail', async () => { @@ -706,7 +730,7 @@ describe('@v2 @unit StakingV2 contract', function () { const initialStake = hre.ethers.utils.parseEther('1000'); const { identityId, nodeId } = await createProfile(accounts[0], accounts[1]); - await Token.approve(StakingV2.address, initialStake); + await Token.increaseAllowance(StakingV2.address, initialStake); await StakingV2['addStake(uint72,uint96)'](identityId, initialStake); const sharesToBurn = hre.ethers.utils.parseEther('500'); @@ -752,7 +776,7 @@ describe('@v2 @unit StakingV2 contract', function () { const initialStakeAmount = hre.ethers.utils.parseEther('500'); const reward = hre.ethers.utils.parseEther('250'); - await Token.approve(StakingV2.address, initialStakeAmount); + await Token.increaseAllowance(StakingV2.address, initialStakeAmount); await StakingV2['addStake(uint72,uint96)'](identityId, initialStakeAmount); const sharesToBurn = initialStakeAmount.div(2); @@ -797,4 +821,293 @@ describe('@v2 @unit StakingV2 contract', function () { hre.ethers.utils.parseEther('375'), ); }); + + it('should correctly redelegate shares from one node to another', async function () { + // Create two nodes + const node1 = await createProfile(accounts[0], accounts[1]); // From node + const node2 = await createProfile(accounts[2], accounts[3]); // To node + + // Stake some amount on node1 + const initialStakeAmount = hre.ethers.utils.parseEther('1000'); // 1000 tokens + + // Approve tokens and stake on node1 + await Token.increaseAllowance(StakingV2.address, initialStakeAmount); + await StakingV2['addStake(uint72,uint96)'](node1.identityId, initialStakeAmount); + + // Get shares contracts + const fromSharesAddress = await ProfileStorage.getSharesContractAddress(node1.identityId); + const fromSharesContract = await hre.ethers.getContractAt('Shares', fromSharesAddress); + + const toSharesAddress = await ProfileStorage.getSharesContractAddress(node2.identityId); + const toSharesContract = await hre.ethers.getContractAt('Shares', toSharesAddress); + + // Get initial balances and stakes + const fromInitialSharesBalance = await fromSharesContract.balanceOf(accounts[0].address); + const toInitialSharesBalance = await toSharesContract.balanceOf(accounts[0].address); + + const fromCurrentStake = await StakingStorage.totalStakes(node1.identityId); + const toCurrentStake = await StakingStorage.totalStakes(node2.identityId); + + const fromTotalShares = await fromSharesContract.totalSupply(); + const toTotalShares = await toSharesContract.totalSupply(); + + // Redelegate half of the shares + const sharesToBurn = fromInitialSharesBalance.div(2); + + // Calculate redelegationAmount + const redelegationAmount = fromCurrentStake.mul(sharesToBurn).div(fromTotalShares); + + // Calculate sharesToMint + let sharesToMint: BigNumber; + if (toTotalShares.isZero()) { + sharesToMint = redelegationAmount; + } else { + sharesToMint = redelegationAmount.mul(toTotalShares).div(toCurrentStake); + } + + // Increase allowance for fromSharesContract + await fromSharesContract.connect(accounts[0]).increaseAllowance(StakingV2.address, sharesToBurn); + + // Call redelegate + await expect(StakingV2.redelegate(node1.identityId, node2.identityId, sharesToBurn)) + .to.emit(StakingV2, 'SharesBurned') + .withArgs( + node1.identityId, + fromSharesAddress, + accounts[0].address, + sharesToBurn, + fromTotalShares.sub(sharesToBurn), + ) + .to.emit(StakingV2, 'StakeWithdrawn') + .withArgs(node1.identityId, node1.nodeId, accounts[0].address, redelegationAmount) + .to.emit(StakingV2, 'SharesMinted') + .withArgs(node2.identityId, toSharesAddress, accounts[0].address, sharesToMint, toTotalShares.add(sharesToMint)) + .to.emit(StakingV2, 'StakeIncreased') + .withArgs( + node2.identityId, + node2.nodeId, + accounts[0].address, + toCurrentStake, + toCurrentStake.add(redelegationAmount), + ); + + // Check final balances and stakes + const fromFinalSharesBalance = await fromSharesContract.balanceOf(accounts[0].address); + const toFinalSharesBalance = await toSharesContract.balanceOf(accounts[0].address); + + const fromFinalStake = await StakingStorage.totalStakes(node1.identityId); + const toFinalStake = await StakingStorage.totalStakes(node2.identityId); + + expect(fromFinalSharesBalance).to.equal(fromInitialSharesBalance.sub(sharesToBurn)); + expect(toFinalSharesBalance).to.equal(toInitialSharesBalance.add(sharesToMint)); + + expect(fromFinalStake).to.equal(fromCurrentStake.sub(redelegationAmount)); + expect(toFinalStake).to.equal(toCurrentStake.add(redelegationAmount)); + }); + + it('should revert when attempting to redelegate zero shares', async function () { + const node1 = await createProfile(accounts[0], accounts[1]); + const node2 = await createProfile(accounts[2], accounts[3]); + + const initialStakeAmount = hre.ethers.utils.parseEther('1000'); + await Token.increaseAllowance(StakingV2.address, initialStakeAmount); + await StakingV2['addStake(uint72,uint96)'](node1.identityId, initialStakeAmount); + + await expect(StakingV2.redelegate(node1.identityId, node2.identityId, 0)).to.be.revertedWithCustomError( + StakingV2, + 'ZeroSharesAmount', + ); + }); + + it('should revert when attempting to redelegate more shares than owned', async function () { + const node1 = await createProfile(accounts[0], accounts[1]); + const node2 = await createProfile(accounts[2], accounts[3]); + + const initialStakeAmount = hre.ethers.utils.parseEther('1000'); + await Token.increaseAllowance(StakingV2.address, initialStakeAmount); + await StakingV2['addStake(uint72,uint96)'](node1.identityId, initialStakeAmount); + + const fromSharesAddress = await ProfileStorage.getSharesContractAddress(node1.identityId); + const fromSharesContract = await hre.ethers.getContractAt('Shares', fromSharesAddress); + + const userSharesBalance = await fromSharesContract.balanceOf(accounts[0].address); + const sharesToBurn = userSharesBalance.add(1); // One more than user owns + + await fromSharesContract.connect(accounts[0]).increaseAllowance(StakingV2.address, sharesToBurn); + + await expect(StakingV2.redelegate(node1.identityId, node2.identityId, sharesToBurn)).to.be.revertedWithCustomError( + StakingV2, + 'TooLowBalance', + ); + }); + + it('should revert when attempting to redelegate from a non-existent identity', async function () { + const node2 = await createProfile(accounts[0], accounts[2]); + const nonExistentIdentityId = 9999; // Assuming this identity doesn't exist + + const sharesToBurn = hre.ethers.utils.parseEther('100'); + + await expect( + StakingV2.redelegate(nonExistentIdentityId, node2.identityId, sharesToBurn), + ).to.be.revertedWithCustomError(StakingV2, 'ProfileDoesntExist'); + }); + + it('should revert when attempting to redelegate to a non-existent identity', async function () { + const node1 = await createProfile(accounts[0], accounts[1]); + const nonExistentIdentityId = 9999; // Assuming this identity doesn't exist + + const initialStakeAmount = hre.ethers.utils.parseEther('1000'); + await Token.increaseAllowance(StakingV2.address, initialStakeAmount); + await StakingV2['addStake(uint72,uint96)'](node1.identityId, initialStakeAmount); + + const fromSharesAddress = await ProfileStorage.getSharesContractAddress(node1.identityId); + const fromSharesContract = await hre.ethers.getContractAt('Shares', fromSharesAddress); + + const sharesToBurn = hre.ethers.utils.parseEther('100'); + + await fromSharesContract.connect(accounts[0]).increaseAllowance(StakingV2.address, sharesToBurn); + + await expect( + StakingV2.redelegate(node1.identityId, nonExistentIdentityId, sharesToBurn), + ).to.be.revertedWithCustomError(StakingV2, 'ProfileDoesntExist'); + }); + + it('should revert when redelegating causes "to" identity stake to exceed maximumStake', async function () { + const node1 = await createProfile(accounts[0], accounts[1]); + const node2 = await createProfile(accounts[2], accounts[3]); + + const maximumStake = await ParametersStorage.maximumStake(); + + // Stake on node2 up to maximumStake - small amount + const initialStakeToNode2 = maximumStake.sub(hre.ethers.utils.parseEther('100')); + await Token.connect(accounts[0]).increaseAllowance(StakingV2.address, initialStakeToNode2); + await StakingV2['addStake(uint72,uint96)'](node2.identityId, initialStakeToNode2); + + // Stake on node1 + const initialStakeToNode1 = hre.ethers.utils.parseEther('1000'); + await Token.connect(accounts[0]).increaseAllowance(StakingV2.address, initialStakeToNode1); + await StakingV2['addStake(uint72,uint96)'](node1.identityId, initialStakeToNode1); + + const fromSharesAddress = await ProfileStorage.getSharesContractAddress(node1.identityId); + const fromSharesContract = await hre.ethers.getContractAt('Shares', fromSharesAddress); + + const sharesToBurn = await fromSharesContract.balanceOf(accounts[0].address); + + await fromSharesContract.connect(accounts[0]).increaseAllowance(StakingV2.address, sharesToBurn); + + await expect(StakingV2.redelegate(node1.identityId, node2.identityId, sharesToBurn)).to.be.revertedWithCustomError( + StakingV2, + 'MaximumStakeExceeded', + ); + }); + + it('should update sharding table when from node stake falls below minimum and to node stake exceeds minimum after redelegation', async function () { + // Create two nodes + const node1 = await createProfile(accounts[0], accounts[1]); // From node + const node2 = await createProfile(accounts[2], accounts[3]); // To node + + const minimumStake = await ParametersStorage.minimumStake(); + const extraStake = hre.ethers.utils.parseEther('100'); + + // Stake amount for node1: Initially above minimum + const initialStakeNode1 = minimumStake.add(extraStake); // Above minimum + + // Stake amount for node2: Initially below minimum + const initialStakeNode2 = minimumStake.sub(hre.ethers.utils.parseEther('1')); // Just below minimum + + // Approve tokens and stake on node1 + await Token.approve(StakingV2.address, initialStakeNode1); + await StakingV2['addStake(uint72,uint96)'](node1.identityId, initialStakeNode1); + + // Ensure node1 is in the sharding table + let node1InShardingTable = await ShardingTableStorage.nodeExists(node1.identityId); + expect(node1InShardingTable).to.be.true; + + // Approve tokens and stake on node2 + await Token.connect(accounts[0]).approve(StakingV2.address, initialStakeNode2); + await StakingV2['addStake(uint72,uint96)'](node2.identityId, initialStakeNode2); + + // Ensure node2 is not in the sharding table + let node2InShardingTable = await ShardingTableStorage.nodeExists(node2.identityId); + expect(node2InShardingTable).to.be.false; + + // Get shares contracts + const fromSharesAddress = await ProfileStorage.getSharesContractAddress(node1.identityId); + const fromSharesContract = await hre.ethers.getContractAt('Shares', fromSharesAddress); + + const toSharesAddress = await ProfileStorage.getSharesContractAddress(node2.identityId); + const toSharesContract = await hre.ethers.getContractAt('Shares', toSharesAddress); + + // Redelegate amount that will cause node1's stake to fall below minimum and node2's stake to exceed minimum + const fromCurrentStake = await StakingStorage.totalStakes(node1.identityId); + const toCurrentStake = await StakingStorage.totalStakes(node2.identityId); + + // Calculate amount to redelegate + const stakeToTransfer = fromCurrentStake.sub(minimumStake).add(hre.ethers.utils.parseEther('1')); // Enough to reduce node1 below minimum and increase node2 above minimum + + // Calculate shares to burn + const fromTotalShares = await fromSharesContract.totalSupply(); + const toTotalShares = await toSharesContract.totalSupply(); + + const sharesToBurn = fromTotalShares.mul(stakeToTransfer).div(fromCurrentStake); + + // Calculate redelegationAmount + const redelegationAmount = fromCurrentStake.mul(sharesToBurn).div(fromTotalShares); + + let sharesToMint: BigNumber; + if (toTotalShares.isZero()) { + sharesToMint = redelegationAmount; + } else { + sharesToMint = redelegationAmount.mul(toTotalShares).div(toCurrentStake); + } + + // Increase allowance for fromSharesContract + await fromSharesContract.connect(accounts[0]).increaseAllowance(StakingV2.address, sharesToBurn); + + // Redelegate and check events + await expect(StakingV2.redelegate(node1.identityId, node2.identityId, sharesToBurn)) + .to.emit(StakingV2, 'SharesBurned') + .withArgs( + node1.identityId, + fromSharesAddress, + accounts[0].address, + sharesToBurn, + fromTotalShares.sub(sharesToBurn), + ) + .to.emit(StakingV2, 'StakeWithdrawn') + .withArgs(node1.identityId, node1.nodeId, accounts[0].address, stakeToTransfer) + .to.emit(StakingV2, 'SharesMinted') + .withArgs(node2.identityId, toSharesAddress, accounts[0].address, sharesToMint, toTotalShares.add(sharesToMint)) + .to.emit(StakingV2, 'StakeIncreased') + .withArgs( + node2.identityId, + node2.nodeId, + accounts[0].address, + toCurrentStake, + toCurrentStake.add(stakeToTransfer), + ) + .to.emit(ShardingTable, 'NodeRemoved') // Assuming NodeRemoved event is emitted + .to.emit(ShardingTable, 'NodeAdded'); // Assuming NodeInserted event is emitted + + // After redelegation, check that node1 is no longer in sharding table + node1InShardingTable = await ShardingTableStorage.nodeExists(node1.identityId); + expect(node1InShardingTable).to.be.false; + + // Check that node2 is now in sharding table + node2InShardingTable = await ShardingTableStorage.nodeExists(node2.identityId); + expect(node2InShardingTable).to.be.true; + + // Verify the stakes + const fromFinalStake = await StakingStorage.totalStakes(node1.identityId); + const toFinalStake = await StakingStorage.totalStakes(node2.identityId); + + expect(fromFinalStake).to.equal(fromCurrentStake.sub(stakeToTransfer)); + expect(toFinalStake).to.equal(toCurrentStake.add(stakeToTransfer)); + + // Verify that node1's stake is below minimum + expect(fromFinalStake).to.be.lt(minimumStake); + + // Verify that node2's stake is above minimum + expect(toFinalStake).to.be.gte(minimumStake); + }); });