diff --git a/.gitignore b/.gitignore index 2c2c244b..ce7c82f4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,106 @@ -node_modules +# ---------------------------- + +# Node / TypeScript + +# ---------------------------- + +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Env + .env -coverage +.env.* + +# Build outputs + +dist/ +build/ +out/ + +# ---------------------------- + +# Hardhat + +# ---------------------------- + +cache/ +artifacts/ + +# Typechain + +typechain/ +typechain-types/ + +# Coverage + +coverage/ coverage.json -typechain -typechain-types -.idea -build -.vscode -#Hardhat files -cache -artifacts -migration-result.json -events-data.json -scripts/upgrade/verifiers/helpers/circuits -**localhost.json -**temp*.json -!ignition/modules/params/localhost.json -!ignition/deployments/**/artifacts -ignition/deployments/chain-31337 \ No newline at end of file + +# ---------------------------- + +# Ignition / Deployments (IMPORTANT) + +# ---------------------------- + +ignition/deployments/ +scripts/deployments_output/ + +# ---------------------------- + +# OpenZeppelin Upgrades (network junk) + +# ---------------------------- + +.openzeppelin/ + +# ---------------------------- + +# OS / Editor junk + +# ---------------------------- + +.DS_Store +**/.DS_Store + +.idea/ +.vscode/ + +# ---------------------------- + +# Logs / temp + +# ---------------------------- + +*.log +output.txt + +# ---------------------------- + +# Hardhat / temp JSONs + +# ---------------------------- + +*localhost.json +*temp*.json + +# ---------------------------- + +# Circuits (generated artifacts) + +# ---------------------------- + +scripts/upgrade/verifiers/helpers/circuits/ + +# ---------------------------- + +# Optional (uncomment if not needed in repo) + +# ---------------------------- + +# adi_deployment_notes.md + +# ignition/modules/params/ diff --git a/adi_deployment_notes.md b/adi_deployment_notes.md new file mode 100644 index 00000000..2096bd67 --- /dev/null +++ b/adi_deployment_notes.md @@ -0,0 +1,637 @@ +# ADI Contracts Fork — Deployment & Maintenance Notes + +## Scope +This note captures the exact fork-level changes, deployment flow, validation steps, and follow-up updates needed for ADI testnet now and ADI mainnet later. + +--- + +## 1. Fork changes that matter + +### 1.1 Add ADI chain support in `helpers/constants.ts` +The standard deployment scripts resolve `defaultIdType` through `DeployHelper.getDefaultIdType()`, which reads from `chainIdInfoMap`. + +### Current ADI testnet entry +```ts +export const chainIdInfoMap: Map = new Map() + // ... existing entries + .set(59141, { + idType: "0x0148", + networkType: "test", + oracleSigningAddress: ORACLE_SIGNING_ADDRESS_PRODUCTION, + }) // linea-sepolia + .set(99999, { + idType: "0x01f9", + networkType: "test", + oracleSigningAddress: ORACLE_SIGNING_ADDRESS_PRODUCTION, + }); // adi-testnet +``` + +### Why this matters +Without this entry: +- `deployState.ts` cannot resolve the ADI `defaultIdType` +- `CrossChainProofValidator` will not pick the chain-specific oracle signing address correctly + +### Mainnet later +When ADI mainnet is ready, add another `.set(...)` entry in the same map: + +```ts +.set(, { + idType: "", + networkType: "main", + oracleSigningAddress: , +}); // adi-mainnet +``` + +### Mainnet placeholders to replace later +```ts + + + +``` + +--- + +## 2. State / SMT fix kept in the fork + +### 2.1 SmtLib.sol critical fix + +#### Final `_updateLeaf` implementation (do not break) + +```solidity +function _updateLeaf( + Data storage self, + uint256 index, + uint256 oldValue, + uint256 newValue, + uint256 nodeHash, + uint256 depth +) internal returns (uint256) { + if (depth > self.maxDepth) { + revert("Max depth reached"); + } + + Node memory node = self.nodes[nodeHash]; + + if (node.nodeType == NodeType.EMPTY) { + revert("Leaf does not exist"); + } + + if (node.nodeType == NodeType.LEAF) { + require(node.index == index, "Leaf index mismatch"); + require(node.value == oldValue, "Old value mismatch"); + + Node memory newLeaf = Node({ + nodeType: NodeType.LEAF, + childLeft: 0, + childRight: 0, + index: index, + value: newValue + }); + + return _addNode(self, newLeaf); + } + + Node memory newNode; + + if ((index >> depth) & 1 == 1) { + uint256 updatedRight = _updateLeaf( + self, + index, + oldValue, + newValue, + node.childRight, + depth + 1 + ); + + newNode = Node({ + nodeType: NodeType.MIDDLE, + childLeft: node.childLeft, + childRight: updatedRight, + index: 0, + value: 0 + }); + } else { + uint256 updatedLeft = _updateLeaf( + self, + index, + oldValue, + newValue, + node.childLeft, + depth + 1 + ); + + newNode = Node({ + nodeType: NodeType.MIDDLE, + childLeft: updatedLeft, + childRight: node.childRight, + index: 0, + value: 0 + }); + } + + return _addNode(self, newNode); +} +``` + +#### External wrapper + +```solidity +function updateLeaf( + Data storage self, + uint256 i, + uint256 oldV, + uint256 newV +) external onlyInitialized(self) { + require(newV != 0, "New leaf value should not be zero"); + + uint256 prevRoot = getRoot(self); + uint256 newRoot = _updateLeaf(self, i, oldV, newV, prevRoot, 0); + + _addEntry(self, newRoot, block.timestamp, block.number); +} +``` + +#### Critical invariants (must NOT be changed) + +- Leaf update must: + - match `index` + - match `oldValue` +- Update must **replace leaf via `_addNode`**, not mutate in-place +- Tree path must be rebuilt upward recursively +- Root must be recomputed via `_addNode` at every level + +#### Why this fixes the issue + +- Prevents duplicate node insertion conflicts +- Ensures deterministic recomputation of the Merkle path +- Guarantees same `(index)` can be updated multiple times safely + +#### If broken, you will see + +```txt +panic code 0x1 +NodeHashConflict(...) +``` + +#### DO NOT change unless + +- You fully understand SMT structure +- You revalidate Poseidon hashing + proof circuits +- You rerun multi-step transition tests + +--- + +A root cause of the earlier `panic (0x01)` and `NodeHashConflict` errors was inside `SmtLib._addNode` / `_updateLeaf`. + +### What was happening +- Repeated updates for the same issuer (same GIST key) +- Incorrect handling of node insertion / overwrite +- Leading to assertion failures or hash conflicts + +### Fix applied +Ensure that leaf updates for an existing key **do not attempt to re-add conflicting nodes**, but instead correctly overwrite/update the path. + +> ⚠️ Important: This fix is tightly coupled with keeping a stable GIST key (`Poseidon(id)`) and updating only the value. + +### Expected invariant after fix +- Same `gistKey` can be updated N times +- No `panic(0x01)` +- No `NodeHashConflict` + +### Developer note +If you ever see: +```txt +panic code 0x1 (Assertion error) +NodeHashConflict(...) +``` +The issue is almost always: +- wrong Poseidon linkage OR +- broken SmtLib node update logic + +Do NOT change `_transitState` first — verify `SmtLib` behavior. + +--- + +### 2.2 State.sol transition logic (final) + +### File: `contracts/state/State.sol` +The final working `_transitState` logic keeps one GIST key per issuer and updates the leaf value for non-genesis transitions. + +### Final snippet +```solidity +function _transitState( + uint256 id, + uint256 oldState, + uint256 newState, + bool isOldStateGenesis +) internal { + require(id != 0, "ID should not be zero"); + require(newState != 0, "New state should not be zero"); + + if (isOldStateGenesis) { + require(!idExists(id), "Old state is genesis but identity already exists"); + + // Push old state to state entries, with zero timestamp and block + _stateData.addGenesisState(id, oldState); + } else { + require(idExists(id), "Old state is not genesis but identity does not yet exist"); + + StateLib.EntryInfo memory prevStateInfo = _stateData.getStateInfoById(id); + require(prevStateInfo.state == oldState, "Old state does not match the latest state"); + } + + require(!stateExists(id, newState), "New state already exists"); + + _stateData.addState(id, newState); + + uint256 gistKey = PoseidonUnit1L.poseidon([id]); + + if (isOldStateGenesis) { + _gistData.addLeaf(gistKey, newState); + } else { + _gistData.updateLeaf(gistKey, oldState, newState); + } +} +``` + +### Why this is the correct model +- GIST key remains `Poseidon(id)` +- leaf value changes from state to state +- this preserves verifier / proof model compatibility +- repeated issuer state transitions no longer panic inside SMT + +--- + +## 3. Poseidon deployment rule + +### Important +Do **not** deploy placeholder `Poseidon.sol` libraries directly with raw `getContractFactory("PoseidonUnit...")` in custom scripts/tests. + +### Correct approach +Use the repo helper: + +```ts +import { deployPoseidons } from "../../helpers/PoseidonDeployHelper"; + +const [poseidon1, poseidon2, poseidon3] = await deployPoseidons([1, 2, 3], "basic"); +``` + +This is the path that generated real Poseidon bytecode and made the state regression test pass. + +--- + +## 4. Regression test to keep permanently + +### File +`test/state/adi-eth-two-step-transition.test.ts` + +### Purpose +Validates repeated issuer state transitions for the same ETH issuer. + +### Final working test structure +```ts +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { deployPoseidons } from "../../helpers/PoseidonDeployHelper"; + +describe("ADI ETH issuer multi-step state transition", function () { + it("supports five sequential transitions for the same ETH issuer", async function () { + const [deployer, issuer] = await ethers.getSigners(); + + const idType = "0x01f9"; + + const CrossChainProofValidator = await ethers.getContractFactory("CrossChainProofValidator"); + const crossChainProofValidator = await CrossChainProofValidator.deploy( + "iden3", + "1", + await deployer.getAddress(), + ); + await crossChainProofValidator.waitForDeployment(); + + const Groth16VerifierStateTransition = await ethers.getContractFactory( + "Groth16VerifierStateTransition", + ); + const groth16VerifierStateTransition = await Groth16VerifierStateTransition.deploy(); + await groth16VerifierStateTransition.waitForDeployment(); + + const [poseidon1, poseidon2, poseidon3] = await deployPoseidons([1, 2, 3], "basic"); + + const poseidon1Hash = await poseidon1["poseidon(uint256[1])"]([123n]); + const poseidon3HashA = await poseidon3["poseidon(uint256[3])"]([0n, 111n, 1n]); + const poseidon3HashB = await poseidon3["poseidon(uint256[3])"]([0n, 222n, 1n]); + + expect(poseidon1Hash).to.not.equal(0n); + expect(poseidon3HashA).to.not.equal(0n); + expect(poseidon3HashB).to.not.equal(0n); + expect(poseidon3HashA).to.not.equal(poseidon3HashB); + + const SmtLibFactory = await ethers.getContractFactory("SmtLib", { + libraries: { + PoseidonUnit2L: await poseidon2.getAddress(), + PoseidonUnit3L: await poseidon3.getAddress(), + }, + }); + const smtLib = await SmtLibFactory.deploy(); + await smtLib.waitForDeployment(); + + const StateLibFactory = await ethers.getContractFactory("StateLib"); + const stateLib = await StateLibFactory.deploy(); + await stateLib.waitForDeployment(); + + const StateCrossChainLibFactory = await ethers.getContractFactory("StateCrossChainLib"); + const stateCrossChainLib = await StateCrossChainLibFactory.deploy(); + await stateCrossChainLib.waitForDeployment(); + + const StateFactory = await ethers.getContractFactory("State", { + libraries: { + PoseidonUnit1L: await poseidon1.getAddress(), + SmtLib: await smtLib.getAddress(), + StateLib: await stateLib.getAddress(), + StateCrossChainLib: await stateCrossChainLib.getAddress(), + }, + }); + + const stateImpl = await StateFactory.deploy(); + await stateImpl.waitForDeployment(); + + const TransparentUpgradeableProxyFactory = await ethers.getContractFactory( + "TransparentUpgradeableProxy", + ); + + const proxy = await TransparentUpgradeableProxyFactory.deploy( + await stateImpl.getAddress(), + await deployer.getAddress(), + "0x", + ); + await proxy.waitForDeployment(); + + const state = StateFactory.attach(await proxy.getAddress()); + + const initTx = await state.initialize( + await groth16VerifierStateTransition.getAddress(), + idType, + await deployer.getAddress(), + await crossChainProofValidator.getAddress(), + ); + await initTx.wait(); + + const GenesisUtilsWrapperFactory = await ethers.getContractFactory("GenesisUtilsWrapper"); + const genesisWrapper = await GenesisUtilsWrapperFactory.deploy(); + await genesisWrapper.waitForDeployment(); + + const issuerAddress = await issuer.getAddress(); + const issuerId = await genesisWrapper.calcOnchainIdFromAddress(idType, issuerAddress); + + const gistKey = await poseidon1["poseidon(uint256[1])"]([issuerId]); + expect(gistKey).to.not.equal(0n); + + const states = [111n, 222n, 333n, 444n, 555n]; + + const tx1 = await state + .connect(issuer) + .transitStateGeneric(issuerId, 0n, states[0], true, 1, "0x"); + await tx1.wait(); + + expect(await state.idExists(issuerId)).to.equal(true); + expect(await state.stateExists(issuerId, states[0])).to.equal(true); + + let latest = await state.getStateInfoById(issuerId); + expect(latest.state).to.equal(states[0]); + + for (let i = 1; i < states.length; i++) { + const tx = await state + .connect(issuer) + .transitStateGeneric(issuerId, states[i - 1], states[i], false, 1, "0x"); + await tx.wait(); + + expect(await state.stateExists(issuerId, states[i])).to.equal(true); + + latest = await state.getStateInfoById(issuerId); + expect(latest.state).to.equal(states[i]); + } + + for (const s of states) { + expect(await state.stateExists(issuerId, s)).to.equal(true); + } + + const finalStateInfo = await state.getStateInfoById(issuerId); + expect(finalStateInfo.state).to.equal(states[states.length - 1]); + }); +}); +``` + +### If future state logic changes +Update only these parts first: +- `idType` +- expected transition method +- number of sequential states in `states = [...]` +- final assertions + +Do **not** change the GIST model unless verifier/circuit compatibility is revalidated. + +--- + +## 5. Standard deployment path used + +### Command order +```bash +npx hardhat run scripts/deploy/deployLibraries.ts --network adi-testnet +npx hardhat run scripts/deploy/deployState.ts --network adi-testnet +npx hardhat run scripts/deploy/deployIdentityTreeStore.ts --network adi-testnet +npx hardhat run scripts/deploy/deployUniversalVerifier.ts --network adi-testnet +npx hardhat run scripts/deploy/deployValidators.ts --network adi-testnet +``` + +### Why standard scripts were used +The repo already uses: +- `DeployHelper` +- `helpers/constants.ts` +- deployment outputs under `scripts/deployments_output/*.json` + +So the custom `chain-99999.json` path was **not** kept as the live deployment input. + +--- + +## 6. ADI testnet deployed addresses + +### Core +```txt +State 0x1049f3a8e81f91d00E65DB46519778A5d178b37E +IdentityTreeStore 0x6a08cE6f467399169233BcC58F7C356C7bD81E66 +UniversalVerifier 0x33bfDC76C575d3858468E4feCb60Ec852C7817D5 +``` + +### State dependencies +```txt +Groth16VerifierStateTransition 0xBbd4110e7F0aB57B192e482A3310fF7ef26f30bd +StateLib 0x0e17A51149ae37DA4fBE0B7d701dc63ACB8EC749 +StateCrossChainLib 0x36B5F56da240926ad5983638e685291D5eDa0190 +CrossChainProofValidator 0xd9E7B503530e7578682ABb26D381B5fbD3baD17c +``` + +### Libraries +```txt +Poseidon1 0xd54ff97c6298CC16E16b3e6865F8046ef67081cB +Poseidon2 0x50335a02100eE83FDC31F611f90B9435bc0B7524 +Poseidon3 0xa6ff06E89Ce6Ca739a520edbb5c7C38533954301 +Poseidon4 0xe3069ff2dD77D708B283c86cD2aEd50921A5f906 +SmtLib 0x61f88be5a24ddff8bD6Efcd2C6aD7a33D40588A0 +VerifierLib 0x7e22e4239a5568886901E73505d005D8513E42d3 +``` + +### Validators +```txt +Groth16VerifierMTPWrapper 0x77Afafdc8978DdE8AAc11745F2cD1B9F0555523C +CredentialAtomicQueryMTPV2 0xaaAeb1093e01660f038B8D0600bEfE8095c81fc7 + +Groth16VerifierSigWrapper 0xBdEcc59dff3343c5A0a59BC7064ba54DCf9bdEdF +CredentialAtomicQuerySigV2 0x92E55fFFE4A46fC882A94310992ffD440Ed605D3 + +Groth16VerifierV3Wrapper 0x9b7EaAf7Ef32B07F4D177f27487ab660246e852e +CredentialAtomicQueryV3 0xC973cAEAE87036e160e82052e9815814fD80C6af + +Groth16VerifierAuthV2Wrapper 0xbF7d8118e4F37feA0882C66a4083a6178e65D2C8 +AuthV2Validator 0x960105FBdA5972721463F36a8f1CFA2dbD24C001 +``` + +--- + +## 7. Post-deploy check script to keep + +### File: `scripts/deploy/adi/checkState.ts` +Use this one as the standard health check. + +```ts +import { ethers } from "hardhat"; + +async function main() { + const stateAddress = "0x1049f3a8e81f91d00E65DB46519778A5d178b37E"; + + const state = await ethers.getContractAt("State", stateAddress); + + const defaultIdType = await state.getDefaultIdType(); + const verifier = await state.getVerifier(); + const crossChainProofValidator = await state.getCrossChainProofValidator(); + const gistRoot = await state.getGISTRoot(); + const gistHistoryLength = await state.getGISTRootHistoryLength(); + const isSupported = await state.isIdTypeSupported("0x01f9"); + + console.log("State:", stateAddress); + console.log("defaultIdType:", defaultIdType); + console.log("verifier:", verifier); + console.log("crossChainProofValidator:", crossChainProofValidator); + console.log("getGISTRoot:", gistRoot.toString()); + console.log("getGISTRootHistoryLength:", gistHistoryLength.toString()); + console.log("isIdTypeSupported(0x01f9):", isSupported); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); +``` + +### Expected output after fresh deploy +```txt +State: 0x1049f3a8e81f91d00E65DB46519778A5d178b37E +defaultIdType: 0x01f9 +verifier: 0xBbd4110e7F0aB57B192e482A3310fF7ef26f30bd +crossChainProofValidator: 0xd9E7B503530e7578682ABb26D381B5fbD3baD17c +getGISTRoot: 0 +getGISTRootHistoryLength: 1 +isIdTypeSupported(0x01f9): true +``` + +--- + +## 8. What to update in services + +### Issuer / verifier / app configs must use these fresh ADI addresses +```txt +State 0x1049f3a8e81f91d00E65DB46519778A5d178b37E +IdentityTreeStore 0x6a08cE6f467399169233BcC58F7C356C7bD81E66 +UniversalVerifier 0x33bfDC76C575d3858468E4feCb60Ec852C7817D5 +``` + +### Validators to wire if required by verifier config +```txt +MTP Validator 0xaaAeb1093e01660f038B8D0600bEfE8095c81fc7 +SIG Validator 0x92E55fFFE4A46fC882A94310992ffD440Ed605D3 +V3 Validator 0xC973cAEAE87036e160e82052e9815814fD80C6af +AuthV2 Validator 0x960105FBdA5972721463F36a8f1CFA2dbD24C001 +``` + +### Rule +Do not mix any previous State / verifier / ITS addresses with this new deployment set. + +--- + +## 9. Mainnet preparation block + +When ADI mainnet is ready, update these only. + +### 9.1 `helpers/constants.ts` +Add a new chain map entry: + +```ts +.set(, { + idType: "", + networkType: "main", + oracleSigningAddress: "", +}); // adi-mainnet +``` + +### 9.2 Hardhat network config +Add the ADI mainnet network in `hardhat.config.ts`: + +```ts +adi-mainnet: { + url: process.env.ADI_MAINNET_RPC_URL, + chainId: , + accounts: [process.env.PRIVATE_KEY!], +}, +``` + +### 9.3 Environment variables +Add: + +```bash +ADI_MAINNET_RPC_URL= +PRIVATE_KEY= +``` + +### 9.4 Re-run same deployment order +```bash +npx hardhat run scripts/deploy/deployLibraries.ts --network adi-mainnet +npx hardhat run scripts/deploy/deployState.ts --network adi-mainnet +npx hardhat run scripts/deploy/deployIdentityTreeStore.ts --network adi-mainnet +npx hardhat run scripts/deploy/deployUniversalVerifier.ts --network adi-mainnet +npx hardhat run scripts/deploy/deployValidators.ts --network adi-mainnet +``` + +### 9.5 Replace addresses below after mainnet deployment +```txt +State TBD +IdentityTreeStore TBD +UniversalVerifier TBD +CrossChainProofValidator TBD +VerifierLib TBD +MTP Validator TBD +SIG Validator TBD +V3 Validator TBD +AuthV2 Validator TBD +``` + +--- + +## 10. Final reminder + +### The minimum safety set to keep in the repo +- `helpers/constants.ts` ADI chain entry +- final `State.sol` transition logic +- `adi-eth-two-step-transition.test.ts` +- `scripts/deploy/adi/checkState.ts` +- this document + +These are the minimum references needed to reproduce ADI deployment and understand what must change for mainnet later. + diff --git a/contracts/lib/SmtLib.sol b/contracts/lib/SmtLib.sol index 809fb86c..48cc6752 100644 --- a/contracts/lib/SmtLib.sol +++ b/contracts/lib/SmtLib.sol @@ -11,6 +11,22 @@ import {ArrayUtils} from "./ArrayUtils.sol"; // versions of this library, without changing the existing state variables // In this way all the SMT data may be preserved for the contracts already in production. library SmtLib { + + + error NodeHashConflict( + uint256 nodeHash, + uint8 existingNodeType, + uint8 newNodeType, + uint256 existingChildLeft, + uint256 newChildLeft, + uint256 existingChildRight, + uint256 newChildRight, + uint256 existingIndex, + uint256 newIndex, + uint256 existingValue, + uint256 newValue + ); + /** * @dev Max return array length for SMT root history requests */ @@ -156,6 +172,20 @@ library SmtLib { _addEntry(self, newRoot, block.timestamp, block.number); } + function updateLeaf( + Data storage self, + uint256 i, + uint256 oldV, + uint256 newV + ) external onlyInitialized(self) { + require(newV != 0, "New leaf value should not be zero"); + + uint256 prevRoot = getRoot(self); + uint256 newRoot = _updateLeaf(self, i, oldV, newV, prevRoot, 0); + + _addEntry(self, newRoot, block.timestamp, block.number); + } + /** * @dev Get SMT root history length * @return SMT history length @@ -493,6 +523,80 @@ library SmtLib { return leafHash; } + function _updateLeaf( + Data storage self, + uint256 index, + uint256 oldValue, + uint256 newValue, + uint256 nodeHash, + uint256 depth + ) internal returns (uint256) { + if (depth > self.maxDepth) { + revert("Max depth reached"); + } + + Node memory node = self.nodes[nodeHash]; + + if (node.nodeType == NodeType.EMPTY) { + revert("Leaf does not exist"); + } + + if (node.nodeType == NodeType.LEAF) { + require(node.index == index, "Leaf index mismatch"); + require(node.value == oldValue, "Old value mismatch"); + + Node memory newLeaf = Node({ + nodeType: NodeType.LEAF, + childLeft: 0, + childRight: 0, + index: index, + value: newValue + }); + + return _addNode(self, newLeaf); + } + + Node memory newNode; + + if ((index >> depth) & 1 == 1) { + uint256 updatedRight = _updateLeaf( + self, + index, + oldValue, + newValue, + node.childRight, + depth + 1 + ); + + newNode = Node({ + nodeType: NodeType.MIDDLE, + childLeft: node.childLeft, + childRight: updatedRight, + index: 0, + value: 0 + }); + } else { + uint256 updatedLeft = _updateLeaf( + self, + index, + oldValue, + newValue, + node.childLeft, + depth + 1 + ); + + newNode = Node({ + nodeType: NodeType.MIDDLE, + childLeft: updatedLeft, + childRight: node.childRight, + index: 0, + value: 0 + }); + } + + return _addNode(self, newNode); + } + function _pushLeaf( Data storage self, Node memory newLeaf, @@ -547,15 +651,32 @@ library SmtLib { function _addNode(Data storage self, Node memory node) internal returns (uint256) { uint256 nodeHash = _getNodeHash(node); - // We don't have any guarantees if the hash function attached is good enough. - // So, if the node hash already exists, we need to check - // if the node in the tree exactly matches the one we are trying to add. + if (self.nodes[nodeHash].nodeType != NodeType.EMPTY) { - assert(self.nodes[nodeHash].nodeType == node.nodeType); - assert(self.nodes[nodeHash].childLeft == node.childLeft); - assert(self.nodes[nodeHash].childRight == node.childRight); - assert(self.nodes[nodeHash].index == node.index); - assert(self.nodes[nodeHash].value == node.value); + Node memory existing = self.nodes[nodeHash]; + + if ( + existing.nodeType != node.nodeType || + existing.childLeft != node.childLeft || + existing.childRight != node.childRight || + existing.index != node.index || + existing.value != node.value + ) { + revert NodeHashConflict( + nodeHash, + uint8(existing.nodeType), + uint8(node.nodeType), + existing.childLeft, + node.childLeft, + existing.childRight, + node.childRight, + existing.index, + node.index, + existing.value, + node.value + ); + } + return nodeHash; } diff --git a/contracts/state/State.sol b/contracts/state/State.sol index ed6f5b42..c683a002 100644 --- a/contracts/state/State.sol +++ b/contracts/state/State.sol @@ -7,6 +7,7 @@ import {IStateTransitionVerifier} from "../interfaces/IStateTransitionVerifier.s import {SmtLib} from "../lib/SmtLib.sol"; import {PoseidonUnit1L} from "../lib/Poseidon.sol"; import {StateLib} from "../lib/StateLib.sol"; +import {StateCrossChainLib} from "../lib/StateCrossChainLib.sol"; import {GenesisUtils} from "../lib/GenesisUtils.sol"; import {ICrossChainProofValidator} from "../interfaces/ICrossChainProofValidator.sol"; @@ -15,15 +16,7 @@ contract State is Ownable2StepUpgradeable, IState { /** * @dev Version of contract */ - string public constant VERSION = "2.6.3"; - /** - * @dev Global state proof type - */ - bytes32 private constant GLOBAL_STATE_PROOF_TYPE = keccak256(bytes("globalStateProof")); - /** - * @dev State proof type - */ - bytes32 private constant STATE_PROOF_TYPE = keccak256(bytes("stateProof")); + string public constant VERSION = "2.6.1"; // This empty reserved space is put in place to allow future versions // of the State contract to inherit from other contracts without a risk of @@ -60,34 +53,34 @@ contract State is Ownable2StepUpgradeable, IState { */ bool internal _defaultIdTypeInitialized; - /// @custom:storage-location erc7201:iden3.storage.StateCrossChain - struct StateCrossChainStorage { - mapping(uint256 id => mapping(uint256 state => uint256 replacedAt)) _idToStateReplacedAt; - mapping(bytes2 idType => mapping(uint256 root => uint256 replacedAt)) _rootToGistRootReplacedAt; - ICrossChainProofValidator _crossChainProofValidator; - } - // keccak256(abi.encode(uint256(keccak256("iden3.storage.StateCrossChain")) - 1)) // & ~bytes32(uint256(0xff)); - // solhint-disable-next-line const-name-snakecase bytes32 private constant StateCrossChainStorageLocation = 0xfe6de916382846695d2555237dc6c0ef6555f4c949d4ba263e03532600778100; - function _getStateCrossChainStorage() private pure returns (StateCrossChainStorage storage $) { - // solhint-disable-next-line no-inline-assembly - assembly { - $.slot := StateCrossChainStorageLocation - } + /// @custom:storage-location erc7201:iden3.storage.StateCrossChain + struct StateCrossChainStorage { + mapping(uint256 id => mapping(uint256 state => uint256 replacedAt)) _idToStateReplacedAt; + mapping(bytes2 idType => mapping(uint256 root => uint256 replacedAt)) _rootToGistRootReplacedAt; + ICrossChainProofValidator _crossChainProofValidator; + IState _state; } using SmtLib for SmtLib.Data; using StateLib for StateLib.Data; + using StateCrossChainLib for StateCrossChainStorage; /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } + function _getStateCrossChainStorage() private pure returns (StateCrossChainStorage storage $) { + assembly { + $.slot := StateCrossChainStorageLocation + } + } + /** * @dev Initialize the contract * @param verifierContractAddr Verifier address @@ -126,35 +119,12 @@ contract State is Ownable2StepUpgradeable, IState { } /** - * @dev Processes cross chain proofs. - * @param crossChainProofs The cross chain proofs. + * @dev Process cross chain proofs with identity and global state proofs + * @param proofs Cross chain proofs to be processed */ - function processCrossChainProofs(bytes calldata crossChainProofs) public { - if (crossChainProofs.length == 0) { - return; - } - - IState.CrossChainProof[] memory proofs = abi.decode( - crossChainProofs, - (IState.CrossChainProof[]) - ); - + function processCrossChainProofs(bytes calldata proofs) public { StateCrossChainStorage storage $ = _getStateCrossChainStorage(); - for (uint256 i = 0; i < proofs.length; i++) { - if (keccak256(bytes(proofs[i].proofType)) == GLOBAL_STATE_PROOF_TYPE) { - IState.GlobalStateProcessResult memory gsp = $ - ._crossChainProofValidator - .processGlobalStateProof(proofs[i].proof); - $._rootToGistRootReplacedAt[gsp.idType][gsp.root] = gsp.replacedAtTimestamp; - } else if (keccak256(bytes(proofs[i].proofType)) == STATE_PROOF_TYPE) { - IState.IdentityStateProcessResult memory isu = $ - ._crossChainProofValidator - .processIdentityStateProof(proofs[i].proof); - $._idToStateReplacedAt[isu.id][isu.state] = isu.replacedAtTimestamp; - } else { - revert("Unknown proof type"); - } - } + $.processCrossChainProofs(proofs); } /** @@ -509,26 +479,6 @@ contract State is Ownable2StepUpgradeable, IState { } } - /** - * @dev Check if the id type is supported and return the id type - * @param id Identity - * trows if id type is not supported - */ - function getIdTypeIfSupported(uint256 id) public view returns (bytes2) { - bytes2 idType = GenesisUtils.getIdType(id); - require(_stateData.isIdTypeSupported[idType], "id type is not supported"); - return idType; - } - - /** - * @dev Set supported IdType setter - * @param idType id type - * @param supported ability to enable or disable id type support - */ - function setSupportedIdType(bytes2 idType, bool supported) public onlyOwner { - _stateData.isIdTypeSupported[idType] = supported; - } - /** * @dev Change the state of an identity (transit to the new state) with ZKP ownership check. * @param id Identity @@ -559,8 +509,16 @@ contract State is Ownable2StepUpgradeable, IState { // this checks that oldState != newState as well require(!stateExists(id, newState), "New state already exists"); + _stateData.addState(id, newState); - _gistData.addLeaf(PoseidonUnit1L.poseidon([id]), newState); + + uint256 gistKey = PoseidonUnit1L.poseidon([id]); + + if (isOldStateGenesis) { + _gistData.addLeaf(gistKey, newState); + } else { + _gistData.updateLeaf(gistKey, oldState, newState); + } } function _smtProofAdapter( @@ -624,4 +582,24 @@ contract State is Ownable2StepUpgradeable, IState { _defaultIdTypeInitialized = true; _stateData.isIdTypeSupported[defaultIdType] = true; } + + /** + * @dev Check if the id type is supported and return the id type + * @param id Identity + * trows if id type is not supported + */ + function getIdTypeIfSupported(uint256 id) public view returns (bytes2) { + bytes2 idType = GenesisUtils.getIdType(id); + require(_stateData.isIdTypeSupported[idType], "id type is not supported"); + return idType; + } + + /** + * @dev Set supported IdType setter + * @param idType id type + * @param supported ability to enable or disable id type support + */ + function setSupportedIdType(bytes2 idType, bool supported) public onlyOwner { + _stateData.isIdTypeSupported[idType] = supported; + } } diff --git a/hardhat.config.ts b/hardhat.config.ts index 30e6adb0..4347cffa 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,31 +1,14 @@ -import { defineConfig } from "hardhat/config"; -import hardhatToolboxMochaEthers from "@nomicfoundation/hardhat-toolbox-mocha-ethers"; -import hardhatIgnitionPlugin from "@nomicfoundation/hardhat-ignition"; -import hardhatLedgerPlugin from "@nomicfoundation/hardhat-ledger"; -import hardhatContractSizer from "@solidstate/hardhat-contract-sizer"; -import hardhatVerify from "@nomicfoundation/hardhat-verify"; +import { HardhatUserConfig, task } from "hardhat/config"; +import "@typechain/hardhat"; +import "hardhat-gas-reporter"; +import "hardhat-contract-sizer"; +import "solidity-coverage"; +import "@openzeppelin/hardhat-upgrades"; +import "@nomicfoundation/hardhat-chai-matchers"; +import "@nomicfoundation/hardhat-verify"; +import "@nomicfoundation/hardhat-ignition-ethers"; +import "@nomicfoundation/hardhat-ledger"; import dotenv from "dotenv"; -import { - BASE_MAINNET_RPC_URL, - BASE_SEPOLIA_RPC_URL, - BILLIONS_MAINNET_RPC_URL, - BILLIONS_TESTNET_RPC_URL, - BNB_MAINNET_RPC_URL, - BNB_TESTNET_RPC_URL, - ETHEREUM_MAINNET_RPC_URL, - ETHEREUM_SEPOLIA_RPC_URL, - ETHERSCAN_API_KEY, - LEDGER_ACCOUNT, - LINEA_MAINNET_RPC_URL, - LINEA_SEPOLIA_RPC_URL, - POLYGON_AMOY_RPC_URL, - POLYGON_MAINNET_RPC_URL, - PRIVADO_MAINNET_RPC_URL, - PRIVADO_TESTNET_RPC_URL, - PRIVATE_KEY, - ZKEVM_CARDONA_RPC_URL, - ZKEVM_MAINNET_RPC_URL, -} from "./helpers/environment"; dotenv.config(); const DEFAULT_MNEMONIC = "test test test test test test test test test test test junk"; @@ -36,249 +19,137 @@ const DEFAULT_ACCOUNTS: any = { count: 20, }; -export default defineConfig({ - plugins: [ - hardhatToolboxMochaEthers, - hardhatIgnitionPlugin, - hardhatLedgerPlugin, - hardhatContractSizer, - hardhatVerify, - ], +// This is a sample Hardhat task. To learn how to create your own go to +// https://hardhat.org/guides/create-task.html +task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { + const accounts = await hre.ethers.getSigners(); + + for (const account of accounts) { + console.log(await account.getAddress()); + } +}); + +// You need to export an object to set up your config +// Go to https://hardhat.org/config/ to learn more + +/** + * @type import('hardhat/config').HardhatUserConfig + */ +const config: HardhatUserConfig = { solidity: { compilers: [ { version: "0.8.27", }, ], - npmFilesToBuild: [ - "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol", - "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol", - ], - overrides: { - "contracts/verifiers/UniversalVerifier.sol": { - version: "0.8.27", - settings: { - optimizer: { - enabled: true, - runs: 80, - }, - }, - }, - "contracts/test-helpers/VerifierTestWrapper.sol": { - version: "0.8.27", - settings: { - optimizer: { - enabled: true, - runs: 200, - }, - }, - }, - "contracts/test-helpers/UniversalVerifierTestWrapper_ManyResponsesPerUserAndRequest.sol": { - version: "0.8.27", - settings: { - optimizer: { - enabled: true, - runs: 80, - }, - }, - }, - "contracts/test-helpers/EmbeddedVerifierWrapper.sol": { - version: "0.8.27", - settings: { - optimizer: { - enabled: true, - runs: 200, - }, - }, - }, - "contracts/test-helpers/RequestDisableableTestWrapper.sol": { - version: "0.8.27", - settings: { - optimizer: { - enabled: true, - runs: 200, - }, - }, - }, - "contracts/test-helpers/RequestOwnershipTestWrapper.sol": { - version: "0.8.27", - settings: { - optimizer: { - enabled: true, - runs: 200, - }, - }, - }, - "contracts/test-helpers/ValidatorWhitelistTestWrapper.sol": { - version: "0.8.27", - settings: { - optimizer: { - enabled: true, - runs: 200, - }, - }, - }, - "contracts/state/State.sol": { - version: "0.8.27", - settings: { - optimizer: { - enabled: true, - runs: 200, - }, - }, - }, - "contracts/lib/VerifierLib.sol": { - version: "0.8.27", - settings: { - optimizer: { - enabled: true, - runs: 200, - }, - }, - }, - }, }, networks: { - "privado-mainnet": { - type: "http", + "privado-main": { chainId: 21000, - url: `${PRIVADO_MAINNET_RPC_URL}`, + url: `${process.env.PRIVADO_MAIN_RPC_URL}`, // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], + ledgerAccounts: [`${process.env.LEDGER_ACCOUNT}`], }, - "privado-testnet": { - type: "http", + "privado-test": { chainId: 21001, - url: `${PRIVADO_TESTNET_RPC_URL}`, + url: `${process.env.PRIVADO_TEST_RPC_URL}`, // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], - }, - "billions-mainnet": { - type: "http", - chainId: 45056, - url: `${BILLIONS_MAINNET_RPC_URL}`, - // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], - }, - "billions-testnet": { - type: "http", - chainId: 6913, - url: `${BILLIONS_TESTNET_RPC_URL}`, - // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], + ledgerAccounts: [`${process.env.LEDGER_ACCOUNT}`], }, "polygon-mainnet": { - type: "http", chainId: 137, - url: `${POLYGON_MAINNET_RPC_URL}`, + url: `${process.env.POLYGON_MAINNET_RPC_URL}`, // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], + ledgerAccounts: [`${process.env.LEDGER_ACCOUNT}`], }, "polygon-amoy": { - type: "http", chainId: 80002, - url: `${POLYGON_AMOY_RPC_URL}`, + url: `${process.env.POLYGON_AMOY_RPC_URL}`, // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], + ledgerAccounts: [`${process.env.LEDGER_ACCOUNT}`], }, "ethereum-mainnet": { - type: "http", chainId: 1, - url: `${ETHEREUM_MAINNET_RPC_URL}`, + url: `${process.env.ETHEREUM_MAINNET_RPC_URL}`, // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], + ledgerAccounts: [`${process.env.LEDGER_ACCOUNT}`], }, "ethereum-sepolia": { - type: "http", chainId: 11155111, - url: `${ETHEREUM_SEPOLIA_RPC_URL}`, + url: `${process.env.ETHEREUM_SEPOLIA_RPC_URL}`, // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], + ledgerAccounts: [`${process.env.LEDGER_ACCOUNT}`], }, "zkevm-mainnet": { - type: "http", chainId: 1101, - url: `${ZKEVM_MAINNET_RPC_URL}`, + url: `${process.env.ZKEVM_MAINNET_RPC_URL}`, // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], + ledgerAccounts: [`${process.env.LEDGER_ACCOUNT}`], }, "zkevm-cardona": { - type: "http", chainId: 2442, - url: `${ZKEVM_CARDONA_RPC_URL}`, + url: `${process.env.ZKEVM_CARDONA_RPC_URL}`, // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], + ledgerAccounts: [`${process.env.LEDGER_ACCOUNT}`], }, "linea-mainnet": { - type: "http", chainId: 59144, - url: `${LINEA_MAINNET_RPC_URL}`, + url: `${process.env.LINEA_MAINNET_RPC_URL}`, // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], + ledgerAccounts: [`${process.env.LEDGER_ACCOUNT}`], }, "linea-sepolia": { - type: "http", chainId: 59141, - url: `${LINEA_SEPOLIA_RPC_URL}`, - // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], - }, - "base-mainnet": { - type: "http", - chainId: 8453, - url: `${BASE_MAINNET_RPC_URL}`, + url: `${process.env.LINEA_SEPOLIA_RPC_URL}`, // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], + ledgerAccounts: [`${process.env.LEDGER_ACCOUNT}`], }, - "base-sepolia": { + "adi-testnet": { type: "http", - chainId: 84532, - url: `${BASE_SEPOLIA_RPC_URL}`, - // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], - }, - "bnb-mainnet": { - type: "http", - chainId: 56, - url: `${BNB_MAINNET_RPC_URL}`, - // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], + chainId: Number(process.env.ADI_CHAIN_ID || 99999), + url: process.env.ADI_RPC_URL!, + accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, + timeout: 120000, + httpHeaders: {}, }, - "bnb-testnet": { - type: "http", - chainId: 97, - url: `${BNB_TESTNET_RPC_URL}`, - // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, - ledgerAccounts: [`${LEDGER_ACCOUNT}`], - }, - // -------------------------------------------------------------------------------------------------------------- - // Note: uncomment to use a forked network and then run `npx hardhat node --fork` - // in some networks is needed to execute first a script with `await ethers.provider.send("evm_mine")` - // to mine a block. Otherwise you can receive an error: "No known hardfork for execution on historical block..." - // -------------------------------------------------------------------------------------------------------------- - // fork: { + // hardhat: { // chainId: 80002, - // type: "edr-simulated", // forking: { - // url: `${POLYGON_AMOY_RPC_URL}`, + // url: `${process.env.POLYGON_AMOY_RPC_URL}`, + // }, + // chains: { + // 80002: { + // hardforkHistory: { + // london: 10000000, + // }, + // }, // }, // accounts: [ // { - // privateKey: PRIVATE_KEY as string, + // privateKey: process.env.PRIVATE_KEY as string, // balance: "1000000000000000000000000", // }, // ], // }, localhost: { - type: "http", url: "http://127.0.0.1:8545", timeout: 100000000, // accounts: process.env.PRIVATE_KEY ? [`0x${process.env.PRIVATE_KEY}`] : DEFAULT_ACCOUNTS, }, }, - typechain: { - outDir: "typechain", - discriminateTypes: true, + gasReporter: { + currency: "USD", + coinmarketcap: process.env.COINMARKETCAP_KEY, + enabled: !!process.env.REPORT_GAS, + token: "MATIC", + gasPriceApi: "https://api.polygonscan.com/api?module=proxy&action=eth_gasPrice", // MATIC + // gasPriceAPI: "https://api.etherscan.io/api?module=proxy&action=eth_gasPrice", // ETH + }, + contractSizer: { + alphaSort: false, + disambiguatePaths: false, + runOnCompile: true, + strict: false, }, ignition: { strategyConfig: { @@ -300,38 +171,64 @@ export default defineConfig({ // -> In our case f4179bc3e4988a1a06f8d1 }, }, + requiredConfirmations: 5, }, - verify: { - etherscan: { - apiKey: ETHERSCAN_API_KEY, - }, - }, - chainDescriptors: { - 6913: { - name: "billions-testnet", - blockExplorers: { - blockscout: { - name: "billions-testnet", - url: "https://billions-testnet-blockscout.eu-north-2.gateway.fm", - apiUrl: "https://billions-testnet-blockscout.eu-north-2.gateway.fm/api/", + + etherscan: { + apiKey: { + "polygon-amoy": process.env.POLYGON_EXPLORER_API_KEY || "", + polygon: process.env.POLYGON_EXPLORER_API_KEY || "", + sepolia: process.env.ETHEREUM_EXPLORER_API_KEY || "", + mainnet: process.env.ETHEREUM_EXPLORER_API_KEY || "", + "linea-mainnet": process.env.LINEA_EXPLORER_API_KEY || "", + "linea-sepolia": process.env.LINEA_EXPLORER_API_KEY || "", + "zkevm-cardona": process.env.ZKEVM_EXPLORER_API_KEY || "", + "zkevm-mainnet": process.env.ZKEVM_EXPLORER_API_KEY || "", + }, + customChains: [ + { + network: "polygon-amoy", + chainId: 80002, + urls: { + apiURL: "https://api-amoy.polygonscan.com/api", + browserURL: "https://docs.polygonscan.com", }, }, - }, - 45056: { - name: "billions-mainnet", - blockExplorers: { - blockscout: { - name: "billions-mainnet", - url: "https://billions-rpc.eu-north-2.gateway.fm", - apiUrl: "https://billions-rpc.eu-north-2.gateway.fm/api/", + { + network: "linea-sepolia", + chainId: 59141, + urls: { + apiURL: "https://api-sepolia.lineascan.build/api", + browserURL: "https://docs.lineascan.build/sepolia-lineascan", }, }, - }, - }, - contractSizer: { - alphaSort: false, - runOnCompile: false, - strict: false, - flat: true, + { + network: "linea-mainnet", + chainId: 59144, + urls: { + apiURL: "https://api.lineascan.build/api", + browserURL: "https://docs.lineascan.build", + }, + }, + { + network: "zkevm-cardona", + chainId: 2442, + urls: { + apiURL: "https://api-cardona-zkevm.polygonscan.com/api", + browserURL: "https://docs.polygonscan.com/cardona-polygon-zkevm", + }, + }, + { + network: "zkevm-mainnet", + chainId: 1101, + urls: { + apiURL: "https://api-zkevm.polygonscan.com/api", + browserURL: "https://docs.polygonscan.com/polygon-zkevm", + }, + + }, + ], }, -}); +}; + +export default config; diff --git a/helpers/constants.ts b/helpers/constants.ts index d7cdf1ed..12b56f32 100644 --- a/helpers/constants.ts +++ b/helpers/constants.ts @@ -1,22 +1,13 @@ // HARDHAT network Oracle signing address -import { network } from "hardhat"; - -const { ethers } = await network.connect(); +import { ethers } from "hardhat"; export const DEFAULT_MNEMONIC = "test test test test test test test test test test test junk"; -export const ORACLE_SIGNING_ADDRESS_HARDHAT = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; -export const LEGACY_ORACLE_SIGNING_ADDRESS_HARDHAT = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"; - +const ORACLE_SIGNING_ADDRESS_HARDHAT = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; +// TEST networks Oracle signing address (For now we will use in testnets the same production signing address) +export const ORACLE_SIGNING_ADDRESS_TEST = "0x3e1cFE1b83E7C1CdB0c9558236c1f6C7B203C34e"; // PRODUCTION networks Oracle signing address -export const ORACLE_SIGNING_ADDRESS_PRODUCTION = "0x0aD316c6D3F29B76cBd8f5a1ED5e3990c6B5174C"; -export const LEGACY_ORACLE_SIGNING_ADDRESS_PRODUCTION = - "0xf0Ae6D287aF14f180E1FAfe3D2CB62537D7b1A82"; - -export const SMT_MAX_DEPTH = 64; - -export type Groth16VerifierType = "mtpV2" | "sigV2" | "v3" | "lmq10" | "authV2" | undefined; -export type ValidatorType = "mtpV2" | "sigV2" | "v3" | "lmq" | "authV2" | "ethIdentity"; +export const ORACLE_SIGNING_ADDRESS_PRODUCTION = "0xf0Ae6D287aF14f180E1FAfe3D2CB62537D7b1A82"; type ChainIdInfo = { idType: string; @@ -65,62 +56,35 @@ export const chainIdInfoMap: Map = new Map() networkType: "test", oracleSigningAddress: ORACLE_SIGNING_ADDRESS_PRODUCTION, }) // ethereum sepolia - .set(45056, { - idType: "0x01B1", - networkType: "main", - oracleSigningAddress: ORACLE_SIGNING_ADDRESS_PRODUCTION, - }) // billions-mainnet - .set(6913, { - idType: "0x01B2", - networkType: "test", - oracleSigningAddress: ORACLE_SIGNING_ADDRESS_PRODUCTION, - }) // billions-testnet .set(21000, { idType: "0x01A1", networkType: "main", oracleSigningAddress: ORACLE_SIGNING_ADDRESS_PRODUCTION, - }) // privado-mainnet + }) // privado-main .set(21001, { idType: "0x01A2", networkType: "test", oracleSigningAddress: ORACLE_SIGNING_ADDRESS_PRODUCTION, - }) // privado-testnet + }) // privado-test .set(59144, { idType: "0x0149", networkType: "main", oracleSigningAddress: ORACLE_SIGNING_ADDRESS_PRODUCTION, - }) // linea-mainnet + }) // linea-main .set(59141, { idType: "0x0148", networkType: "test", oracleSigningAddress: ORACLE_SIGNING_ADDRESS_PRODUCTION, }) // linea-sepolia - .set(8453, { - idType: "0x0151", - networkType: "main", - oracleSigningAddress: ORACLE_SIGNING_ADDRESS_PRODUCTION, - }) // base-mainnet - .set(84532, { - idType: "0x0152", - networkType: "test", - oracleSigningAddress: ORACLE_SIGNING_ADDRESS_PRODUCTION, - }) // base-sepolia - .set(56, { - idType: "0x0161", - networkType: "main", - oracleSigningAddress: ORACLE_SIGNING_ADDRESS_PRODUCTION, - }) // bnb-mainnet - .set(97, { - idType: "0x0162", + .set(99999, { + idType: "0x01f9", networkType: "test", oracleSigningAddress: ORACLE_SIGNING_ADDRESS_PRODUCTION, - }); // bnb-testnet + }); // adi-testnet export const networks = Object.freeze({ - PRIVADO_TESTNET: { name: "Privado Testnet", chainId: 21001 }, - PRIVADO_MAINNET: { name: "Privado Mainnet", chainId: 21000 }, - BILLIONS_TESTNET: { name: "Billions Testnet", chainId: 6913 }, - BILLIONS_MAINNET: { name: "Billions Mainnet", chainId: 45056 }, + PRIVADO_TEST: { name: "Privado Test", chainId: 21001 }, + PRIVADO_MAIN: { name: "Privado Main", chainId: 21000 }, POLYGON_AMOY: { name: "Polygon Amoy", chainId: 80002 }, POLYGON_MAINNET: { name: "Polygon Mainnet", chainId: 137 }, ETHEREUM_SEPOLIA: { name: "Ethereum Sepolia", chainId: 11155111 }, @@ -129,10 +93,6 @@ export const networks = Object.freeze({ ZKEVM_MAINNET: { name: "Zkevm Mainnet", chainId: 1101 }, LINEA_SEPOLIA: { name: "Linea Sepolia", chainId: 59141 }, LINEA_MAINNET: { name: "Linea Mainnet", chainId: 59144 }, - BASE_SEPOLIA: { name: "Base Sepolia", chainId: 84532 }, - BASE_MAINNET: { name: "Base Mainnet", chainId: 8453 }, - BNB_MAINNET: { name: "Bnb Mainnet", chainId: 56 }, - BNB_TESTNET: { name: "Bnb Testnet", chainId: 97 }, }); export const STATE_ADDRESS_POLYGON_AMOY = "0x1a4cC30f2aA0377b0c3bc9848766D90cb4404124"; @@ -153,16 +113,16 @@ export const contractsInfo = Object.freeze({ }, UNIVERSAL_VERIFIER: { name: "UniversalVerifier", - version: "2.2.0", - unifiedAddress: "0x2B0D3f664A5EbbfBD76E6cbc2cA9A504a68d2F4F", - create2Calldata: ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.UniversalVerifier.v2")), + version: "1.1.6", + unifiedAddress: "0xfcc86A79fCb057A8e55C6B853dff9479C3cf607c", + create2Calldata: ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.UniversalVerifier")), verificationOpts: { // For verifying the different contracts with proxy we need verification with different constructor arguments constructorArgsImplementation: [], constructorArgsProxy: [ "0x56fF81aBB5cdaC478bF236db717e4976b2ff841e", "0xae15d2023a76174a940cbb2b7f44012c728b9d74", - ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.UniversalVerifier.v2")), + "0x6964656e332e637265617465322e556e6976657273616c5665726966696572", ], constructorArgsProxyAdmin: ["0xAe15d2023A76174a940cbb2b7F44012C728B9d74"], libraries: {}, @@ -170,7 +130,7 @@ export const contractsInfo = Object.freeze({ }, STATE: { name: "State", - version: "2.6.3", + version: "2.6.1", unifiedAddress: "0x3C9acB2205Aa72A05F6D77d708b5Cf85FCa3a896", create2Calldata: ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.State")), verificationOpts: { @@ -178,7 +138,7 @@ export const contractsInfo = Object.freeze({ constructorArgsProxy: [ "0x56fF81aBB5cdaC478bF236db717e4976b2ff841e", "0xae15d2023a76174a940cbb2b7f44012c728b9d74", - ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.State")), + "0x6964656e332e637265617465322e556e6976657273616c5665726966696572", ], constructorArgsProxyAdmin: ["0xAe15d2023A76174a940cbb2b7F44012C728B9d74"], libraries: {}, @@ -186,17 +146,17 @@ export const contractsInfo = Object.freeze({ }, VALIDATOR_SIG: { name: "CredentialAtomicQuerySigV2Validator", - version: "3.1.0", - unifiedAddress: "0x5BD60F3Ef5890260906172EEe1f0a965707791f1", + version: "2.1.1", + unifiedAddress: "0x59B347f0D3dd4B98cc2E056Ee6C53ABF14F8581b", create2Calldata: ethers.hexlify( - ethers.toUtf8Bytes("iden3.create2.CredentialAtomicQuerySigV2Validator.v3"), + ethers.toUtf8Bytes("iden3.create2.CredentialAtomicQuerySigV2Validator"), ), verificationOpts: { constructorArgsImplementation: [], constructorArgsProxy: [ "0x56fF81aBB5cdaC478bF236db717e4976b2ff841e", "0xae15d2023a76174a940cbb2b7f44012c728b9d74", - ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.CredentialAtomicQuerySigV2Validator.v3")), + "0x6964656e332e637265617465322e556e6976657273616c5665726966696572", ], constructorArgsProxyAdmin: ["0xAe15d2023A76174a940cbb2b7F44012C728B9d74"], libraries: {}, @@ -204,17 +164,17 @@ export const contractsInfo = Object.freeze({ }, VALIDATOR_MTP: { name: "CredentialAtomicQueryMTPV2Validator", - version: "3.1.0", - unifiedAddress: "0xec9EF9c4595B46abF2b6A923BD1529081E03fbBB", + version: "2.1.1", + unifiedAddress: "0x27bDFFCeC5478a648f89764E22fE415486A42Ede", create2Calldata: ethers.hexlify( - ethers.toUtf8Bytes("iden3.create2.CredentialAtomicQueryMTPV2Validator.v3"), + ethers.toUtf8Bytes("iden3.create2.CredentialAtomicQueryMTPV2Validator"), ), verificationOpts: { constructorArgsImplementation: [], constructorArgsProxy: [ "0x56fF81aBB5cdaC478bF236db717e4976b2ff841e", "0xae15d2023a76174a940cbb2b7f44012c728b9d74", - ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.CredentialAtomicQueryMTPV2Validator.v3")), + "0x6964656e332e637265617465322e556e6976657273616c5665726966696572", ], constructorArgsProxyAdmin: ["0xAe15d2023A76174a940cbb2b7F44012C728B9d74"], libraries: {}, @@ -222,65 +182,33 @@ export const contractsInfo = Object.freeze({ }, VALIDATOR_V3: { name: "CredentialAtomicQueryV3Validator", - version: "3.1.0-beta.1", - unifiedAddress: "0xC616963610A5545EF89b373e1fEAE8A1e505FaFF", + version: "2.1.1-beta.1", + unifiedAddress: "0xd179f29d00Cd0E8978eb6eB847CaCF9E2A956336", create2Calldata: ethers.hexlify( - ethers.toUtf8Bytes("iden3.create2.CredentialAtomicQueryV3Validator.v3"), + ethers.toUtf8Bytes("iden3.create2.CredentialAtomicQueryV3Validator"), ), verificationOpts: { constructorArgsImplementation: [], constructorArgsProxy: [ "0x56fF81aBB5cdaC478bF236db717e4976b2ff841e", "0xae15d2023a76174a940cbb2b7f44012c728b9d74", - ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.CredentialAtomicQueryV3Validator.v3")), + "0x6964656e332e637265617465322e556e6976657273616c5665726966696572", ], constructorArgsProxyAdmin: ["0xAe15d2023A76174a940cbb2b7F44012C728B9d74"], libraries: {}, }, }, - VALIDATOR_LINKED_MULTI_QUERY: { - name: "LinkedMultiQueryValidator", - version: "1.0.0-beta.1", - unifiedAddress: "0xfA622418d7aBF33868545732CaD2C2E7ce9B16C8", - create2Calldata: ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.LinkedMultiQueryValidator")), - verificationOpts: { - constructorArgsImplementation: [], - constructorArgsProxy: [ - "0x56fF81aBB5cdaC478bF236db717e4976b2ff841e", - "0xae15d2023a76174a940cbb2b7f44012c728b9d74", - ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.LinkedMultiQueryValidator")), - ], - constructorArgsProxyAdmin: ["0xAe15d2023A76174a940cbb2b7f44012c728b9d74"], - libraries: {}, - }, - }, VALIDATOR_AUTH_V2: { name: "AuthV2Validator", version: "1.0.0", - unifiedAddress: "0x535F6a1B30533616CE4bD44081ea7A17CF2042B8", + unifiedAddress: "0x49ebdC163fa014F310CeDBc8e4a0b15C738D8073", create2Calldata: ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.AuthV2Validator")), verificationOpts: { constructorArgsImplementation: [], constructorArgsProxy: [ "0x56fF81aBB5cdaC478bF236db717e4976b2ff841e", "0xae15d2023a76174a940cbb2b7f44012c728b9d74", - ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.AuthV2Validator")), - ], - constructorArgsProxyAdmin: ["0xAe15d2023A76174a940cbb2b7F44012C728B9d74"], - libraries: {}, - }, - }, - VALIDATOR_ETH_IDENTITY: { - name: "EthIdentityValidator", - version: "1.0.0", - unifiedAddress: "0x8546bFd67F19dd0449dF73fb75A56BC9ddFA57Db", - create2Calldata: ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.EthIdentityValidator")), - verificationOpts: { - constructorArgsImplementation: [], - constructorArgsProxy: [ - "0x56fF81aBB5cdaC478bF236db717e4976b2ff841e", - "0xae15d2023a76174a940cbb2b7f44012c728b9d74", - ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.EthIdentityValidator")), + "0x6964656e332e637265617465322e556e6976657273616c5665726966696572", ], constructorArgsProxyAdmin: ["0xAe15d2023A76174a940cbb2b7F44012C728B9d74"], libraries: {}, @@ -296,7 +224,7 @@ export const contractsInfo = Object.freeze({ constructorArgsProxy: [ "0x56fF81aBB5cdaC478bF236db717e4976b2ff841e", "0xae15d2023a76174a940cbb2b7f44012c728b9d74", - ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.IdentityTreeStore")), + "0x6964656e332e637265617465322e556e6976657273616c5665726966696572", ], constructorArgsProxyAdmin: ["0xAe15d2023A76174a940cbb2b7F44012C728B9d74"], libraries: {}, @@ -309,17 +237,12 @@ export const contractsInfo = Object.freeze({ create2Calldata: ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.VCPayment")), verificationOpts: { constructorArgsImplementation: [], - constructorArgsProxy: [ - "0x56fF81aBB5cdaC478bF236db717e4976b2ff841e", - "0xae15d2023a76174a940cbb2b7f44012c728b9d74", - ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.VCPayment")), - ], libraries: {}, }, }, MC_PAYMENT: { name: "MCPayment", - version: "1.0.7", + version: "1.0.3", unifiedAddress: "0xe317A4f1450116b2fD381446DEaB41c882D6136D", create2Calldata: ethers.hexlify(ethers.toUtf8Bytes("iden3.create2.MCPayment")), verificationOpts: { @@ -414,32 +337,30 @@ export const contractsInfo = Object.freeze({ libraries: {}, }, }, - GROTH16_VERIFIER_LINKED_MULTI_QUERY10: { - name: "Groth16VerifierLinkedMultiQuery10Wrapper", + GROTH16_VERIFIER_AUTH_V2: { + name: "Groth16VerifierAuthV2Wrapper", unifiedAddress: "", create2Calldata: "", verificationOpts: { contract: - "contracts/lib/groth16-verifiers/Groth16VerifierLinkedMultiQuery10Wrapper.sol:Groth16VerifierLinkedMultiQuery10Wrapper", + "contracts/lib/groth16-verifiers/Groth16VerifierAuthV2Wrapper.sol:Groth16VerifierAuthV2Wrapper", constructorArgsImplementation: [], libraries: {}, }, }, - GROTH16_VERIFIER_AUTH_V2: { - name: "Groth16VerifierAuthV2Wrapper", + STATE_LIB: { + name: "StateLib", unifiedAddress: "", - create2Calldata: "", + create2Address: "", verificationOpts: { - contract: - "contracts/lib/groth16-verifiers/Groth16VerifierAuthV2Wrapper.sol:Groth16VerifierAuthV2Wrapper", constructorArgsImplementation: [], libraries: {}, }, }, - STATE_LIB: { - name: "StateLib", + STATE_CROSS_CHAIN_LIB: { + name: "StateCrossChainLib", unifiedAddress: "", - create2Calldata: "", + create2Address: "", verificationOpts: { constructorArgsImplementation: [], libraries: {}, @@ -448,14 +369,14 @@ export const contractsInfo = Object.freeze({ VERIFIER_LIB: { name: "VerifierLib", unifiedAddress: "", - create2Calldata: "", + create2Address: "", verificationOpts: { constructorArgsImplementation: [], libraries: {}, }, }, - EMBEDDED_VERIFIER_WRAPPER: { - name: "EmbeddedVerifierWrapper", + EMBEDDED_ZKP_VERIFIER_WRAPPER: { + name: "EmbeddedZKPVerifierWrapper", unifiedAddress: "", create2Calldata: "", }, @@ -572,29 +493,8 @@ export const TRANSPARENT_UPGRADEABLE_PROXY_ABI = [ stateMutability: "payable", type: "fallback", }, - { - inputs: [ - { - internalType: "address", - name: "newImplementation", - type: "address", - }, - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - ], - name: "upgradeToAndCall", - outputs: [], - stateMutability: "payable", - type: "function", - }, ]; -export const SIGNED_SERIALISED_TRANSACTION_GAS_LIMIT_3000000 = - "0xf92f698085174876e800832dc6c08080b92f1660a06040523060805234801561001457600080fd5b50608051612e3e6100d860003960008181610603015281816107050152818161082b015281816108d50152818161127f01528181611375015281816113e00152818161141f015281816114a7015281816115b3015281816117d20152818161183d0152818161187c0152818161190401528181611ac501528181611c7801528181611ce301528181611d2201528181611daa01528181611fe901528181612206015281816122f20152818161244d015281816124a601526125820152612e3e6000f3fe60806040526004361061018a5760003560e01c806381503da1116100d6578063d323826a1161007f578063e96deee411610059578063e96deee414610395578063f5745aba146103a8578063f9664498146103bb57600080fd5b8063d323826a1461034f578063ddda0acb1461036f578063e437252a1461038257600080fd5b80639c36a286116100b05780639c36a28614610316578063a7db93f214610329578063c3fe107b1461033c57600080fd5b806381503da1146102d0578063890c283b146102e357806398e810771461030357600080fd5b80632f990e3f116101385780636cec2536116101125780636cec25361461027d57806374637a7a1461029d5780637f565360146102bd57600080fd5b80632f990e3f1461023757806331a7c8c81461024a57806342d654fc1461025d57600080fd5b806327fe18221161016957806327fe1822146101f15780632852527a1461020457806328ddd0461461021757600080fd5b8062d84acb1461018f57806326307668146101cb57806326a32fc7146101de575b600080fd5b6101a261019d366004612915565b6103ce565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6101a26101d9366004612994565b6103e6565b6101a26101ec3660046129db565b610452565b6101a26101ff3660046129db565b6104de565b6101a2610212366004612a39565b610539565b34801561022357600080fd5b506101a2610232366004612a90565b6106fe565b6101a2610245366004612aa9565b61072a565b6101a2610258366004612aa9565b6107bb565b34801561026957600080fd5b506101a2610278366004612b1e565b6107c9565b34801561028957600080fd5b506101a2610298366004612a90565b610823565b3480156102a957600080fd5b506101a26102b8366004612b4a565b61084f565b6101a26102cb3660046129db565b611162565b6101a26102de366004612b74565b6111e8565b3480156102ef57600080fd5b506101a26102fe366004612bac565b611276565b6101a2610311366004612bce565b6112a3565b6101a2610324366004612994565b611505565b6101a2610337366004612c49565b6116f1565b6101a261034a366004612aa9565b611964565b34801561035b57600080fd5b506101a261036a366004612cd9565b6119ed565b6101a261037d366004612c49565b611a17565b6101a2610390366004612bce565b611e0c565b6101a26103a3366004612915565b611e95565b6101a26103b6366004612bce565b611ea4565b6101a26103c9366004612b74565b611f2d565b60006103dd8585858533611a17565b95945050505050565b6000806103f2846120db565b90508083516020850134f59150610408826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a35092915050565b60006104d86104d260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b836103e6565b92915050565b600081516020830134f090506104f3816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a2919050565b600080610545856120db565b905060008460601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006028820152826037826000f593505073ffffffffffffffffffffffffffffffffffffffff8316610635576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660048201526024015b60405180910390fd5b604051829073ffffffffffffffffffffffffffffffffffffffff8516907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808473ffffffffffffffffffffffffffffffffffffffff1634876040516106a19190612d29565b60006040518083038185875af1925050503d80600081146106de576040519150601f19603f3d011682016040523d82523d6000602084013e6106e3565b606091505b50915091506106f382828961247d565b505050509392505050565b60006104d87f00000000000000000000000000000000000000000000000000000000000000008361084f565b60006107b36107aa60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b85858533611a17565b949350505050565b60006107b3848484336112a3565b60006040518260005260ff600b53836020527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f6040526055600b20601452806040525061d694600052600160345350506017601e20919050565b60006104d8827f00000000000000000000000000000000000000000000000000000000000000006107c9565b600060607f9400000000000000000000000000000000000000000000000000000000000000610887600167ffffffffffffffff612d45565b67ffffffffffffffff16841115610902576040517f3c55ab3b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b836000036109c7576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f800000000000000000000000000000000000000000000000000000000000000060368201526037015b6040516020818303038152906040529150611152565b607f8411610a60576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b16602283015260f886901b1660368201526037016109b1565b60ff8411610b1f576040517fd70000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660228301527f8100000000000000000000000000000000000000000000000000000000000000603683015260f886901b1660378201526038016109b1565b61ffff8411610bff576040517fd80000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f820000000000000000000000000000000000000000000000000000000000000060368201527fffff00000000000000000000000000000000000000000000000000000000000060f086901b1660378201526039016109b1565b62ffffff8411610ce0576040517fd90000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f830000000000000000000000000000000000000000000000000000000000000060368201527fffffff000000000000000000000000000000000000000000000000000000000060e886901b166037820152603a016109b1565b63ffffffff8411610dc2576040517fda0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f840000000000000000000000000000000000000000000000000000000000000060368201527fffffffff0000000000000000000000000000000000000000000000000000000060e086901b166037820152603b016109b1565b64ffffffffff8411610ea5576040517fdb0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f850000000000000000000000000000000000000000000000000000000000000060368201527fffffffffff00000000000000000000000000000000000000000000000000000060d886901b166037820152603c016109b1565b65ffffffffffff8411610f89576040517fdc0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f860000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffff000000000000000000000000000000000000000000000000000060d086901b166037820152603d016109b1565b66ffffffffffffff841161106e576040517fdd0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f870000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffff0000000000000000000000000000000000000000000000000060c886901b166037820152603e016109b1565b6040517fde0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f880000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffffff00000000000000000000000000000000000000000000000060c086901b166037820152603f0160405160208183030381529060405291505b5080516020909101209392505050565b60006104d86111e260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b83611505565b600061126f61126860408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b8484610539565b9392505050565b600061126f83837f00000000000000000000000000000000000000000000000000000000000000006119ed565b60008451602086018451f090506112b9816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808273ffffffffffffffffffffffffffffffffffffffff168560200151876040516113279190612d29565b60006040518083038185875af1925050503d8060008114611364576040519150601f19603f3d011682016040523d82523d6000602084013e611369565b606091505b5091509150816113c9577f0000000000000000000000000000000000000000000000000000000000000000816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001631156114fb578373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611495576040519150601f19603f3d011682016040523d82523d6000602084013e61149a565b606091505b509092509050816114fb577f0000000000000000000000000000000000000000000000000000000000000000816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b5050949350505050565b600080611511846120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff81166115e0576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a361162c83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1634876040516116569190612d29565b60006040518083038185875af1925050503d8060008114611693576040519150601f19603f3d011682016040523d82523d6000602084013e611698565b606091505b505090506116a681866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a25050505092915050565b6000806116fd876120db565b9050808651602088018651f59150611714826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808373ffffffffffffffffffffffffffffffffffffffff168660200151886040516117849190612d29565b60006040518083038185875af1925050503d80600081146117c1576040519150601f19603f3d011682016040523d82523d6000602084013e6117c6565b606091505b509150915081611826577f0000000000000000000000000000000000000000000000000000000000000000816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163115611958578473ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d80600081146118f2576040519150601f19603f3d011682016040523d82523d6000602084013e6118f7565b606091505b50909250905081611958577f0000000000000000000000000000000000000000000000000000000000000000816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b50505095945050505050565b60006107b36119e460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b858585336116f1565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b600080611a23876120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff8116611af2576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a3611b3e83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1687600001518a604051611b6c9190612d29565b60006040518083038185875af1925050503d8060008114611ba9576040519150601f19603f3d011682016040523d82523d6000602084013e611bae565b606091505b50509050611bbc81866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a260608573ffffffffffffffffffffffffffffffffffffffff1688602001518a604051611c299190612d29565b60006040518083038185875af1925050503d8060008114611c66576040519150601f19603f3d011682016040523d82523d6000602084013e611c6b565b606091505b50909250905081611ccc577f0000000000000000000000000000000000000000000000000000000000000000816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163115611dfe578673ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611d98576040519150601f19603f3d011682016040523d82523d6000602084013e611d9d565b606091505b50909250905081611dfe577f0000000000000000000000000000000000000000000000000000000000000000816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050505095945050505050565b60006103dd611e8c60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b868686866116f1565b60006103dd85858585336116f1565b60006103dd611f2460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b86868686611a17565b6000808360601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f092505073ffffffffffffffffffffffffffffffffffffffff8216612016576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b60405173ffffffffffffffffffffffffffffffffffffffff8316907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808373ffffffffffffffffffffffffffffffffffffffff1634866040516120809190612d29565b60006040518083038185875af1925050503d80600081146120bd576040519150601f19603f3d011682016040523d82523d6000602084013e6120c2565b606091505b50915091506120d282828861247d565b50505092915050565b60008060006120e9846125b3565b9092509050600082600281111561210257612102612e02565b1480156121205750600081600281111561211e5761211e612e02565b145b1561215e57604080513360208201524691810191909152606081018590526080016040516020818303038152906040528051906020012092506123cc565b600082600281111561217257612172612e02565b1480156121905750600181600281111561218e5761218e612e02565b145b156121b0576121a9338560009182526020526040902090565b92506123cc565b60008260028111156121c4576121c4612e02565b03612233576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b600182600281111561224757612247612e02565b1480156122655750600081600281111561226357612263612e02565b145b1561227e576121a9468560009182526020526040902090565b600182600281111561229257612292612e02565b1480156122b0575060028160028111156122ae576122ae612e02565b145b1561231f576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b61239a60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b84036123a657836123c9565b604080516020810186905201604051602081830303815290604052805190602001205b92505b5050919050565b73ffffffffffffffffffffffffffffffffffffffff8116158061240b575073ffffffffffffffffffffffffffffffffffffffff81163b155b1561247a576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b50565b82158061249f575073ffffffffffffffffffffffffffffffffffffffff81163b155b156124fa577f0000000000000000000000000000000000000000000000000000000000000000826040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050565b811580612520575073ffffffffffffffffffffffffffffffffffffffff8116155b80612540575073ffffffffffffffffffffffffffffffffffffffff81163b155b156125af576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b5050565b600080606083901c3314801561261057508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b1561262057506000905080915091565b606083901c3314801561265a57507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561266b5750600090506001915091565b33606084901c036126825750600090506002915091565b606083901c1580156126db57508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b156126ec5750600190506000915091565b606083901c15801561272557507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561273557506001905080915091565b606083901c61274a5750600190506002915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000036127a55750600290506000915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000036127e15750600290506001915091565b506002905080915091565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261282c57600080fd5b813567ffffffffffffffff80821115612847576128476127ec565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561288d5761288d6127ec565b816040528381528660208588010111156128a657600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000604082840312156128d857600080fd5b6040516040810181811067ffffffffffffffff821117156128fb576128fb6127ec565b604052823581526020928301359281019290925250919050565b60008060008060a0858703121561292b57600080fd5b84359350602085013567ffffffffffffffff8082111561294a57600080fd5b6129568883890161281b565b9450604087013591508082111561296c57600080fd5b506129798782880161281b565b92505061298986606087016128c6565b905092959194509250565b600080604083850312156129a757600080fd5b82359150602083013567ffffffffffffffff8111156129c557600080fd5b6129d18582860161281b565b9150509250929050565b6000602082840312156129ed57600080fd5b813567ffffffffffffffff811115612a0457600080fd5b6107b38482850161281b565b803573ffffffffffffffffffffffffffffffffffffffff81168114612a3457600080fd5b919050565b600080600060608486031215612a4e57600080fd5b83359250612a5e60208501612a10565b9150604084013567ffffffffffffffff811115612a7a57600080fd5b612a868682870161281b565b9150509250925092565b600060208284031215612aa257600080fd5b5035919050565b600080600060808486031215612abe57600080fd5b833567ffffffffffffffff80821115612ad657600080fd5b612ae28783880161281b565b94506020860135915080821115612af857600080fd5b50612b058682870161281b565b925050612b1585604086016128c6565b90509250925092565b60008060408385031215612b3157600080fd5b82359150612b4160208401612a10565b90509250929050565b60008060408385031215612b5d57600080fd5b612b6683612a10565b946020939093013593505050565b60008060408385031215612b8757600080fd5b612b9083612a10565b9150602083013567ffffffffffffffff8111156129c557600080fd5b60008060408385031215612bbf57600080fd5b50508035926020909101359150565b60008060008060a08587031215612be457600080fd5b843567ffffffffffffffff80821115612bfc57600080fd5b612c088883890161281b565b95506020870135915080821115612c1e57600080fd5b50612c2b8782880161281b565b935050612c3b86604087016128c6565b915061298960808601612a10565b600080600080600060c08688031215612c6157600080fd5b85359450602086013567ffffffffffffffff80821115612c8057600080fd5b612c8c89838a0161281b565b95506040880135915080821115612ca257600080fd5b50612caf8882890161281b565b935050612cbf87606088016128c6565b9150612ccd60a08701612a10565b90509295509295909350565b600080600060608486031215612cee57600080fd5b8335925060208401359150612b1560408501612a10565b60005b83811015612d20578181015183820152602001612d08565b50506000910152565b60008251612d3b818460208701612d05565b9190910192915050565b67ffffffffffffffff828116828216039080821115612d8d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5092915050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260008251806040840152612dcf816060850160208701612d05565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c6343000817000a1ca005f70bf8a1493291468f36ef23b05eb3a4f1807f6b4022942a4104b7537bfc36a029528c0c29546c81e7d78b0277ef87031541bdc96427b246ecedb6d74cd3ed62"; - export const SIGNED_SERIALISED_TRANSACTION_GAS_LIMIT_25000000 = "0xf92f6a8085174876e80084017d78408080b92f1660a06040523060805234801561001457600080fd5b50608051612e3e6100d860003960008181610603015281816107050152818161082b015281816108d50152818161127f01528181611375015281816113e00152818161141f015281816114a7015281816115b3015281816117d20152818161183d0152818161187c0152818161190401528181611ac501528181611c7801528181611ce301528181611d2201528181611daa01528181611fe901528181612206015281816122f20152818161244d015281816124a601526125820152612e3e6000f3fe60806040526004361061018a5760003560e01c806381503da1116100d6578063d323826a1161007f578063e96deee411610059578063e96deee414610395578063f5745aba146103a8578063f9664498146103bb57600080fd5b8063d323826a1461034f578063ddda0acb1461036f578063e437252a1461038257600080fd5b80639c36a286116100b05780639c36a28614610316578063a7db93f214610329578063c3fe107b1461033c57600080fd5b806381503da1146102d0578063890c283b146102e357806398e810771461030357600080fd5b80632f990e3f116101385780636cec2536116101125780636cec25361461027d57806374637a7a1461029d5780637f565360146102bd57600080fd5b80632f990e3f1461023757806331a7c8c81461024a57806342d654fc1461025d57600080fd5b806327fe18221161016957806327fe1822146101f15780632852527a1461020457806328ddd0461461021757600080fd5b8062d84acb1461018f57806326307668146101cb57806326a32fc7146101de575b600080fd5b6101a261019d366004612915565b6103ce565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6101a26101d9366004612994565b6103e6565b6101a26101ec3660046129db565b610452565b6101a26101ff3660046129db565b6104de565b6101a2610212366004612a39565b610539565b34801561022357600080fd5b506101a2610232366004612a90565b6106fe565b6101a2610245366004612aa9565b61072a565b6101a2610258366004612aa9565b6107bb565b34801561026957600080fd5b506101a2610278366004612b1e565b6107c9565b34801561028957600080fd5b506101a2610298366004612a90565b610823565b3480156102a957600080fd5b506101a26102b8366004612b4a565b61084f565b6101a26102cb3660046129db565b611162565b6101a26102de366004612b74565b6111e8565b3480156102ef57600080fd5b506101a26102fe366004612bac565b611276565b6101a2610311366004612bce565b6112a3565b6101a2610324366004612994565b611505565b6101a2610337366004612c49565b6116f1565b6101a261034a366004612aa9565b611964565b34801561035b57600080fd5b506101a261036a366004612cd9565b6119ed565b6101a261037d366004612c49565b611a17565b6101a2610390366004612bce565b611e0c565b6101a26103a3366004612915565b611e95565b6101a26103b6366004612bce565b611ea4565b6101a26103c9366004612b74565b611f2d565b60006103dd8585858533611a17565b95945050505050565b6000806103f2846120db565b90508083516020850134f59150610408826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a35092915050565b60006104d86104d260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b836103e6565b92915050565b600081516020830134f090506104f3816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a2919050565b600080610545856120db565b905060008460601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006028820152826037826000f593505073ffffffffffffffffffffffffffffffffffffffff8316610635576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660048201526024015b60405180910390fd5b604051829073ffffffffffffffffffffffffffffffffffffffff8516907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808473ffffffffffffffffffffffffffffffffffffffff1634876040516106a19190612d29565b60006040518083038185875af1925050503d80600081146106de576040519150601f19603f3d011682016040523d82523d6000602084013e6106e3565b606091505b50915091506106f382828961247d565b505050509392505050565b60006104d87f00000000000000000000000000000000000000000000000000000000000000008361084f565b60006107b36107aa60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b85858533611a17565b949350505050565b60006107b3848484336112a3565b60006040518260005260ff600b53836020527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f6040526055600b20601452806040525061d694600052600160345350506017601e20919050565b60006104d8827f00000000000000000000000000000000000000000000000000000000000000006107c9565b600060607f9400000000000000000000000000000000000000000000000000000000000000610887600167ffffffffffffffff612d45565b67ffffffffffffffff16841115610902576040517f3c55ab3b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b836000036109c7576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f800000000000000000000000000000000000000000000000000000000000000060368201526037015b6040516020818303038152906040529150611152565b607f8411610a60576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b16602283015260f886901b1660368201526037016109b1565b60ff8411610b1f576040517fd70000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660228301527f8100000000000000000000000000000000000000000000000000000000000000603683015260f886901b1660378201526038016109b1565b61ffff8411610bff576040517fd80000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f820000000000000000000000000000000000000000000000000000000000000060368201527fffff00000000000000000000000000000000000000000000000000000000000060f086901b1660378201526039016109b1565b62ffffff8411610ce0576040517fd90000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f830000000000000000000000000000000000000000000000000000000000000060368201527fffffff000000000000000000000000000000000000000000000000000000000060e886901b166037820152603a016109b1565b63ffffffff8411610dc2576040517fda0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f840000000000000000000000000000000000000000000000000000000000000060368201527fffffffff0000000000000000000000000000000000000000000000000000000060e086901b166037820152603b016109b1565b64ffffffffff8411610ea5576040517fdb0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f850000000000000000000000000000000000000000000000000000000000000060368201527fffffffffff00000000000000000000000000000000000000000000000000000060d886901b166037820152603c016109b1565b65ffffffffffff8411610f89576040517fdc0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f860000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffff000000000000000000000000000000000000000000000000000060d086901b166037820152603d016109b1565b66ffffffffffffff841161106e576040517fdd0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f870000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffff0000000000000000000000000000000000000000000000000060c886901b166037820152603e016109b1565b6040517fde0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f880000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffffff00000000000000000000000000000000000000000000000060c086901b166037820152603f0160405160208183030381529060405291505b5080516020909101209392505050565b60006104d86111e260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b83611505565b600061126f61126860408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b8484610539565b9392505050565b600061126f83837f00000000000000000000000000000000000000000000000000000000000000006119ed565b60008451602086018451f090506112b9816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808273ffffffffffffffffffffffffffffffffffffffff168560200151876040516113279190612d29565b60006040518083038185875af1925050503d8060008114611364576040519150601f19603f3d011682016040523d82523d6000602084013e611369565b606091505b5091509150816113c9577f0000000000000000000000000000000000000000000000000000000000000000816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001631156114fb578373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611495576040519150601f19603f3d011682016040523d82523d6000602084013e61149a565b606091505b509092509050816114fb577f0000000000000000000000000000000000000000000000000000000000000000816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b5050949350505050565b600080611511846120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff81166115e0576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a361162c83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1634876040516116569190612d29565b60006040518083038185875af1925050503d8060008114611693576040519150601f19603f3d011682016040523d82523d6000602084013e611698565b606091505b505090506116a681866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a25050505092915050565b6000806116fd876120db565b9050808651602088018651f59150611714826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808373ffffffffffffffffffffffffffffffffffffffff168660200151886040516117849190612d29565b60006040518083038185875af1925050503d80600081146117c1576040519150601f19603f3d011682016040523d82523d6000602084013e6117c6565b606091505b509150915081611826577f0000000000000000000000000000000000000000000000000000000000000000816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163115611958578473ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d80600081146118f2576040519150601f19603f3d011682016040523d82523d6000602084013e6118f7565b606091505b50909250905081611958577f0000000000000000000000000000000000000000000000000000000000000000816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b50505095945050505050565b60006107b36119e460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b858585336116f1565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b600080611a23876120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff8116611af2576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a3611b3e83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1687600001518a604051611b6c9190612d29565b60006040518083038185875af1925050503d8060008114611ba9576040519150601f19603f3d011682016040523d82523d6000602084013e611bae565b606091505b50509050611bbc81866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a260608573ffffffffffffffffffffffffffffffffffffffff1688602001518a604051611c299190612d29565b60006040518083038185875af1925050503d8060008114611c66576040519150601f19603f3d011682016040523d82523d6000602084013e611c6b565b606091505b50909250905081611ccc577f0000000000000000000000000000000000000000000000000000000000000000816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163115611dfe578673ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611d98576040519150601f19603f3d011682016040523d82523d6000602084013e611d9d565b606091505b50909250905081611dfe577f0000000000000000000000000000000000000000000000000000000000000000816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050505095945050505050565b60006103dd611e8c60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b868686866116f1565b60006103dd85858585336116f1565b60006103dd611f2460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b86868686611a17565b6000808360601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f092505073ffffffffffffffffffffffffffffffffffffffff8216612016576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b60405173ffffffffffffffffffffffffffffffffffffffff8316907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808373ffffffffffffffffffffffffffffffffffffffff1634866040516120809190612d29565b60006040518083038185875af1925050503d80600081146120bd576040519150601f19603f3d011682016040523d82523d6000602084013e6120c2565b606091505b50915091506120d282828861247d565b50505092915050565b60008060006120e9846125b3565b9092509050600082600281111561210257612102612e02565b1480156121205750600081600281111561211e5761211e612e02565b145b1561215e57604080513360208201524691810191909152606081018590526080016040516020818303038152906040528051906020012092506123cc565b600082600281111561217257612172612e02565b1480156121905750600181600281111561218e5761218e612e02565b145b156121b0576121a9338560009182526020526040902090565b92506123cc565b60008260028111156121c4576121c4612e02565b03612233576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b600182600281111561224757612247612e02565b1480156122655750600081600281111561226357612263612e02565b145b1561227e576121a9468560009182526020526040902090565b600182600281111561229257612292612e02565b1480156122b0575060028160028111156122ae576122ae612e02565b145b1561231f576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b61239a60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b84036123a657836123c9565b604080516020810186905201604051602081830303815290604052805190602001205b92505b5050919050565b73ffffffffffffffffffffffffffffffffffffffff8116158061240b575073ffffffffffffffffffffffffffffffffffffffff81163b155b1561247a576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b50565b82158061249f575073ffffffffffffffffffffffffffffffffffffffff81163b155b156124fa577f0000000000000000000000000000000000000000000000000000000000000000826040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050565b811580612520575073ffffffffffffffffffffffffffffffffffffffff8116155b80612540575073ffffffffffffffffffffffffffffffffffffffff81163b155b156125af576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b5050565b600080606083901c3314801561261057508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b1561262057506000905080915091565b606083901c3314801561265a57507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561266b5750600090506001915091565b33606084901c036126825750600090506002915091565b606083901c1580156126db57508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b156126ec5750600190506000915091565b606083901c15801561272557507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561273557506001905080915091565b606083901c61274a5750600190506002915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000036127a55750600290506000915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000036127e15750600290506001915091565b506002905080915091565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261282c57600080fd5b813567ffffffffffffffff80821115612847576128476127ec565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561288d5761288d6127ec565b816040528381528660208588010111156128a657600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000604082840312156128d857600080fd5b6040516040810181811067ffffffffffffffff821117156128fb576128fb6127ec565b604052823581526020928301359281019290925250919050565b60008060008060a0858703121561292b57600080fd5b84359350602085013567ffffffffffffffff8082111561294a57600080fd5b6129568883890161281b565b9450604087013591508082111561296c57600080fd5b506129798782880161281b565b92505061298986606087016128c6565b905092959194509250565b600080604083850312156129a757600080fd5b82359150602083013567ffffffffffffffff8111156129c557600080fd5b6129d18582860161281b565b9150509250929050565b6000602082840312156129ed57600080fd5b813567ffffffffffffffff811115612a0457600080fd5b6107b38482850161281b565b803573ffffffffffffffffffffffffffffffffffffffff81168114612a3457600080fd5b919050565b600080600060608486031215612a4e57600080fd5b83359250612a5e60208501612a10565b9150604084013567ffffffffffffffff811115612a7a57600080fd5b612a868682870161281b565b9150509250925092565b600060208284031215612aa257600080fd5b5035919050565b600080600060808486031215612abe57600080fd5b833567ffffffffffffffff80821115612ad657600080fd5b612ae28783880161281b565b94506020860135915080821115612af857600080fd5b50612b058682870161281b565b925050612b1585604086016128c6565b90509250925092565b60008060408385031215612b3157600080fd5b82359150612b4160208401612a10565b90509250929050565b60008060408385031215612b5d57600080fd5b612b6683612a10565b946020939093013593505050565b60008060408385031215612b8757600080fd5b612b9083612a10565b9150602083013567ffffffffffffffff8111156129c557600080fd5b60008060408385031215612bbf57600080fd5b50508035926020909101359150565b60008060008060a08587031215612be457600080fd5b843567ffffffffffffffff80821115612bfc57600080fd5b612c088883890161281b565b95506020870135915080821115612c1e57600080fd5b50612c2b8782880161281b565b935050612c3b86604087016128c6565b915061298960808601612a10565b600080600080600060c08688031215612c6157600080fd5b85359450602086013567ffffffffffffffff80821115612c8057600080fd5b612c8c89838a0161281b565b95506040880135915080821115612ca257600080fd5b50612caf8882890161281b565b935050612cbf87606088016128c6565b9150612ccd60a08701612a10565b90509295509295909350565b600080600060608486031215612cee57600080fd5b8335925060208401359150612b1560408501612a10565b60005b83811015612d20578181015183820152602001612d08565b50506000910152565b60008251612d3b818460208701612d05565b9190910192915050565b67ffffffffffffffff828116828216039080821115612d8d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5092915050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260008251806040840152612dcf816060850160208701612d05565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c6343000817000a1ba06c6a2a796c36b3f9ac9adacf91987f9cd29b602e63ece01d17a26bf329634d94a06df43ab80059dd7dd3ec16ef5a983cf6652e7fb703349145f46024f848a9a936"; diff --git a/ignition/modules/params/chain-99999.json b/ignition/modules/params/chain-99999.json new file mode 100644 index 00000000..d31e7d1d --- /dev/null +++ b/ignition/modules/params/chain-99999.json @@ -0,0 +1,107 @@ +{ + "StateProxyFirstImplementationModule": { + "proxyAdminOwner": "" + }, + "UniversalVerifierProxyFirstImplementationModule": { + "proxyAdminOwner": "" + }, + "IdentityTreeStoreProxyFirstImplementationModule": { + "proxyAdminOwner": "" + }, + + "StateProxyFinalImplementationModule": { + "defaultIdType": "0x01f9" + }, + + "CrossChainProofValidatorModule": { + "oracleSigningAddress": "" + }, + + "Poseidon1AtModule": { + "contractAddress": "" + }, + "Poseidon2AtModule": { + "contractAddress": "" + }, + "Poseidon3AtModule": { + "contractAddress": "" + }, + "Poseidon4AtModule": { + "contractAddress": "" + }, + + "SmtLibAtModule": { + "contractAddress": "" + }, + + "StateLibAtModule": { + "contractAddress": "" + }, + + "StateAtModule": { + "proxyAddress": "", + "proxyAdminAddress": "" + }, + + "StateNewImplementationAtModule": { + "contractAddress": "" + }, + + "CrossChainProofValidatorAtModule": { + "contractAddress": "" + }, + + "Groth16VerifierStateTransitionAtModule": { + "contractAddress": "" + }, + + "IdentityTreeStoreAtModule": { + "proxyAddress": "", + "proxyAdminAddress": "" + }, + + "IdentityTreeStoreNewImplementationAtModule": { + "contractAddress": "" + }, + + "UniversalVerifierAtModule": { + "proxyAddress": "", + "proxyAdminAddress": "" + }, + + "UniversalVerifierNewImplementationAtModule": { + "contractAddress": "" + }, + + "VerifierLibAtModule": { + "contractAddress": "" + }, + + "CredentialAtomicQuerySigV2ValidatorAtModule": { + "contractAddress": "" + }, + "CredentialAtomicQueryMTPV2ValidatorAtModule": { + "contractAddress": "" + }, + + "CredentialAtomicQuerySigV2OnChainValidatorAtModule": { + "contractAddress": "" + }, + "CredentialAtomicQueryMTPV2OnChainValidatorAtModule": { + "contractAddress": "" + }, + + "Groth16VerifierSigWrapperAtModule": { + "contractAddress": "" + }, + "Groth16VerifierMTPWrapperAtModule": { + "contractAddress": "" + }, + + "Groth16VerifierSigAtModule": { + "contractAddress": "" + }, + "Groth16VerifierMTPAtModule": { + "contractAddress": "" + } +} \ No newline at end of file diff --git a/scripts/deploy/adi/check-gist.js b/scripts/deploy/adi/check-gist.js new file mode 100644 index 00000000..38a63fb7 --- /dev/null +++ b/scripts/deploy/adi/check-gist.js @@ -0,0 +1,36 @@ +import { ethers } from "ethers"; + +async function main() { + const rpcUrl = "https://rpc.ab.testnet.adifoundation.ai"; + const provider = new ethers.JsonRpcProvider(rpcUrl); + + const stateAddress = "0x1049f3a8e81f91d00E65DB46519778A5d178b37E"; + + const abi = [ + "function getGISTRoot() view returns (uint256)", + "function getGISTRootHistoryLength() view returns (uint256)", + "function getDefaultIdType() view returns (bytes2)", + "function getVerifier() view returns (address)", + "function getCrossChainProofValidator() view returns (address)" + ]; + + const contract = new ethers.Contract(stateAddress, abi, provider); + + const gistRoot = await contract.getGISTRoot(); + const gistHistoryLength = await contract.getGISTRootHistoryLength(); + const defaultIdType = await contract.getDefaultIdType(); + const verifier = await contract.getVerifier(); + const crossChainProofValidator = await contract.getCrossChainProofValidator(); + + console.log("State:", stateAddress); + console.log("getGISTRoot:", gistRoot.toString()); + console.log("getGISTRootHistoryLength:", gistHistoryLength.toString()); + console.log("getDefaultIdType:", defaultIdType); + console.log("getVerifier:", verifier); + console.log("getCrossChainProofValidator:", crossChainProofValidator); +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); \ No newline at end of file diff --git a/scripts/deploy/adi/check-state.js b/scripts/deploy/adi/check-state.js new file mode 100644 index 00000000..22ddb8b3 --- /dev/null +++ b/scripts/deploy/adi/check-state.js @@ -0,0 +1,39 @@ +import { ethers } from "ethers"; + +async function main() { + const rpcUrl = "https://rpc.ab.testnet.adifoundation.ai"; + const provider = new ethers.JsonRpcProvider(rpcUrl); + + const stateAddress = "0x1049f3a8e81f91d00E65DB46519778A5d178b37E"; + + const abi = [ + "function getDefaultIdType() view returns (bytes2)", + "function getVerifier() view returns (address)", + "function getCrossChainProofValidator() view returns (address)", + "function getGISTRoot() view returns (uint256)", + "function getGISTRootHistoryLength() view returns (uint256)", + "function isIdTypeSupported(bytes2 idType) view returns (bool)" + ]; + + const contract = new ethers.Contract(stateAddress, abi, provider); + + const defaultIdType = await contract.getDefaultIdType(); + const verifier = await contract.getVerifier(); + const crossChainProofValidator = await contract.getCrossChainProofValidator(); + const gistRoot = await contract.getGISTRoot(); + const gistHistoryLength = await contract.getGISTRootHistoryLength(); + const isSupported = await contract.isIdTypeSupported("0x01f9"); + + console.log("State:", stateAddress); + console.log("defaultIdType:", defaultIdType); + console.log("verifier:", verifier); + console.log("crossChainProofValidator:", crossChainProofValidator); + console.log("getGISTRoot:", gistRoot.toString()); + console.log("getGISTRootHistoryLength:", gistHistoryLength.toString()); + console.log("isIdTypeSupported(0x01f9):", isSupported); +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); \ No newline at end of file diff --git a/scripts/deploy/adi/checkState.ts b/scripts/deploy/adi/checkState.ts new file mode 100644 index 00000000..6744365f --- /dev/null +++ b/scripts/deploy/adi/checkState.ts @@ -0,0 +1,27 @@ +import { ethers } from "hardhat"; + +async function main() { + const stateAddress = "0x1049f3a8e81f91d00E65DB46519778A5d178b37E"; + + const state = await ethers.getContractAt("State", stateAddress); + + const defaultIdType = await state.getDefaultIdType(); + const verifier = await state.getVerifier(); + const crossChainProofValidator = await state.getCrossChainProofValidator(); + const gistRoot = await state.getGISTRoot(); + const gistHistoryLength = await state.getGISTRootHistoryLength(); + const isSupported = await state.isIdTypeSupported("0x01f9"); + + console.log("State:", stateAddress); + console.log("defaultIdType:", defaultIdType); + console.log("verifier:", verifier); + console.log("crossChainProofValidator:", crossChainProofValidator); + console.log("getGISTRoot:", gistRoot.toString()); + console.log("getGISTRootHistoryLength:", gistHistoryLength.toString()); + console.log("isIdTypeSupported(0x01f9):", isSupported); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); \ No newline at end of file diff --git a/scripts/deploy/adi/deployIdentityTreeStore.noignition.ts b/scripts/deploy/adi/deployIdentityTreeStore.noignition.ts new file mode 100644 index 00000000..15d21dab --- /dev/null +++ b/scripts/deploy/adi/deployIdentityTreeStore.noignition.ts @@ -0,0 +1,179 @@ +import { + getDeploymentParameters, + writeDeploymentParameters, +} from "../../../helpers/helperUtils"; +import { network } from "hardhat"; + +const { ethers } = await network.connect(); + +async function withRetry(fn: () => Promise, label: string, tries = 10) { + let lastErr: any; + for (let i = 1; i <= tries; i++) { + try { + return await fn(); + } catch (e: any) { + lastErr = e; + const msg = String(e?.message || e); + const is502 = + msg.includes("502") || + msg.includes("Bad Gateway") || + msg.includes("unexpected status code"); + if (!is502) throw e; + + const waitMs = 1500 * i; + console.log(`[retry ${i}/${tries}] ${label} hit RPC 502-ish error. Waiting ${waitMs}ms...`); + await new Promise((r) => setTimeout(r, waitMs)); + } + } + throw lastErr; +} + +function isNonZeroAddress(addr?: string) { + return ( + !!addr && + /^0x[a-fA-F0-9]{40}$/.test(addr) && + addr !== "0x0000000000000000000000000000000000000000" + ); +} + +async function deployByName( + contractName: string, + libraries?: Record, + args: any[] = [], +) { + const factory = await withRetry( + async () => ethers.getContractFactory(contractName, { libraries }), + `getContractFactory(${contractName})`, + ); + + const contract = await withRetry( + async () => factory.deploy(...args), + `deploy(${contractName})`, + ); + + const tx = contract.deploymentTransaction(); + if (tx) { + await withRetry(async () => tx.wait(1), `wait(1) ${contractName}`); + } + + const addr = await contract.getAddress(); + console.log(`${contractName} deployed to: ${addr}`); + return { contract, addr }; +} + +async function main() { + const [signer] = await ethers.getSigners(); + const sender = await signer.getAddress(); + + const parameters = await getDeploymentParameters(); + + if (!parameters.StateAtModule?.proxyAddress || !isNonZeroAddress(parameters.StateAtModule.proxyAddress)) { + throw new Error(`State proxy missing. Expected parameters.StateAtModule.proxyAddress`); + } + + // Skip if already deployed + if (parameters.IdentityTreeStoreAtModule?.proxyAddress && isNonZeroAddress(parameters.IdentityTreeStoreAtModule.proxyAddress)) { + console.log(`IdentityTreeStore proxy already set: ${parameters.IdentityTreeStoreAtModule.proxyAddress}`); + return; + } + + // Libraries required in this repo + + const poseidon2Addr = parameters.Poseidon2AtModule?.contractAddress; + const poseidon3Addr = parameters.Poseidon3AtModule?.contractAddress; + + + if (!isNonZeroAddress(poseidon2Addr)) throw new Error(`PoseidonUnit2L missing in params`); + if (!isNonZeroAddress(poseidon3Addr)) throw new Error(`PoseidonUnit3L missing in params`); + + console.log(`Deploying from: ${sender}`); + console.log(`Using State proxy: ${parameters.StateAtModule.proxyAddress}`); + + // 1) Deploy IdentityTreeStore implementation (likely linked) + // If your IdentityTreeStore uses different poseidon units, the error will tell us the exact names. + const implLibraries: Record = { + PoseidonUnit2L: poseidon2Addr, + PoseidonUnit3L: poseidon3Addr, + }; + + + const { contract: impl, addr: implAddr } = await deployByName("IdentityTreeStore", implLibraries); + + // 2) ProxyAdmin (OZ v5: constructor(initialOwner)) + const { addr: proxyAdminAddr } = await deployByName("ProxyAdmin", undefined, [sender]); + + // 3) TransparentUpgradeableProxy (OZ v5: (_logic, initialOwner, _data)) + const TransparentUpgradeableProxy = await withRetry( + async () => ethers.getContractFactory("TransparentUpgradeableProxy"), + "getContractFactory(TransparentUpgradeableProxy)", + ); + + const proxy = await withRetry( + async () => TransparentUpgradeableProxy.deploy(implAddr, sender, "0x"), + "deploy(TransparentUpgradeableProxy)", + ); + + const ptx = proxy.deploymentTransaction(); + if (ptx) await withRetry(async () => ptx.wait(1), "wait(1) TransparentUpgradeableProxy"); + + const proxyAddr = await proxy.getAddress(); + + console.log(`IdentityTreeStore proxy deployed to: ${proxyAddr}`); + console.log(`ProxyAdmin deployed to: ${proxyAdminAddr}`); + console.log(`IdentityTreeStore implementation deployed to: ${implAddr}`); + + // 4) Initialize via proxy + // Most iden3 IdentityTreeStore initializes with State address + owner/admin. + // We will introspect and call the correct initializer at runtime. + const identityAtProxy = impl.attach(proxyAddr); + + // Try common patterns (repo variations exist). We attempt in safe order. + const stateAddr = parameters.StateAtModule.proxyAddress; + + const tried: string[] = []; + const tryInit = async (fnName: string, args: any[]) => { + tried.push(`${fnName}(${args.map(() => "arg").join(",")})`); + const tx = await (identityAtProxy as any)[fnName](...args); + await tx.wait(1); + console.log(`✅ Initialized via ${fnName}`); + return true; + }; + + try { + // Pattern A: initialize(address state, address owner) + if ((identityAtProxy as any).initialize) { + try { + await withRetry(() => tryInit("initialize", [stateAddr, sender]), "IdentityTreeStore.initialize(state,owner)"); + } catch { + // Pattern B: initialize(address state) + await withRetry(() => tryInit("initialize", [stateAddr]), "IdentityTreeStore.initialize(state)"); + } + } else { + throw new Error("No initialize() found on IdentityTreeStore"); + } + } catch (e: any) { + console.log("❌ Could not initialize IdentityTreeStore with common signatures."); + console.log("Tried:", tried.join(" | ")); + throw e; + } + + // Save params + parameters.IdentityTreeStoreAtModule = { + proxyAddress: proxyAddr, + proxyAdminAddress: proxyAdminAddr, + }; + + parameters.IdentityTreeStoreNewImplementationAtModule ||= { contractAddress: "" }; + parameters.IdentityTreeStoreNewImplementationAtModule.contractAddress = implAddr; + + await writeDeploymentParameters(parameters); + + console.log(`✅ IdentityTreeStore (proxy): ${proxyAddr}`); +} + +main() + .then(() => process.exit(0)) + .catch((e) => { + console.error(e); + process.exit(1); + }); diff --git a/scripts/deploy/adi/deployLibraries.noignition.js b/scripts/deploy/adi/deployLibraries.noignition.js new file mode 100644 index 00000000..f9636d20 --- /dev/null +++ b/scripts/deploy/adi/deployLibraries.noignition.js @@ -0,0 +1,163 @@ +import { + getDeploymentParameters, + verifyContract, + writeDeploymentParameters, +} from "../../../helpers/helperUtils"; +import { contractsInfo } from "../../../helpers/constants"; +import { network } from "hardhat"; + +const { ethers } = await network.connect(); + +// Retry helper for flaky RPC 502s +async function withRetry(fn: () => Promise, label: string, tries = 8) { + let lastErr: any; + for (let i = 1; i <= tries; i++) { + try { + return await fn(); + } catch (e: any) { + lastErr = e; + const msg = String(e?.message || e); + const is502 = + msg.includes("502") || + msg.includes("Bad Gateway") || + msg.includes("unexpected status code"); + if (!is502) throw e; + + const waitMs = 1500 * i; + console.log( + `[retry ${i}/${tries}] ${label} hit RPC 502-ish error. Waiting ${waitMs}ms...`, + ); + await new Promise((r) => setTimeout(r, waitMs)); + } + } + throw lastErr; +} + +function isNonZeroAddress(addr?: string) { + return !!addr && /^0x[a-fA-F0-9]{40}$/.test(addr) && addr !== "0x0000000000000000000000000000000000000000"; +} + +async function deployByName( + contractName: string, + libraries?: Record, +) { + const factory = await withRetry( + async () => ethers.getContractFactory(contractName, { libraries }), + `getContractFactory(${contractName})`, + ); + + const contract = await withRetry( + async () => factory.deploy(), + `deploy(${contractName})`, + ); + + const tx = contract.deploymentTransaction(); + if (tx) { + await withRetry(async () => tx.wait(1), `wait(1) ${contractName}`); + } + + const addr = await contract.getAddress(); + return { contract, addr }; +} + +async function main() { + const [signer] = await ethers.getSigners(); + const sender = await signer.getAddress(); + + const parameters = await getDeploymentParameters(); + + // Ensure placeholders exist + parameters.Poseidon1AtModule ||= { contractAddress: "" }; + parameters.Poseidon2AtModule ||= { contractAddress: "" }; + parameters.Poseidon3AtModule ||= { contractAddress: "" }; + parameters.Poseidon4AtModule ||= { contractAddress: "" }; + parameters.SmtLibAtModule ||= { contractAddress: "" }; + + console.log(`Deploying from: ${sender}`); + + // --- Poseidon 1 --- + if (!isNonZeroAddress(parameters.Poseidon1AtModule.contractAddress)) { + const { addr } = await deployByName("PoseidonUnit1L"); + parameters.Poseidon1AtModule.contractAddress = addr; + console.log(`${contractsInfo.POSEIDON_1.name} deployed to: ${addr}`); + } else { + console.log( + `${contractsInfo.POSEIDON_1.name} already set: ${parameters.Poseidon1AtModule.contractAddress}`, + ); + } + + // --- Poseidon 2 --- + if (!isNonZeroAddress(parameters.Poseidon2AtModule.contractAddress)) { + const { addr } = await deployByName("PoseidonUnit2L"); + parameters.Poseidon2AtModule.contractAddress = addr; + console.log(`${contractsInfo.POSEIDON_2.name} deployed to: ${addr}`); + } else { + console.log( + `${contractsInfo.POSEIDON_2.name} already set: ${parameters.Poseidon2AtModule.contractAddress}`, + ); + } + + // --- Poseidon 3 --- + if (!isNonZeroAddress(parameters.Poseidon3AtModule.contractAddress)) { + const { addr } = await deployByName("PoseidonUnit3L"); + parameters.Poseidon3AtModule.contractAddress = addr; + console.log(`${contractsInfo.POSEIDON_3.name} deployed to: ${addr}`); + } else { + console.log( + `${contractsInfo.POSEIDON_3.name} already set: ${parameters.Poseidon3AtModule.contractAddress}`, + ); + } + + // --- Poseidon 4 --- + if (!isNonZeroAddress(parameters.Poseidon4AtModule.contractAddress)) { + const { addr } = await deployByName("PoseidonUnit4L"); + parameters.Poseidon4AtModule.contractAddress = addr; + console.log(`${contractsInfo.POSEIDON_4.name} deployed to: ${addr}`); + } else { + console.log( + `${contractsInfo.POSEIDON_4.name} already set: ${parameters.Poseidon4AtModule.contractAddress}`, + ); + } + + // --- SmtLib (requires linking PoseidonUnit2L + PoseidonUnit3L) --- + if (!isNonZeroAddress(parameters.SmtLibAtModule.contractAddress)) { + const p2 = parameters.Poseidon2AtModule.contractAddress; + const p3 = parameters.Poseidon3AtModule.contractAddress; + + if (!isNonZeroAddress(p2) || !isNonZeroAddress(p3)) { + throw new Error( + `Cannot deploy SmtLib: missing Poseidon links. Poseidon2=${p2} Poseidon3=${p3}`, + ); + } + + const { addr } = await deployByName("SmtLib", { + PoseidonUnit2L: p2, + PoseidonUnit3L: p3, + }); + + parameters.SmtLibAtModule.contractAddress = addr; + console.log(`${contractsInfo.SMT_LIB.name} deployed to: ${addr}`); + + // Optional verification (keep if your verify config is set up) + if (contractsInfo.SMT_LIB.verificationOpts) { + const net = await ethers.provider.getNetwork(); + if (Number(net.chainId) !== 99999) { + await verifyContract(addr, contractsInfo.SMT_LIB.verificationOpts); + } + } + } else { + console.log( + `${contractsInfo.SMT_LIB.name} already set: ${parameters.SmtLibAtModule.contractAddress}`, + ); + } + + await writeDeploymentParameters(parameters); + console.log("✅ Updated chain params with deployed library addresses."); +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/deploy/adi/deployState.noignition.ts b/scripts/deploy/adi/deployState.noignition.ts new file mode 100644 index 00000000..37c2149a --- /dev/null +++ b/scripts/deploy/adi/deployState.noignition.ts @@ -0,0 +1,190 @@ +import { + getDeploymentParameters, + writeDeploymentParameters, +} from "../../../helpers/helperUtils"; +import { ethers } from "hardhat"; + +// Retry helper for flaky RPC 502s +async function withRetry(fn: () => Promise, label: string, tries = 10): Promise { + let lastErr: unknown; + for (let i = 1; i <= tries; i++) { + try { + return await fn(); + } catch (e) { + lastErr = e; + const msg = String((e as Error)?.message || e); + const is502 = + msg.includes("502") || + msg.includes("Bad Gateway") || + msg.includes("unexpected status code"); + if (!is502) throw e; + + const waitMs = 1500 * i; + console.log(`[retry ${i}/${tries}] ${label} hit RPC 502-ish error. Waiting ${waitMs}ms...`); + await new Promise((r) => setTimeout(r, waitMs)); + } + } + throw lastErr as Error; +} + +function isNonZeroAddress(addr?: string): boolean { + return ( + !!addr && + /^0x[a-fA-F0-9]{40}$/.test(addr) && + addr !== "0x0000000000000000000000000000000000000000" + ); +} + +// Deploy a contract by name, with optional library linking + constructor args +async function deployByName( + contractName: string, + libraries?: Record, + args: unknown[] = [], +) { + const factory = await withRetry( + async () => ethers.getContractFactory(contractName, { libraries }), + `getContractFactory(${contractName})`, + ); + + const contract = await withRetry( + async () => factory.deploy(...args), + `deploy(${contractName})`, + ); + + await contract.waitForDeployment(); + + const addr = await contract.getAddress(); + console.log(`${contractName} deployed to: ${addr}`); + return { contract, addr }; +} + +async function main() { + const [signer] = await ethers.getSigners(); + const sender = await signer.getAddress(); + + const parameters = await getDeploymentParameters(); + + parameters.StateProxyFinalImplementationModule ||= { defaultIdType: "" }; + parameters.CrossChainProofValidatorModule ||= { oracleSigningAddress: sender }; + + const defaultIdType: string = parameters.StateProxyFinalImplementationModule.defaultIdType || ""; + + if (!defaultIdType) { + throw new Error( + "Missing StateProxyFinalImplementationModule.defaultIdType in deployment parameters.", + ); + } + + if (!/^0x[a-fA-F0-9]{4}$/.test(defaultIdType)) { + throw new Error(`defaultIdType must be bytes2 like 0x0113. Got: ${defaultIdType}`); + } + + console.log(`Deploying from: ${sender}`); + console.log(`defaultIdType: ${defaultIdType}`); + + if (parameters.StateAtModule?.proxyAddress && isNonZeroAddress(parameters.StateAtModule.proxyAddress)) { + console.log(`State proxy already set: ${parameters.StateAtModule.proxyAddress}`); + return; + } + + const oracle = parameters.CrossChainProofValidatorModule.oracleSigningAddress; + const domainName = "iden3"; + const signatureVersion = "1"; + + const { addr: crossChainProofValidatorAddr } = await deployByName( + "CrossChainProofValidator", + undefined, + [domainName, signatureVersion, oracle], + ); + + const { addr: groth16VerifierAddr } = await deployByName("Groth16VerifierStateTransition"); + const { addr: stateLibAddr } = await deployByName("StateLib"); + + const smtLibAddr = parameters.SmtLibAtModule?.contractAddress; + const poseidon1Addr = parameters.Poseidon1AtModule?.contractAddress; + + if (!isNonZeroAddress(smtLibAddr)) { + throw new Error(`SmtLib address missing in params. Got: ${smtLibAddr}`); + } + if (!isNonZeroAddress(poseidon1Addr)) { + throw new Error(`PoseidonUnit1L address missing in params. Got: ${poseidon1Addr}`); + } + + const stateLibraries: Record = { + PoseidonUnit1L: poseidon1Addr, + SmtLib: smtLibAddr, + StateLib: stateLibAddr, + }; + + const { contract: stateImpl, addr: stateImplAddr } = await deployByName("State", stateLibraries); + + const { addr: proxyAdminAddr } = await deployByName("ProxyAdmin", undefined, [sender]); + + const TransparentUpgradeableProxy = await withRetry( + async () => ethers.getContractFactory("TransparentUpgradeableProxy"), + "getContractFactory(TransparentUpgradeableProxy)", + ); + + const proxy = await withRetry( + async () => TransparentUpgradeableProxy.deploy(stateImplAddr, sender, "0x"), + "deploy(TransparentUpgradeableProxy)", + ); + await proxy.waitForDeployment(); + + const proxyAddr = await proxy.getAddress(); + console.log(`State proxy deployed to: ${proxyAddr}`); + console.log(`ProxyAdmin deployed to: ${proxyAdminAddr}`); + console.log(`State implementation deployed to: ${stateImplAddr}`); + + const stateAtProxy = stateImpl.attach(proxyAddr); + + console.log("Calling State.initialize(verifier, defaultIdType, owner, validator) ..."); + const initTx = await withRetry( + async () => + stateAtProxy.initialize( + groth16VerifierAddr, + defaultIdType, + sender, + crossChainProofValidatorAddr, + ), + "State.initialize", + ); + await initTx.wait(); + + console.log("✅ State initialized"); + + const deployedDefaultIdType = await stateAtProxy.getDefaultIdType(); + const deployedVerifier = await stateAtProxy.getVerifier(); + const deployedGistRoot = await stateAtProxy.getGISTRoot(); + + console.log("Post-init getDefaultIdType:", deployedDefaultIdType); + console.log("Post-init getVerifier:", deployedVerifier); + console.log("Post-init getGISTRoot:", deployedGistRoot.toString()); + + parameters.StateAtModule = { + proxyAddress: proxyAddr, + proxyAdminAddress: proxyAdminAddr, + }; + + parameters.CrossChainProofValidatorAtModule ||= { contractAddress: "" }; + parameters.Groth16VerifierStateTransitionAtModule ||= { contractAddress: "" }; + parameters.StateLibAtModule ||= { contractAddress: "" }; + parameters.StateNewImplementationAtModule ||= { contractAddress: "" }; + + parameters.CrossChainProofValidatorAtModule.contractAddress = crossChainProofValidatorAddr; + parameters.Groth16VerifierStateTransitionAtModule.contractAddress = groth16VerifierAddr; + parameters.StateLibAtModule.contractAddress = stateLibAddr; + parameters.StateNewImplementationAtModule.contractAddress = stateImplAddr; + + await writeDeploymentParameters(parameters); + + console.log(`✅ CrossChainProofValidator: ${crossChainProofValidatorAddr}`); + console.log(`✅ Groth16VerifierStateTransition: ${groth16VerifierAddr}`); + console.log(`✅ StateLib: ${stateLibAddr}`); + console.log(`✅ State (proxy): ${proxyAddr}`); +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); \ No newline at end of file diff --git a/scripts/deploy/adi/deployUniversalVerifier.noignition.ts b/scripts/deploy/adi/deployUniversalVerifier.noignition.ts new file mode 100644 index 00000000..0238b16d --- /dev/null +++ b/scripts/deploy/adi/deployUniversalVerifier.noignition.ts @@ -0,0 +1,178 @@ +import { + getDeploymentParameters, + writeDeploymentParameters, +} from "../../../helpers/helperUtils"; +import { network } from "hardhat"; + +const { ethers } = await network.connect(); + +async function withRetry(fn: () => Promise, label: string, tries = 10) { + let lastErr: any; + for (let i = 1; i <= tries; i++) { + try { + return await fn(); + } catch (e: any) { + lastErr = e; + const msg = String(e?.message || e); + const is502 = + msg.includes("502") || + msg.includes("Bad Gateway") || + msg.includes("unexpected status code"); + if (!is502) throw e; + + const waitMs = 1500 * i; + console.log(`[retry ${i}/${tries}] ${label} hit RPC 502-ish error. Waiting ${waitMs}ms...`); + await new Promise((r) => setTimeout(r, waitMs)); + } + } + throw lastErr; +} + +function isNonZeroAddress(addr?: string) { + return ( + !!addr && + /^0x[a-fA-F0-9]{40}$/.test(addr) && + addr !== "0x0000000000000000000000000000000000000000" + ); +} + +async function deployByName( + contractName: string, + libraries?: Record, + args: any[] = [], +) { + const factory = await withRetry( + async () => ethers.getContractFactory(contractName, { libraries }), + `getContractFactory(${contractName})`, + ); + + const contract = await withRetry( + async () => factory.deploy(...args), + `deploy(${contractName})`, + ); + + const tx = contract.deploymentTransaction(); + if (tx) { + await withRetry(async () => tx.wait(1), `wait(1) ${contractName}`); + } + + const addr = await contract.getAddress(); + console.log(`${contractName} deployed to: ${addr}`); + return { contract, addr }; +} + +async function main() { + const [signer] = await ethers.getSigners(); + const sender = await signer.getAddress(); + + const parameters = await getDeploymentParameters(); + + // Pre-reqs + const stateProxy = parameters.StateAtModule?.proxyAddress; + if (!isNonZeroAddress(stateProxy)) throw new Error("State proxy missing in params"); + + // Skip if already deployed + if ( + parameters.UniversalVerifierAtModule?.proxyAddress && + isNonZeroAddress(parameters.UniversalVerifierAtModule.proxyAddress) + ) { + console.log(`UniversalVerifier proxy already set: ${parameters.UniversalVerifierAtModule.proxyAddress}`); + return; + } + + console.log(`Deploying from: ${sender}`); + console.log(`Using State proxy: ${stateProxy}`); + + // UniversalVerifier in this repo usually links VerifierLib. + // We'll deploy VerifierLib first, then link it. + const { addr: verifierLibAddr } = await deployByName("VerifierLib"); + + const verifierLibraries: Record = { + VerifierLib: verifierLibAddr, + }; + + // Deploy implementation + const { contract: impl, addr: implAddr } = await deployByName("UniversalVerifier", verifierLibraries); + + // OZ v5 ProxyAdmin(initialOwner) + const { addr: proxyAdminAddr } = await deployByName("ProxyAdmin", undefined, [sender]); + + // OZ v5 TransparentUpgradeableProxy(_logic, initialOwner, _data) + const TransparentUpgradeableProxy = await withRetry( + async () => ethers.getContractFactory("TransparentUpgradeableProxy"), + "getContractFactory(TransparentUpgradeableProxy)", + ); + + const proxy = await withRetry( + async () => TransparentUpgradeableProxy.deploy(implAddr, sender, "0x"), + "deploy(TransparentUpgradeableProxy)", + ); + + const ptx = proxy.deploymentTransaction(); + if (ptx) await withRetry(async () => ptx.wait(1), "wait(1) TransparentUpgradeableProxy"); + + const proxyAddr = await proxy.getAddress(); + + console.log(`UniversalVerifier proxy deployed to: ${proxyAddr}`); + console.log(`ProxyAdmin deployed to: ${proxyAdminAddr}`); + console.log(`UniversalVerifier implementation deployed to: ${implAddr}`); + + // Initialize via proxy. + // Common signature: initialize(address state, address owner) OR initialize(address state) + const verifierAtProxy = impl.attach(proxyAddr); + + const tried: string[] = []; + const tryInit = async (fnName: string, args: any[]) => { + tried.push(`${fnName}(${args.length})`); + const tx = await (verifierAtProxy as any)[fnName](...args); + await tx.wait(1); + console.log(`✅ Initialized via ${fnName}`); + return true; + }; + + try { + if ((verifierAtProxy as any).initialize) { + try { + await withRetry( + () => tryInit("initialize", [stateProxy, sender]), + "UniversalVerifier.initialize(state,owner)", + ); + } catch { + await withRetry( + () => tryInit("initialize", [stateProxy]), + "UniversalVerifier.initialize(state)", + ); + } + } else { + throw new Error("No initialize() found on UniversalVerifier"); + } + } catch (e: any) { + console.log("❌ Could not initialize UniversalVerifier with common signatures."); + console.log("Tried:", tried.join(" | ")); + throw e; + } + + // Save params + parameters.UniversalVerifierAtModule = { + proxyAddress: proxyAddr, + proxyAdminAddress: proxyAdminAddr, + }; + + parameters.VerifierLibAtModule ||= { contractAddress: "" }; + parameters.UniversalVerifierNewImplementationAtModule ||= { contractAddress: "" }; + + parameters.VerifierLibAtModule.contractAddress = verifierLibAddr; + parameters.UniversalVerifierNewImplementationAtModule.contractAddress = implAddr; + + await writeDeploymentParameters(parameters); + + console.log(`✅ VerifierLib: ${verifierLibAddr}`); + console.log(`✅ UniversalVerifier (proxy): ${proxyAddr}`); +} + +main() + .then(() => process.exit(0)) + .catch((e) => { + console.error(e); + process.exit(1); + }); diff --git a/scripts/deploy/adi/deployValidators.noignition.ts b/scripts/deploy/adi/deployValidators.noignition.ts new file mode 100644 index 00000000..3db74b36 --- /dev/null +++ b/scripts/deploy/adi/deployValidators.noignition.ts @@ -0,0 +1,383 @@ +// scripts/deploy/adi/deployValidators.noignition.ts +import { + getDeploymentParameters, + writeDeploymentParameters, +} from "../../../helpers/helperUtils"; +import { network } from "hardhat"; + +const { ethers } = await network.connect(); + +// ------------------------ +// RPC retry (handles flaky 502 / Cloudflare) +// ------------------------ +async function withRetry(fn: () => Promise, label: string, tries = 10) { + let lastErr: any; + for (let i = 1; i <= tries; i++) { + try { + return await fn(); + } catch (e: any) { + lastErr = e; + const msg = String(e?.message || e); + const is502 = + msg.includes("502") || + msg.includes("Bad Gateway") || + msg.includes("unexpected status code"); + if (!is502) throw e; + + const waitMs = 1500 * i; + console.log( + `[retry ${i}/${tries}] ${label} hit RPC 502-ish error. Waiting ${waitMs}ms...`, + ); + await new Promise((r) => setTimeout(r, waitMs)); + } + } + throw lastErr; +} + +function isNonZeroAddress(addr?: string) { + return ( + !!addr && + /^0x[a-fA-F0-9]{40}$/.test(addr) && + addr !== "0x0000000000000000000000000000000000000000" + ); +} + +// OZ v5 Initializable: InvalidInitialization() selector 0xf92ee8a9 +function isAlreadyInitializedError(e: any) { + const data = e?.data ?? e?.info?.error?.data ?? e?.error?.data; + const msg = String(e?.message || "").toLowerCase(); + return ( + (typeof data === "string" && data.startsWith("0xf92ee8a9")) || + msg.includes("invalidinitialization") || + msg.includes("already initialized") + ); +} + +// ------------------------ +// Deploy helpers (resume-safe) +// ------------------------ +async function deployByName(contractName: string, args: any[] = [], libraries?: Record) { + const factory = await withRetry( + async () => ethers.getContractFactory(contractName, libraries ? { libraries } : undefined), + `getContractFactory(${contractName})`, + ); + + const contract = await withRetry( + async () => factory.deploy(...args), + `deploy(${contractName})`, + ); + + const tx = contract.deploymentTransaction(); + if (tx) await withRetry(async () => tx.wait(1), `wait(1) ${contractName}`); + + const addr = await contract.getAddress(); + console.log(`${contractName} deployed to: ${addr}`); + return { contract, addr }; +} + +async function ensurePlain( + params: any, + paramKey: string, + contractName: string, +) { + const existing = params[paramKey]?.contractAddress; + if (isNonZeroAddress(existing)) { + console.log(`${contractName} already set: ${existing}`); + return existing as string; + } + + params[paramKey] ||= { contractAddress: "" }; + + const { addr } = await deployByName(contractName); + params[paramKey].contractAddress = addr; + + // write immediately so reruns never redeploy + await writeDeploymentParameters(params); + return addr; +} + +async function ensureUpgradeableProxy( + params: any, + implName: string, + atKey: string, + implKey: string, +) { + const [signer] = await ethers.getSigners(); + const sender = await signer.getAddress(); + + const existingProxy = params[atKey]?.proxyAddress as string | undefined; + if (isNonZeroAddress(existingProxy)) { + console.log(`${implName} proxy already set: ${existingProxy}`); + return { proxyAddr: existingProxy, sender }; + } + + const { addr: implAddr } = await deployByName(implName); + const { addr: proxyAdminAddr } = await deployByName("ProxyAdmin", [sender]); + + const TUP = await withRetry( + async () => ethers.getContractFactory("TransparentUpgradeableProxy"), + "getContractFactory(TransparentUpgradeableProxy)", + ); + + // Hardhat v3 + OZ v5 artifact: ctor is (logic, initialOwner, data) + const proxy = await withRetry( + async () => TUP.deploy(implAddr, sender, "0x"), + `deploy(TransparentUpgradeableProxy for ${implName})`, + ); + + const ptx = proxy.deploymentTransaction(); + if (ptx) await withRetry(async () => ptx.wait(1), `wait(1) TUP ${implName}`); + + const proxyAddr = await proxy.getAddress(); + + console.log(`${implName} proxy deployed to: ${proxyAddr}`); + console.log(`ProxyAdmin deployed to: ${proxyAdminAddr}`); + console.log(`${implName} implementation deployed to: ${implAddr}`); + + // write BEFORE init so reruns never redeploy + params[atKey] = { proxyAddress: proxyAddr, proxyAdminAddress: proxyAdminAddr }; + params[implKey] ||= { contractAddress: "" }; + params[implKey].contractAddress = implAddr; + + await writeDeploymentParameters(params); + + return { proxyAddr, sender }; +} + +// ------------------------ +// ABI-driven initializer (works across different signatures) +// ------------------------ +async function callAnyInitializer( + contractName: string, + proxyAddr: string, + candidates: any[][], +) { + const factory = await withRetry( + async () => ethers.getContractFactory(contractName), + `getContractFactory(${contractName})`, + ); + const atProxy = factory.attach(proxyAddr); + + const initFrags = (atProxy.interface.fragments as any[]).filter( + (f) => f.type === "function" && f.name === "initialize", + ); + + const initSigs = initFrags.map((f) => f.format()); + + // No initializer? treat as ok + if (!initSigs.length) { + console.log(`ℹ️ ${contractName} has no initialize() in ABI. Skipping init.`); + return; + } + + for (const args of candidates) { + const matchingSigs = initSigs.filter((sig) => { + const frag = atProxy.interface.getFunction(sig); + return frag.inputs.length === args.length; + }); + + for (const sig of matchingSigs) { + try { + const fn = atProxy.getFunction(sig); // ethers v6 safe + const tx = await withRetry( + async () => fn(...args), + `${contractName}.${sig}`, + ); + await withRetry(async () => tx.wait(1), `wait(1) ${contractName} init`); + console.log(`✅ ${contractName} initialized via ${sig}`); + return; + } catch (e: any) { + if (isAlreadyInitializedError(e)) { + console.log(`ℹ️ ${contractName} already initialized (InvalidInitialization)`); + return; + } + // try next overload / candidate + } + } + } + + const available = initSigs.join(", "); + throw new Error( + `${contractName}: couldn't initialize with provided candidates.\n` + + `Available initialize overloads: ${available}\n` + + `Tried arg sets: ${candidates.map((a) => `(${a.length} args)`).join(", ")}`, + ); +} + +// Debug helper (optional but useful) +async function logInitializeOverloads(contractName: string, proxyAddr: string) { + const factory = await withRetry( + async () => ethers.getContractFactory(contractName), + `getContractFactory(${contractName})`, + ); + const atProxy = factory.attach(proxyAddr); + + const initFrags = (atProxy.interface.fragments as any[]).filter( + (f) => f.type === "function" && f.name === "initialize", + ); + const initSigs = initFrags.map((f) => f.format()); + console.log( + `ℹ️ ${contractName} initialize overloads: ${ + initSigs.length ? initSigs.join(", ") : "(none)" + }`, + ); + return initSigs; +} + +// ------------------------ +// Main +// ------------------------ +async function main() { + const params: any = await getDeploymentParameters(); + + const stateProxy = params.StateAtModule?.proxyAddress as string | undefined; + const universalVerifierProxy = params.UniversalVerifierAtModule?.proxyAddress as string | undefined; + const identityTreeStoreProxy = params.IdentityTreeStoreAtModule?.proxyAddress as string | undefined; + + if (!isNonZeroAddress(stateProxy)) + throw new Error("StateAtModule.proxyAddress missing in chain params"); + if (!isNonZeroAddress(universalVerifierProxy)) + throw new Error("UniversalVerifierAtModule.proxyAddress missing in chain params"); + if (!isNonZeroAddress(identityTreeStoreProxy)) + throw new Error("IdentityTreeStoreAtModule.proxyAddress missing in chain params"); + + const [signer] = await ethers.getSigners(); + const sender = await signer.getAddress(); + + console.log(`Using State proxy: ${stateProxy}`); + console.log(`Using UniversalVerifier proxy: ${universalVerifierProxy}`); + console.log(`Using IdentityTreeStore proxy: ${identityTreeStoreProxy}`); + console.log(`Deploying from: ${sender}`); + + // ---- Groth wrappers (resume-safe) + const grothMtp = await ensurePlain(params, "Groth16VerifierMTPWrapperAtModule", "Groth16VerifierMTPWrapper"); + const grothSig = await ensurePlain(params, "Groth16VerifierSigWrapperAtModule", "Groth16VerifierSigWrapper"); + const grothV3 = await ensurePlain(params, "Groth16VerifierV3WrapperAtModule", "Groth16VerifierV3Wrapper"); + const grothLMQ = await ensurePlain(params, "Groth16VerifierLinkedMultiQuery10WrapperAtModule", "Groth16VerifierLinkedMultiQuery10Wrapper"); + const grothAuth = await ensurePlain(params, "Groth16VerifierAuthV2WrapperAtModule", "Groth16VerifierAuthV2Wrapper"); + + // ---- Validators (resume-safe + ABI-driven init) + + // CredentialAtomicQueryMTPV2Validator + { + const { proxyAddr } = await ensureUpgradeableProxy( + params, + "CredentialAtomicQueryMTPV2Validator", + "CredentialAtomicQueryMTPV2ValidatorAtModule", + "CredentialAtomicQueryMTPV2ValidatorNewImplementationAtModule", + ); + + await callAnyInitializer("CredentialAtomicQueryMTPV2Validator", proxyAddr, [ + [stateProxy, identityTreeStoreProxy, grothMtp], + [stateProxy, universalVerifierProxy, grothMtp], + [stateProxy, identityTreeStoreProxy, universalVerifierProxy, grothMtp], + [stateProxy, universalVerifierProxy, identityTreeStoreProxy, grothMtp], + ]); + } + + // CredentialAtomicQuerySigV2Validator + { + const { proxyAddr } = await ensureUpgradeableProxy( + params, + "CredentialAtomicQuerySigV2Validator", + "CredentialAtomicQuerySigV2ValidatorAtModule", + "CredentialAtomicQuerySigV2ValidatorNewImplementationAtModule", + ); + + await callAnyInitializer("CredentialAtomicQuerySigV2Validator", proxyAddr, [ + [stateProxy, identityTreeStoreProxy, grothSig], + [stateProxy, universalVerifierProxy, grothSig], + [stateProxy, identityTreeStoreProxy, universalVerifierProxy, grothSig], + [stateProxy, universalVerifierProxy, identityTreeStoreProxy, grothSig], + ]); + } + + // CredentialAtomicQueryV3Validator + { + const { proxyAddr } = await ensureUpgradeableProxy( + params, + "CredentialAtomicQueryV3Validator", + "CredentialAtomicQueryV3ValidatorAtModule", + "CredentialAtomicQueryV3ValidatorNewImplementationAtModule", + ); + + await callAnyInitializer("CredentialAtomicQueryV3Validator", proxyAddr, [ + [stateProxy, identityTreeStoreProxy, grothV3], + [stateProxy, universalVerifierProxy, grothV3], + [stateProxy, identityTreeStoreProxy, universalVerifierProxy, grothV3], + [stateProxy, universalVerifierProxy, identityTreeStoreProxy, grothV3], + ]); + } + + // LinkedMultiQueryValidator + // Your deployed build shows ONLY: initialize(address,address) + // So we try sensible 2-arg combos (state + verifier) / (state + treeStore) and also swapped. + { + const { proxyAddr } = await ensureUpgradeableProxy( + params, + "LinkedMultiQueryValidator", + "LinkedMultiQueryValidatorAtModule", + "LinkedMultiQueryValidatorNewImplementationAtModule", + ); + + const initSigs = await logInitializeOverloads("LinkedMultiQueryValidator", proxyAddr); + + if (!initSigs.includes("initialize(address,address)")) { + console.log("⚠️ LinkedMultiQueryValidator has no initialize(address,address) - skipping init."); + } else { + await callAnyInitializer("LinkedMultiQueryValidator", proxyAddr, [ + [stateProxy, universalVerifierProxy], + [stateProxy, identityTreeStoreProxy], + [universalVerifierProxy, stateProxy], + [identityTreeStoreProxy, stateProxy], + ]); + } + } + + // AuthV2Validator + { + const { proxyAddr } = await ensureUpgradeableProxy( + params, + "AuthV2Validator", + "AuthV2ValidatorAtModule", + "AuthV2ValidatorNewImplementationAtModule", + ); + + await callAnyInitializer("AuthV2Validator", proxyAddr, [ + [stateProxy, identityTreeStoreProxy, grothAuth], + [stateProxy, universalVerifierProxy, grothAuth], + [stateProxy, identityTreeStoreProxy, universalVerifierProxy, grothAuth], + [stateProxy, universalVerifierProxy, identityTreeStoreProxy, grothAuth], + ]); + } + + // EthIdentityValidator + { + const { proxyAddr } = await ensureUpgradeableProxy( + params, + "EthIdentityValidator", + "EthIdentityValidatorAtModule", + "EthIdentityValidatorNewImplementationAtModule", + ); + + // ABI says: initialize(address) + await logInitializeOverloads("EthIdentityValidator", proxyAddr); + + await callAnyInitializer("EthIdentityValidator", proxyAddr, [ + [stateProxy], // most likely correct + [universalVerifierProxy], // fallback (unlikely but safe to try) + [identityTreeStoreProxy], // fallback (unlikely but safe to try) + ]); + } + + + console.log("✅ Validators deployed + initialized (resume-safe)."); + await writeDeploymentParameters(params); +} + +main() + .then(() => process.exit(0)) + .catch((e) => { + console.error(e); + process.exit(1); + }); diff --git a/scripts/deploy/adi/deployVerifierAndSet.ts b/scripts/deploy/adi/deployVerifierAndSet.ts new file mode 100644 index 00000000..bf6ac033 --- /dev/null +++ b/scripts/deploy/adi/deployVerifierAndSet.ts @@ -0,0 +1,38 @@ +import { network } from "hardhat"; + +async function main() { + const { ethers } = await network.connect(); + + // ---------------------------- + // 1. Deploy verifier + // ---------------------------- + const Verifier = await ethers.getContractFactory("Groth16VerifierStateTransition"); + + console.log("Deploying Groth16VerifierStateTransition..."); + + const verifier = await Verifier.deploy(); + await verifier.waitForDeployment(); + + const verifierAddress = await verifier.getAddress(); + + console.log("Verifier deployed at:", verifierAddress); + + // ---------------------------- + // 2. Update State contract + // ---------------------------- + const STATE_ADDRESS = "0x35E20F0A1cf70b921F4d72536F2e599982B9352B"; + + const state = await ethers.getContractAt("State", STATE_ADDRESS); + + console.log("Updating verifier in State contract..."); + + const tx = await state.setVerifier(verifierAddress); + await tx.wait(); + + console.log("State verifier updated successfully."); +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); \ No newline at end of file diff --git a/scripts/deploy/adi/test-adi-tx.js b/scripts/deploy/adi/test-adi-tx.js new file mode 100644 index 00000000..3879c82c --- /dev/null +++ b/scripts/deploy/adi/test-adi-tx.js @@ -0,0 +1,44 @@ +const { ethers } = require("ethers"); + +async function main() { + const rpc = "https://rpc.ab.testnet.adifoundation.ai"; + const provider = new ethers.JsonRpcProvider(rpc, { + name: "adiTestnet", + chainId: 99999, + }); + + const privateKey = "YOUR_FUNDED_PRIVATE_KEY_HERE"; + const wallet = new ethers.Wallet(privateKey, provider); + + console.log("Wallet address:", await wallet.getAddress()); + + const balance = await provider.getBalance(wallet.address); + console.log("Balance:", ethers.formatEther(balance)); + + const feeData = await provider.getFeeData(); + console.log("Fee data:", { + gasPrice: feeData.gasPrice?.toString(), + maxFeePerGas: feeData.maxFeePerGas?.toString(), + maxPriorityFeePerGas: feeData.maxPriorityFeePerGas?.toString(), + }); + + const nonce = await provider.getTransactionCount(wallet.address, "latest"); + console.log("Nonce:", nonce); + + const tx = await wallet.sendTransaction({ + to: wallet.address, + value: 0n, + nonce, + gasLimit: 21000n, + maxPriorityFeePerGas: 0n, + maxFeePerGas: feeData.maxFeePerGas ?? feeData.gasPrice ?? ethers.parseUnits("600", "gwei"), + chainId: 99999, + type: 2, + }); + + console.log("TX hash:", tx.hash); + const receipt = await tx.wait(); + console.log("Receipt:", receipt); +} + +main().catch(console.error); \ No newline at end of file diff --git a/test/state/adi-eth-two-step-transition.test.ts b/test/state/adi-eth-two-step-transition.test.ts new file mode 100644 index 00000000..42438659 --- /dev/null +++ b/test/state/adi-eth-two-step-transition.test.ts @@ -0,0 +1,146 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { deployPoseidons } from "../../helpers/PoseidonDeployHelper"; + +describe("ADI ETH issuer multi-step state transition", function () { + it("supports five sequential transitions for the same ETH issuer", async function () { + const [deployer, issuer] = await ethers.getSigners(); + + const idType = "0x01f9"; + + // ---------- Deploy dependencies ---------- + const CrossChainProofValidator = await ethers.getContractFactory("CrossChainProofValidator"); + const crossChainProofValidator = await CrossChainProofValidator.deploy( + "iden3", + "1", + await deployer.getAddress(), + ); + await crossChainProofValidator.waitForDeployment(); + + const Groth16VerifierStateTransition = await ethers.getContractFactory( + "Groth16VerifierStateTransition", + ); + const groth16VerifierStateTransition = await Groth16VerifierStateTransition.deploy(); + await groth16VerifierStateTransition.waitForDeployment(); + + // ---------- Deploy real Poseidon contracts via helper ---------- + const [poseidon1, poseidon2, poseidon3] = await deployPoseidons([1, 2, 3], "basic"); + + // ---------- Sanity-check Poseidon ---------- + const poseidon1Hash = await poseidon1["poseidon(uint256[1])"]([123n]); + const poseidon3HashA = await poseidon3["poseidon(uint256[3])"]([0n, 111n, 1n]); + const poseidon3HashB = await poseidon3["poseidon(uint256[3])"]([0n, 222n, 1n]); + + expect(poseidon1Hash).to.not.equal(0n); + expect(poseidon3HashA).to.not.equal(0n); + expect(poseidon3HashB).to.not.equal(0n); + expect(poseidon3HashA).to.not.equal(poseidon3HashB); + + // ---------- Deploy SmtLib with linked Poseidon libs ---------- + const SmtLibFactory = await ethers.getContractFactory("SmtLib", { + libraries: { + PoseidonUnit2L: await poseidon2.getAddress(), + PoseidonUnit3L: await poseidon3.getAddress(), + }, + }); + const smtLib = await SmtLibFactory.deploy(); + await smtLib.waitForDeployment(); + + // ---------- Deploy StateLib ---------- + const StateLibFactory = await ethers.getContractFactory("StateLib"); + const stateLib = await StateLibFactory.deploy(); + await stateLib.waitForDeployment(); + + // ---------- Deploy StateCrossChainLib ---------- + const StateCrossChainLibFactory = await ethers.getContractFactory("StateCrossChainLib"); + const stateCrossChainLib = await StateCrossChainLibFactory.deploy(); + await stateCrossChainLib.waitForDeployment(); + + // ---------- Prepare State factory with linked libraries ---------- + const StateFactory = await ethers.getContractFactory("State", { + libraries: { + PoseidonUnit1L: await poseidon1.getAddress(), + SmtLib: await smtLib.getAddress(), + StateLib: await stateLib.getAddress(), + StateCrossChainLib: await stateCrossChainLib.getAddress(), + }, + }); + + // ---------- Deploy State implementation ---------- + const stateImpl = await StateFactory.deploy(); + await stateImpl.waitForDeployment(); + + // ---------- Deploy proxy ---------- + const TransparentUpgradeableProxyFactory = await ethers.getContractFactory( + "TransparentUpgradeableProxy", + ); + + const proxy = await TransparentUpgradeableProxyFactory.deploy( + await stateImpl.getAddress(), + await deployer.getAddress(), + "0x", + ); + await proxy.waitForDeployment(); + + // ---------- Attach State ABI to proxy ---------- + const state = StateFactory.attach(await proxy.getAddress()); + + // ---------- Initialize State via proxy ---------- + const initTx = await state.initialize( + await groth16VerifierStateTransition.getAddress(), + idType, + await deployer.getAddress(), + await crossChainProofValidator.getAddress(), + ); + await initTx.wait(); + + // ---------- Deploy GenesisUtilsWrapper ---------- + const GenesisUtilsWrapperFactory = await ethers.getContractFactory("GenesisUtilsWrapper"); + const genesisWrapper = await GenesisUtilsWrapperFactory.deploy(); + await genesisWrapper.waitForDeployment(); + + // ---------- Build issuer id exactly like contract does ---------- + const issuerAddress = await issuer.getAddress(); + const issuerId = await genesisWrapper.calcOnchainIdFromAddress(idType, issuerAddress); + + // ---------- Check GIST key is non-zero ---------- + const gistKey = await poseidon1["poseidon(uint256[1])"]([issuerId]); + expect(gistKey).to.not.equal(0n); + + // ---------- Sequential deterministic states ---------- + const states = [111n, 222n, 333n, 444n, 555n]; + + // ---------- First transition (genesis -> states[0]) ---------- + const tx1 = await state + .connect(issuer) + .transitStateGeneric(issuerId, 0n, states[0], true, 1, "0x"); + await tx1.wait(); + + expect(await state.idExists(issuerId)).to.equal(true); + expect(await state.stateExists(issuerId, states[0])).to.equal(true); + + let latest = await state.getStateInfoById(issuerId); + expect(latest.state).to.equal(states[0]); + + // ---------- Remaining transitions ---------- + for (let i = 1; i < states.length; i++) { + const tx = await state + .connect(issuer) + .transitStateGeneric(issuerId, states[i - 1], states[i], false, 1, "0x"); + await tx.wait(); + + expect(await state.stateExists(issuerId, states[i])).to.equal(true); + + latest = await state.getStateInfoById(issuerId); + expect(latest.state).to.equal(states[i]); + } + + // ---------- Extra sanity checks ---------- + for (const s of states) { + expect(await state.stateExists(issuerId, s)).to.equal(true); + } + + const finalStateInfo = await state.getStateInfoById(issuerId); + expect(finalStateInfo.state).to.equal(states[states.length - 1]); + }); +}); \ No newline at end of file diff --git a/test/state/adi-eth-two-step-transition.test.v2.ts b/test/state/adi-eth-two-step-transition.test.v2.ts new file mode 100644 index 00000000..66e5d5a4 --- /dev/null +++ b/test/state/adi-eth-two-step-transition.test.v2.ts @@ -0,0 +1,153 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; + +describe("ADI ETH issuer multi-step state transition", function () { + it("first, second, and third transitions succeed for the same ETH issuer", async function () { + const [deployer, issuer] = await ethers.getSigners(); + + const idType = "0x01f9"; + + // ---------- Deploy dependencies ---------- + const CrossChainProofValidator = await ethers.getContractFactory("CrossChainProofValidator"); + const crossChainProofValidator = await CrossChainProofValidator.deploy( + "iden3", + "1", + await deployer.getAddress(), + ); + await crossChainProofValidator.waitForDeployment(); + + const Groth16VerifierStateTransition = await ethers.getContractFactory( + "Groth16VerifierStateTransition", + ); + const groth16VerifierStateTransition = await Groth16VerifierStateTransition.deploy(); + await groth16VerifierStateTransition.waitForDeployment(); + + // ---------- Deploy Poseidon libraries ---------- + const PoseidonUnit1LFactory = await ethers.getContractFactory("PoseidonUnit1L"); + const poseidon1 = await PoseidonUnit1LFactory.deploy(); + await poseidon1.waitForDeployment(); + + const PoseidonUnit2LFactory = await ethers.getContractFactory("PoseidonUnit2L"); + const poseidon2 = await PoseidonUnit2LFactory.deploy(); + await poseidon2.waitForDeployment(); + + const PoseidonUnit3LFactory = await ethers.getContractFactory("PoseidonUnit3L"); + const poseidon3 = await PoseidonUnit3LFactory.deploy(); + await poseidon3.waitForDeployment(); + + // ---------- Deploy SmtLib with linked Poseidon libs ---------- + const SmtLibFactory = await ethers.getContractFactory("SmtLib", { + libraries: { + PoseidonUnit2L: await poseidon2.getAddress(), + PoseidonUnit3L: await poseidon3.getAddress(), + }, + }); + const smtLib = await SmtLibFactory.deploy(); + await smtLib.waitForDeployment(); + + // ---------- Deploy StateLib ---------- + const StateLibFactory = await ethers.getContractFactory("StateLib"); + const stateLib = await StateLibFactory.deploy(); + await stateLib.waitForDeployment(); + + // ---------- Deploy StateCrossChainLib ---------- + const StateCrossChainLibFactory = await ethers.getContractFactory("StateCrossChainLib"); + const stateCrossChainLib = await StateCrossChainLibFactory.deploy(); + await stateCrossChainLib.waitForDeployment(); + + // ---------- Prepare State factory with linked libraries ---------- + const StateFactory = await ethers.getContractFactory("State", { + libraries: { + PoseidonUnit1L: await poseidon1.getAddress(), + SmtLib: await smtLib.getAddress(), + StateLib: await stateLib.getAddress(), + StateCrossChainLib: await stateCrossChainLib.getAddress(), + }, + }); + + // ---------- Deploy State implementation ---------- + const stateImpl = await StateFactory.deploy(); + await stateImpl.waitForDeployment(); + + // ---------- Deploy proxy ---------- + const TransparentUpgradeableProxyFactory = await ethers.getContractFactory( + "TransparentUpgradeableProxy", + ); + + const proxy = await TransparentUpgradeableProxyFactory.deploy( + await stateImpl.getAddress(), + await deployer.getAddress(), + "0x", + ); + await proxy.waitForDeployment(); + + // ---------- Attach State ABI to proxy ---------- + const state = StateFactory.attach(await proxy.getAddress()); + + // ---------- Initialize State via proxy ---------- + const initTx = await state.initialize( + await groth16VerifierStateTransition.getAddress(), + idType, + await deployer.getAddress(), + await crossChainProofValidator.getAddress(), + ); + await initTx.wait(); + + // ---------- Deploy GenesisUtilsWrapper ---------- + const GenesisUtilsWrapperFactory = await ethers.getContractFactory("GenesisUtilsWrapper"); + const genesisWrapper = await GenesisUtilsWrapperFactory.deploy(); + await genesisWrapper.waitForDeployment(); + + // ---------- Build issuer id exactly like contract does ---------- + const issuerAddress = await issuer.getAddress(); + const issuerId = await genesisWrapper.calcOnchainIdFromAddress(idType, issuerAddress); + + // ---------- Deterministic non-zero states ---------- + const oldStateGenesis = 0n; + const firstNewState = + 585371391340085815916792376863458866660038082260120574400716976883002899639n; + const secondNewState = + 16980510869348741758136660225132813271232974884410278164689407139069911556500n; + const thirdNewState = + 21980510869348741758136660225132813271232974884410278164689407139069911556500n; + + // ---------- First transition ---------- + const tx1 = await state + .connect(issuer) + .transitStateGeneric(issuerId, oldStateGenesis, firstNewState, true, 1, "0x"); + await tx1.wait(); + + expect(await state.idExists(issuerId)).to.equal(true); + expect(await state.stateExists(issuerId, firstNewState)).to.equal(true); + + const stateInfoAfterFirst = await state.getStateInfoById(issuerId); + expect(stateInfoAfterFirst.state).to.equal(firstNewState); + + // ---------- Second transition ---------- + const tx2 = await state + .connect(issuer) + .transitStateGeneric(issuerId, firstNewState, secondNewState, false, 1, "0x"); + await tx2.wait(); + + expect(await state.stateExists(issuerId, secondNewState)).to.equal(true); + + const stateInfoAfterSecond = await state.getStateInfoById(issuerId); + expect(stateInfoAfterSecond.state).to.equal(secondNewState); + + // ---------- Third transition ---------- + const tx3 = await state + .connect(issuer) + .transitStateGeneric(issuerId, secondNewState, thirdNewState, false, 1, "0x"); + await tx3.wait(); + + expect(await state.stateExists(issuerId, thirdNewState)).to.equal(true); + + const stateInfoAfterThird = await state.getStateInfoById(issuerId); + expect(stateInfoAfterThird.state).to.equal(thirdNewState); + + // ---------- Extra sanity checks ---------- + expect(await state.stateExists(issuerId, firstNewState)).to.equal(true); + expect(await state.stateExists(issuerId, secondNewState)).to.equal(true); + expect(await state.stateExists(issuerId, thirdNewState)).to.equal(true); + }); +}); \ No newline at end of file diff --git a/test/state/poseidon-sanity.test.ts b/test/state/poseidon-sanity.test.ts new file mode 100644 index 00000000..3bd5f114 --- /dev/null +++ b/test/state/poseidon-sanity.test.ts @@ -0,0 +1,29 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; + +describe("Poseidon sanity", function () { + it("Poseidon libraries should not return zero for normal inputs", async function () { + const PoseidonUnit1LFactory = await ethers.getContractFactory("PoseidonUnit1L"); + const poseidon1 = await PoseidonUnit1LFactory.deploy(); + await poseidon1.waitForDeployment(); + + const PoseidonUnit2LFactory = await ethers.getContractFactory("PoseidonUnit2L"); + const poseidon2 = await PoseidonUnit2LFactory.deploy(); + await poseidon2.waitForDeployment(); + + const PoseidonUnit3LFactory = await ethers.getContractFactory("PoseidonUnit3L"); + const poseidon3 = await PoseidonUnit3LFactory.deploy(); + await poseidon3.waitForDeployment(); + + const h1 = await poseidon1.poseidon([123n]); + const h2 = await poseidon2.poseidon([123n, 456n]); + const h3a = await poseidon3.poseidon([0n, 111n, 1n]); + const h3b = await poseidon3.poseidon([0n, 222n, 1n]); + + expect(h1).to.not.equal(0n); + expect(h2).to.not.equal(0n); + expect(h3a).to.not.equal(0n); + expect(h3b).to.not.equal(0n); + expect(h3a).to.not.equal(h3b); + }); +}); \ No newline at end of file