Skip to content

Commit

Permalink
Reworked deployment scripts, added skeleton for ParanetNeuroIncentive…
Browse files Browse the repository at this point in the history
…sPool unit tests, deployed ERC20 Neuro on Base Sepolia
  • Loading branch information
u-hubar committed Sep 12, 2024
1 parent 1f78e68 commit fe21cc4
Show file tree
Hide file tree
Showing 8 changed files with 335 additions and 10 deletions.
2 changes: 1 addition & 1 deletion deploy/001_deploy_hub_v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const Hub = await hre.deployments.deploy('Hub', { contract: 'HubV2', from: deployer, log: true });

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
hre.helpers.updateDeploymentsJson('Hub', Hub.address, Hub.receipt!.blockNumber);
hre.helpers.updateDeploymentsJson('Hub', 'Hub', Hub.address, Hub.receipt!.blockNumber);
}
}

Expand Down
2 changes: 1 addition & 1 deletion deploy/002_deploy_hub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const Hub = await hre.deployments.deploy('Hub', { from: deployer, log: true });

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
hre.helpers.updateDeploymentsJson('Hub', Hub.address, Hub.receipt!.blockNumber);
hre.helpers.updateDeploymentsJson('Hub', 'Hub', Hub.address, Hub.receipt!.blockNumber);
}
}

Expand Down
24 changes: 23 additions & 1 deletion deploy/100_set_neuroweb_erc20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,34 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {

const tokenInHub = await Hub['isContract(string)']('NeurowebERC20');

if (!tokenInHub) {
if (!tokenInHub && hre.network.config.environment !== 'development') {
hre.helpers.newContracts.push([
'NeurowebERC20',
hre.helpers.contractDeployments.contracts['NeurowebERC20'].evmAddress,
]);
}
} else if (hre.network.config.environment === 'development') {
const Token = await hre.helpers.deploy({
newContractName: 'Token',
newContractNameInHub: 'NeurowebERC20',
passHubInConstructor: false,
additionalArgs: ['NEURO TEST TOKEN', 'NEURO'],
});

const minterRole = await Token.MINTER_ROLE();
if (!(await Token.hasRole(minterRole, deployer))) {
console.log(`Setting ERC20 Neuro minter role for ${deployer}.`);
const setupMinterRoleTx = await Token.setupRole(deployer, { from: deployer });
await setupMinterRoleTx.wait();
}

const amountToMint = hre.ethers.utils.parseEther(`${10_000_000}`);
const accounts = await hre.ethers.getSigners();

for (const acc of accounts) {
const mintTx = await Token.mint(acc.address, amountToMint, { from: deployer, gasLimit: 80_000 });
await mintTx.wait();
}
}
};

