Skip to content

Commit

Permalink
feat: setup FrontendLib contract for easy request in the frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
leosayous21 committed Dec 12, 2022
1 parent 1f9d932 commit ed77c99
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 0 deletions.
27 changes: 27 additions & 0 deletions contracts/periphery/utils/FrontendLib.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.14;

import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol';
import {HydraS1AccountboundAttester} from '../../attesters/hydra-s1/HydraS1AccountboundAttester.sol';
import {Initializable} from '@openzeppelin/contracts/proxy/utils/Initializable.sol';

contract FrontendLib {
address private immutable _hydraS1AccountboundAttester;

constructor(address hydraS1AccountboundAttester) {
_hydraS1AccountboundAttester = hydraS1AccountboundAttester;
}

function getHydraS1AccountboundAttesterDestinationOfNullifierBatch(
uint256[] calldata nullifiers
) external view returns (address[] memory) {
address[] memory destinations = new address[](nullifiers.length);

for (uint256 i = 0; i < nullifiers.length; i++) {
destinations[i] = HydraS1AccountboundAttester(_hydraS1AccountboundAttester)
.getDestinationOfNullifier(nullifiers[i]);
}

return destinations;
}
}
20 changes: 20 additions & 0 deletions contracts/tests/MockHydraS1SimpleAttester.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.14;

import {Attestation, Request} from '../core/libs/Structs.sol';
import {Attester} from '../core/Attester.sol';
import {IAttester} from '../core/interfaces/IAttester.sol';
import {IHydraS1AccountboundAttester} from '../attesters/hydra-s1/interfaces/IHydraS1AccountboundAttester.sol';

contract MockHydraS1SimpleAttester {
mapping(uint256 => address) internal _nullifiersDestinations;

function getDestinationOfNullifier(uint256 nullifier) external view returns (address) {
return _nullifiersDestinations[nullifier];
}

function setDestinationOfNullifier(uint256 nullifier, address destination) external {
_nullifiersDestinations[nullifier] = destination;
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DeployedFrontendLib } from '../unit/periphery/deploy-frontend-lib.task';
import { task } from 'hardhat/config';
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import {
Expand Down Expand Up @@ -132,6 +133,11 @@ async function deploymentAction(
pythia1SimpleAttesterArgs
)) as DeployedPythia1SimpleAttester;

const { frontendLib } = (await hre.run('deploy-frontend-lib', {
hydraS1AccountboundAttester: hydraS1AccountboundAttester.address,
options,
})) as DeployedFrontendLib;

// Register an initial root for attester
if (hydraS1SimpleAttester && (options.manualConfirm || options.log)) {
console.log(`
Expand Down Expand Up @@ -325,6 +331,9 @@ async function deploymentAction(
* Pythia1Verifier:
-> address: ${(await hre.deployments.all()).Pythia1Verifier.address}
* FrontendLib:
-> address: ${frontendLib.address}
`);
}

Expand Down
6 changes: 6 additions & 0 deletions tasks/deploy-tasks/full/local/deploy-full-local.task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
DeployedPythia1SimpleAttester,
DeployPythia1SimpleAttesterArgs,
} from 'tasks/deploy-tasks/unit/attesters/pythia-1/deploy-pythia-1-simple-attester.task';
import { DeployedFrontendLib } from 'tasks/deploy-tasks/unit/periphery/deploy-frontend-lib.task';

async function deploymentAction(
{ options }: { options: DeployOptions },
Expand Down Expand Up @@ -85,6 +86,11 @@ async function deploymentAction(
options,
} as DeployPythia1SimpleAttesterArgs)) as DeployedPythia1SimpleAttester;

await hre.run('deploy-frontend-lib', {
hydraS1AccountboundAttester: hydraS1AccountboundAttester.address,
options,
});

if (hydraS1SimpleAttester) {
await hre.run('register-for-attester', {
availableRootsRegistryAddress: availableRootsRegistry.address,
Expand Down
65 changes: 65 additions & 0 deletions tasks/deploy-tasks/unit/periphery/deploy-frontend-lib.task.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { FrontendLib } from '../../../../types/FrontendLib';
import { task } from 'hardhat/config';
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import {
getDeployer,
beforeDeployment,
afterDeployment,
buildDeploymentName,
customDeployContract,
wrapCommonDeployOptions,
DeployOptions,
} from '../../utils';

import { FrontendLib__factory } from '../../../../types';
import { deploymentsConfig } from '../../../../tasks/deploy-tasks/deployments-config';

export interface DeployFrontendLib {
hydraS1AccountboundAttester?: string;
options?: DeployOptions;
}

export interface DeployedFrontendLib {
frontendLib: FrontendLib;
}

const CONTRACT_NAME = 'FrontendLib';

async function deploymentAction(
{ hydraS1AccountboundAttester, options }: DeployFrontendLib,
hre: HardhatRuntimeEnvironment
): Promise<DeployedFrontendLib> {
const deployer = await getDeployer(hre);
const deploymentName = buildDeploymentName(CONTRACT_NAME, options?.deploymentNamePrefix);
const config = deploymentsConfig[hre.network.name];

const deploymentArgs = [
hydraS1AccountboundAttester || config.hydraS1AccountboundAttester.address,
];

await beforeDeployment(hre, deployer, CONTRACT_NAME, deploymentArgs, options);

const deployed = await customDeployContract(
hre,
deployer,
deploymentName,
CONTRACT_NAME,
deploymentArgs,
{
...options,
behindProxy: false,
}
);

await afterDeployment(hre, deployer, CONTRACT_NAME, deploymentArgs, deployed, options);

const frontLib = FrontendLib__factory.connect(deployed.address, deployer);
return { frontendLib: frontLib };
}

task('deploy-frontend-lib')
.addOptionalParam(
'hydraS1AccountboundAttester',
'address of the hydraS1AccountboundAttester contract'
)
.setAction(wrapCommonDeployOptions(deploymentAction));
72 changes: 72 additions & 0 deletions test/unit/periphery/utils/frontend-lib.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { expect } from 'chai';
import hre from 'hardhat';

import { MockHydraS1SimpleAttester__factory } from './../../../../types/factories/MockHydraS1SimpleAttester__factory';
import { FrontendLib } from './../../../../types/FrontendLib';
import { DeployedFrontendLib } from '../../../../tasks/deploy-tasks/unit/periphery/deploy-frontend-lib.task';
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers';

describe('Test FrontendLib contract', () => {
let deployer: SignerWithAddress;
let frontendLib: FrontendLib;
let dest1: SignerWithAddress;
let nullifier1: string;
let dest2: SignerWithAddress;
let nullifier2: string;
let dest3: SignerWithAddress;
let nullifier3: string;
let dest4: SignerWithAddress;

before(async () => {
const signers = await hre.ethers.getSigners();
[deployer, dest1, dest2, dest3, dest4] = signers;
[nullifier1, nullifier2, nullifier3] = [
'0x1000000000000000000000000000000000000000000000000000000000000001',
'0x2000000000000000000000000000000000000000000000000000000000000002',
'0x3000000000000000000000000000000000000000000000000000000000000003',
];
});

/*************************************************************************************/
/********************************** DEPLOYMENTS **************************************/
/*************************************************************************************/
describe('Deployments', () => {
it('Should deploy the FrontendLib and an HydraS1SimpleAttester mock for tests', async () => {
// MockHydraS1SimpleAttester
const hydraS1AttesterMock = await hre.deployments.deploy('MockHydraS1SimpleAttesterTest', {
contract: 'MockHydraS1SimpleAttester',
from: deployer.address,
args: [],
});
const mockHydraS1Attester = MockHydraS1SimpleAttester__factory.connect(
hydraS1AttesterMock.address,
deployer
);

await mockHydraS1Attester.setDestinationOfNullifier(nullifier1, dest1.address);
await mockHydraS1Attester.setDestinationOfNullifier(nullifier2, dest2.address);
await mockHydraS1Attester.setDestinationOfNullifier(nullifier3, dest3.address);

({ frontendLib } = (await hre.run('deploy-frontend-lib', {
hydraS1AccountboundAttester: hydraS1AttesterMock.address,
})) as DeployedFrontendLib);
});
});

describe('Getter', () => {
it('Should get all nullifier at once', async () => {
const destinations =
await frontendLib.getHydraS1AccountboundAttesterDestinationOfNullifierBatch([
nullifier1,
nullifier2,
nullifier3,
// unregistered nullifier
'0x0000000000000000000000000000000000000000000000000000000000000123',
]);
expect(destinations[0]).to.equal(dest1.address);
expect(destinations[1]).to.equal(dest2.address);
expect(destinations[2]).to.equal(dest3.address);
expect(destinations[3]).to.equal('0x0000000000000000000000000000000000000000');
});
});
});

0 comments on commit ed77c99

Please sign in to comment.