Expand Down
4 changes: 4 additions & 0 deletions deployments/base_sepolia_dev_contracts.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"deployed": true,
"evmAddress": "0x4ead53ee0aaeB0bE5920DC2DAA7AD93F11cA5207"
},
"NeurowebERC20": {
"deployed": true,
"evmAddress": "0x008Ea316ff593E82c592fccB6072f82d1393F1Ac"
},
"Hub": {
"evmAddress": "0x6C861Cb69300C34DfeF674F7C00E734e840C29C0",
"version": "2.0.0",
Expand Down
4 changes: 4 additions & 0 deletions deployments/base_sepolia_test_contracts.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"deployed": true,
"evmAddress": "0x9b17032749aa066a2DeA40b746AA6aa09CdE67d9"
},
"NeurowebERC20": {
"deployed": true,
"evmAddress": "0x3d4f5831fcca588554125f1782dad85a4a235f00"
},
"Hub": {
"evmAddress": "0x144eDa5cbf8926327cb2cceef168A121F0E4A299",
"version": "2.0.0",
Expand Down
3 changes: 3 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ config.abiExporter = {
'IERC721Metadata.sol',
'IERC721Receiver.sol',
'IERC734Extended.sol',
'IERC1155.sol',
'IERC1155MetadataURI.sol',
'IERC1155Receiver.sol',
'IERC4906.sol',
'Ownable.sol',
'CommitManagerErrorsV2.sol',
Expand Down
287 changes: 287 additions & 0 deletions test/v2/unit/ParanetNeuroIncentivesPool.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
import { expect } from 'chai';
import { BigNumberish } from 'ethers';
import hre from 'hardhat';
import { SignerWithAddress } from 'hardhat-deploy-ethers/signers';

import {
HubController,
Paranet,
ContentAssetStorageV2,
ContentAssetV2,
ParanetsRegistry,
ParanetServicesRegistry,
ParanetKnowledgeMinersRegistry,
ParanetKnowledgeAssetsRegistry,
HashingProxy,
ServiceAgreementStorageProxy,
Token,
ServiceAgreementV1,
ParanetIncentivesPoolFactory,
Hub,
} from '../../../typechain';

type deployParanetFixture = {
accounts: SignerWithAddress[];
Paranet: Paranet;
HubController: HubController;
ContentAssetV2: ContentAssetV2;
ContentAssetStorageV2: ContentAssetStorageV2;
ParanetsRegistry: ParanetsRegistry;
ParanetServicesRegistry: ParanetServicesRegistry;
ParanetKnowledgeMinersRegistry: ParanetKnowledgeMinersRegistry;
ParanetKnowledgeAssetsRegistry: ParanetKnowledgeAssetsRegistry;
ParanetIncentivesPoolFactory: ParanetIncentivesPoolFactory;
HashingProxy: HashingProxy;
ServiceAgreementStorageProxy: ServiceAgreementStorageProxy;
Token: Token;
NeuroERC20: Token;
ServiceAgreementV1: ServiceAgreementV1;
};

type IncentivizationPoolParameters = {
paranetKAStorageContract: string;
paranetKATokenId: BigNumberish;
tracToNeuroEmissionMultiplier: BigNumberish;
paranetOperatorRewardPercentage: BigNumberish;
paranetIncentivizationProposalVotersRewardPercentage: BigNumberish;
};

describe('@v2 @unit ParanetNeuroIncentivesPool contract', function () {
let accounts: SignerWithAddress[];
let Paranet: Paranet;
let HubController: HubController;
let ContentAssetV2: ContentAssetV2;
let ContentAssetStorageV2: ContentAssetStorageV2;
let ParanetsRegistry: ParanetsRegistry;
let ParanetServicesRegistry: ParanetServicesRegistry;
let ParanetKnowledgeMinersRegistry: ParanetKnowledgeMinersRegistry;
let ParanetKnowledgeAssetsRegistry: ParanetKnowledgeAssetsRegistry;
let ParanetIncentivesPoolFactory: ParanetIncentivesPoolFactory;
let HashingProxy: HashingProxy;
let ServiceAgreementStorageProxy: ServiceAgreementStorageProxy;
let Token: Token;
let NeuroERC20: Token;
let ServiceAgreementV1: ServiceAgreementV1;

async function deployParanetFixture(): Promise<deployParanetFixture> {
await hre.deployments.fixture(
[
'HubV2',
'HubController',
'Paranet',
'ContentAssetStorageV2',
'ContentAssetV2',
'ParanetsRegistry',
'ParanetServicesRegistry',
'ParanetKnowledgeMinersRegistry',
'ParanetKnowledgeAssetsRegistry',
'ParanetIncentivesPoolFactory',
'HashingProxy',
'ServiceAgreementStorageProxy',
'Token',
'Neuro',
'ServiceAgreementV1',
],
{ keepExistingDeployments: false },
);

const Hub = await hre.ethers.getContract<Hub>('Hub');
HubController = await hre.ethers.getContract<HubController>('HubController');
Paranet = await hre.ethers.getContract<Paranet>('Paranet');
ContentAssetV2 = await hre.ethers.getContract<ContentAssetV2>('ContentAsset');
ContentAssetStorageV2 = await hre.ethers.getContract<ContentAssetStorageV2>('ContentAssetStorage');
ParanetsRegistry = await hre.ethers.getContract<ParanetsRegistry>('ParanetsRegistry');
ParanetServicesRegistry = await hre.ethers.getContract<ParanetServicesRegistry>('ParanetServicesRegistry');
ParanetKnowledgeMinersRegistry = await hre.ethers.getContract<ParanetKnowledgeMinersRegistry>(
'ParanetKnowledgeMinersRegistry',
);
ParanetKnowledgeAssetsRegistry = await hre.ethers.getContract<ParanetKnowledgeAssetsRegistry>(
'ParanetKnowledgeAssetsRegistry',
);
ParanetIncentivesPoolFactory = await hre.ethers.getContract<ParanetIncentivesPoolFactory>(
'ParanetIncentivesPoolFactory',
);
ServiceAgreementStorageProxy = await hre.ethers.getContract<ServiceAgreementStorageProxy>(
'ServiceAgreementStorageProxy',
);
HashingProxy = await hre.ethers.getContract<HashingProxy>('HashingProxy');
Token = await hre.ethers.getContract<Token>('Token');
const neuroERC20Address = await Hub.getContractAddress('NeurowebERC20');
NeuroERC20 = await hre.ethers.getContractAt<Token>('Token', neuroERC20Address);
ServiceAgreementV1 = await hre.ethers.getContract<ServiceAgreementV1>('ServiceAgreementV1');

accounts = await hre.ethers.getSigners();
await HubController.setContractAddress('HubOwner', accounts[0].address);

return {
accounts,
Paranet,
HubController,
ContentAssetV2,
ContentAssetStorageV2,
ParanetsRegistry,
ParanetServicesRegistry,
ParanetKnowledgeMinersRegistry,
ParanetKnowledgeAssetsRegistry,
ParanetIncentivesPoolFactory,
HashingProxy,
ServiceAgreementStorageProxy,
Token,
NeuroERC20,
ServiceAgreementV1,
};
}

beforeEach(async () => {
hre.helpers.resetDeploymentsJson();
({ accounts, Paranet, ParanetIncentivesPoolFactory } = await loadFixture(deployParanetFixture));
});

it('The contract is named "ParanetNeuroIncentivesPool"', async () => {
const { paranetKAStorageContract, paranetKATokenId } = await registerParanet(accounts, Paranet, 1);

const incentivesPoolParams = {
paranetKAStorageContract,
paranetKATokenId,
tracToNeuroEmissionMultiplier: hre.ethers.utils.parseEther('1'),
paranetOperatorRewardPercentage: 1_000,
paranetIncentivizationProposalVotersRewardPercentage: 1_000,
};
const IncentivesPool = await deployERC20NeuroIncentivesPool(accounts, incentivesPoolParams, 1);
expect(await IncentivesPool.name()).to.equal('ParanetNeuroIncentivesPool');
});

it('The contract is version "2.2.0"', async () => {
const { paranetKAStorageContract, paranetKATokenId } = await registerParanet(accounts, Paranet, 1);

const incentivesPoolParams = {
paranetKAStorageContract,
paranetKATokenId,
tracToNeuroEmissionMultiplier: hre.ethers.utils.parseEther('1'),
paranetOperatorRewardPercentage: 1_000,
paranetIncentivizationProposalVotersRewardPercentage: 1_000,
};
const IncentivesPool = await deployERC20NeuroIncentivesPool(accounts, incentivesPoolParams, 1);
expect(await IncentivesPool.version()).to.equal('2.2.0');
});

it('Should accept ERC20 Neuro and update the balance', async () => {
const { paranetKAStorageContract, paranetKATokenId } = await registerParanet(accounts, Paranet, 1);

const incentivesPoolParams = {
paranetKAStorageContract,
paranetKATokenId,
tracToNeuroEmissionMultiplier: hre.ethers.utils.parseEther('1'),
paranetOperatorRewardPercentage: 1_000,
paranetIncentivizationProposalVotersRewardPercentage: 1_000,
};
const IncentivesPool = await deployERC20NeuroIncentivesPool(accounts, incentivesPoolParams, 1);

const neuroAmount = hre.ethers.utils.parseEther('100000');
await NeuroERC20.transfer(IncentivesPool.address, neuroAmount);

expect(await IncentivesPool.getNeuroBalance()).to.be.equal(neuroAmount);
});

async function registerParanet(accounts: SignerWithAddress[], Paranet: Paranet, number: number) {
const assetInputArgs = {
assertionId: getHashFromNumber(number),
size: 3,
triplesNumber: 1,
chunksNumber: 1,
epochsNumber: 5,
tokenAmount: hre.ethers.utils.parseEther('105'),
scoreFunctionId: 2,
immutable_: false,
};

await Token.connect(accounts[100 + number]).increaseAllowance(
ServiceAgreementV1.address,
assetInputArgs.tokenAmount,
);
const tx = await ContentAssetV2.connect(accounts[100 + number]).createAsset(assetInputArgs);
const receipt = await tx.wait();

const paranetKAStorageContract = ContentAssetStorageV2.address;
const paranetKATokenId = Number(receipt.logs[0].topics[3]);
const paranetName = 'Test paranet 1';
const paranetDescription = 'Description of Test Paranet';

await Paranet.connect(accounts[100 + number]).registerParanet(
paranetKAStorageContract,
paranetKATokenId,
paranetName,
paranetDescription,
);

return {
paranetKAStorageContract,
paranetKATokenId,
paranetId: hre.ethers.utils.keccak256(
hre.ethers.utils.solidityPack(['address', 'uint256'], [paranetKAStorageContract, paranetKATokenId]),
),
};
}

async function deployERC20NeuroIncentivesPool(
accounts: SignerWithAddress[],
incentivesPoolParams: IncentivizationPoolParameters,
number: number,
) {
const tx = await ParanetIncentivesPoolFactory.connect(accounts[100 + number]).deployNeuroIncentivesPool(
false,
incentivesPoolParams.paranetKAStorageContract,
incentivesPoolParams.paranetKATokenId,
incentivesPoolParams.tracToNeuroEmissionMultiplier,
incentivesPoolParams.paranetOperatorRewardPercentage,
incentivesPoolParams.paranetIncentivizationProposalVotersRewardPercentage,
);
const receipt = await tx.wait();

const IncentivesPool = await hre.ethers.getContractAt(
'ParanetNeuroIncentivesPool',
receipt.events?.[0].args?.incentivesPool.addr,
);

return IncentivesPool;
}

async function createParanetKnowledgeAsset(
paranetKAStorageContract: string,
paranetKATokenId: number,
number: number,
tokenAmount: string,
) {
const assetInputArgs = {
assertionId: getHashFromNumber(number),
size: 3,
triplesNumber: 1,
chunksNumber: 1,
epochsNumber: 5,
tokenAmount: hre.ethers.utils.parseEther(tokenAmount),
scoreFunctionId: 2,
immutable_: false,
};

await Token.connect(accounts[100 + number]).increaseAllowance(
ServiceAgreementV1.address,
assetInputArgs.tokenAmount,
);

await Paranet.connect(accounts[100 + number]).mintKnowledgeAsset(
paranetKAStorageContract,
paranetKATokenId,
assetInputArgs,
);
}

function getHashFromNumber(number: number) {
return hre.ethers.utils.keccak256(hre.ethers.utils.solidityPack(['uint256'], [number]));
}

function getknowledgeAssetId(address: string, number: number) {
return hre.ethers.utils.keccak256(hre.ethers.utils.solidityPack(['address', 'uint256'], [address, number]));
}
});
Loading

0 comments on commit fe21cc4

Please sign in to comment.