Skip to content

Commit db1b369

Browse files
Updates to extension architecture (#211)
Co-authored-by: semaraugusto <[email protected]>
1 parent ef60226 commit db1b369

File tree

140 files changed

+13825
-14155
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

140 files changed

+13825
-14155
lines changed

.prettierrc.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"options": {
66
"printWidth": 100,
77
"tabWidth": 4,
8-
"useTabs": false,
8+
"useTabs": true,
99
"singleQuote": false,
1010
"bracketSpacing": true
1111
}

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"hardhat-gas-reporter": "^1.0.8",
5353
"lerna": "^5.4.3",
5454
"nx": "^14.5.10",
55+
"prettier-plugin-solidity": "^1.0.0",
5556
"truffle-assertions": "^0.9.2",
5657
"web3": "^1.3.6",
5758
"web3-utils": "^1.2.11"

packages/anchors/src/ChainalysisVAnchor.ts

+5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ export class ChainalysisVAnchor extends VAnchor {
3434
);
3535
createdVAnchor.latestSyncedBlock = vAnchor.deployTransaction.blockNumber!;
3636
createdVAnchor.token = token;
37+
const tx = await createdVAnchor.contract.initialize(
38+
BigNumber.from('1'),
39+
BigNumber.from(2).pow(256).sub(1)
40+
);
41+
await tx.wait();
3742
return createdVAnchor;
3843
}
3944
}

packages/anchors/src/IdentityVAnchor.ts

+50-185
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,18 @@ import {
2626
CircomUtxo,
2727
} from '@webb-tools/sdk-core';
2828
import {
29-
IAnchorDeposit,
30-
IAnchor,
29+
IVAnchor,
3130
IIdentityVariableAnchorExtData,
3231
IIdentityVariableAnchorPublicInputs,
33-
IAnchorDepositInfo,
3432
} from '@webb-tools/interfaces';
35-
import { hexToU8a, u8aToHex, getChainIdType, UTXOInputs, ZkComponents } from '@webb-tools/utils';
33+
import {
34+
hexToU8a,
35+
u8aToHex,
36+
getChainIdType,
37+
UTXOInputs,
38+
ZkComponents,
39+
ZERO_BYTES32,
40+
} from '@webb-tools/utils';
3641
import { Semaphore } from '@webb-tools/semaphore';
3742
import { LinkedGroup } from '@webb-tools/semaphore-group';
3843

@@ -77,7 +82,7 @@ export var proofTimeBenchmark = [];
7782
// It represents a deployed contract throughout its life (e.g. maintains merkle tree state)
7883
// Functionality relevant to anchors in general (proving, verifying) is implemented in static methods
7984
// Functionality relevant to a particular anchor deployment (deposit, withdraw) is implemented in instance methods
80-
export class IdentityVAnchor implements IAnchor {
85+
export class IdentityVAnchor implements IVAnchor {
8186
signer: ethers.Signer;
8287
contract: IdentityVAnchorContract;
8388
semaphore: Semaphore;
@@ -117,59 +122,7 @@ export class IdentityVAnchor implements IAnchor {
117122
this.smallCircuitZkComponents = smallCircuitZkComponents;
118123
this.largeCircuitZkComponents = largeCircuitZkComponents;
119124
}
120-
deposit(destinationChainId: number): Promise<IAnchorDeposit> {
121-
throw new Error('Method not implemented.');
122-
}
123-
setupWithdraw(
124-
deposit: IAnchorDepositInfo,
125-
index: number,
126-
recipient: string,
127-
relayer: string,
128-
fee: bigint,
129-
refreshCommitment: string | number
130-
) {
131-
throw new Error('Method not implemented.');
132-
}
133-
withdraw(
134-
deposit: IAnchorDepositInfo,
135-
index: number,
136-
recipient: string,
137-
relayer: string,
138-
fee: bigint,
139-
refreshCommitment: string | number
140-
): Promise<ethers.Event> {
141-
throw new Error('Method not implemented.');
142-
}
143-
wrapAndDeposit(
144-
tokenAddress: string,
145-
wrappingFee: number,
146-
destinationChainId?: number
147-
): Promise<IAnchorDeposit> {
148-
throw new Error('Method not implemented.');
149-
}
150-
bridgedWithdrawAndUnwrap(
151-
deposit: IAnchorDeposit,
152-
merkleProof: any,
153-
recipient: string,
154-
relayer: string,
155-
fee: string,
156-
refund: string,
157-
refreshCommitment: string,
158-
tokenAddress: string
159-
): Promise<ethers.Event> {
160-
throw new Error('Method not implemented.');
161-
}
162-
bridgedWithdraw(
163-
deposit: IAnchorDeposit,
164-
merkleProof: any,
165-
recipient: string,
166-
relayer: string,
167-
fee: string,
168-
refund: string,
169-
refreshCommitment: string
170-
): Promise<ethers.Event> {
171-
throw new Error('Method not implemented.');
172-
}
125+
173126
getAddress(): string {
174127
return this.contract.address;
175128
}
@@ -201,8 +154,8 @@ export class IdentityVAnchor implements IAnchor {
201154
const vAnchor = await factory.deploy(
202155
semaphore.contract.address,
203156
verifier,
204-
levels,
205157
hasher,
158+
levels,
206159
handler,
207160
token,
208161
maxEdges,
@@ -221,6 +174,11 @@ export class IdentityVAnchor implements IAnchor {
221174
);
222175
createdIdentityVAnchor.latestSyncedBlock = vAnchor.deployTransaction.blockNumber!;
223176
createdIdentityVAnchor.token = token;
177+
const tx = await createdIdentityVAnchor.contract.initialize(
178+
BigNumber.from('1'),
179+
BigNumber.from(2).pow(256).sub(1)
180+
);
181+
await tx.wait();
224182
return createdIdentityVAnchor;
225183
}
226184

@@ -235,7 +193,7 @@ export class IdentityVAnchor implements IAnchor {
235193
) {
236194
const anchor = IdentityVAnchor__factory.connect(address, signer);
237195
const maxEdges = await anchor.maxEdges();
238-
const treeHeight = await anchor.levels();
196+
const treeHeight = await anchor.outerLevels();
239197
const groupId = await anchor.groupId();
240198
const createdAnchor = new IdentityVAnchor(
241199
anchor,
@@ -466,7 +424,7 @@ export class IdentityVAnchor implements IAnchor {
466424
return rootData.root;
467425
});
468426
let thisRoot = await this.contract.getLastRoot();
469-
return [thisRoot, ...neighborRootInfos];
427+
return [thisRoot.toString(), ...neighborRootInfos.map((bignum) => bignum.toString())];
470428
}
471429

472430
public async getClassAndContractRoots() {
@@ -709,6 +667,7 @@ export class IdentityVAnchor implements IAnchor {
709667
relayer: string,
710668
fee: BigNumber,
711669
refund: BigNumber,
670+
wrapUnwrapToken: string,
712671
encryptedOutput1: string,
713672
encryptedOutput2: string
714673
): Promise<{ extData: ExtData; extDataHash: BigNumber }> {
@@ -718,7 +677,7 @@ export class IdentityVAnchor implements IAnchor {
718677
relayer: toFixedHex(relayer, 20),
719678
fee: toFixedHex(fee),
720679
refund: toFixedHex(refund.toString()),
721-
token: toFixedHex(this.token, 20),
680+
token: toFixedHex(wrapUnwrapToken, 20),
722681
encryptedOutput1,
723682
encryptedOutput2,
724683
};
@@ -731,7 +690,7 @@ export class IdentityVAnchor implements IAnchor {
731690
recipient,
732691
relayer,
733692
refund.toString(),
734-
this.token
693+
wrapUnwrapToken
735694
);
736695
return { extData, extDataHash };
737696
}
@@ -789,7 +748,8 @@ export class IdentityVAnchor implements IAnchor {
789748
fee: BigNumberish,
790749
refund: BigNumberish,
791750
recipient: string,
792-
relayer: string
751+
relayer: string,
752+
wrapUnwrapToken: string
793753
): Promise<ethers.ContractTransaction> {
794754
const chainId = getChainIdType(await this.signer.getChainId());
795755
const randomKeypair = new Keypair();
@@ -832,104 +792,17 @@ export class IdentityVAnchor implements IAnchor {
832792
.add(outputs.reduce((sum, x) => sum.add(BigNumber.from(BigInt(x.amount))), BigNumber.from(0)))
833793
.sub(inputs.reduce((sum, x) => sum.add(BigNumber.from(BigInt(x.amount))), BigNumber.from(0)));
834794

835-
const { extData, extDataHash } = await this.generateExtData(
836-
recipient,
837-
extAmount,
838-
relayer,
839-
BigNumber.from(fee),
840-
BigNumber.from(refund),
841-
outputs[0].encrypt(),
842-
outputs[1].encrypt()
843-
);
844-
845-
const vanchorInput: UTXOInputs = await this.generateUTXOInputs(
846-
inputs,
847-
outputs,
848-
chainId,
849-
extAmount,
850-
BigNumber.from(fee),
851-
extDataHash
852-
);
853-
854-
const outSemaphoreProofs = this.generateOutputSemaphoreProof(outputs);
855-
856-
const publicInputs = await this.setupTransaction(
857-
keypair,
858-
identityRootInputs,
859-
identityMerkleProof,
860-
outSemaphoreProofs,
861-
vanchorInput,
862-
extDataHash.toString()
863-
);
864-
865-
let tx = await this.contract.transact({ ...publicInputs }, extData, { gasLimit: '0x5B8D80' });
866-
867-
// Add the leaves to the tree
868-
outputs.forEach((x) => {
869-
this.tree.insert(u8aToHex(x.commitment));
870-
let numOfElements = this.tree.number_of_elements();
871-
this.depositHistory[numOfElements - 1] = toFixedHex(this.tree.root().toString());
872-
});
873-
874-
return tx;
875-
}
876-
877-
public async transactWrap(
878-
tokenAddress: string,
879-
keypair: Keypair,
880-
inputs: Utxo[],
881-
outputs: Utxo[],
882-
fee: BigNumberish,
883-
refund: BigNumberish,
884-
recipient: string,
885-
relayer: string
886-
): Promise<ethers.ContractTransaction> {
887-
// Default UTXO chain ID will match with the configured signer's chain ID
888-
const evmId = await this.signer.getChainId();
889-
const chainId = getChainIdType(evmId);
890-
const randomKeypair = new Keypair();
891-
892-
const identityRootInputs = this.populateIdentityRootsForProof();
893-
const identityMerkleProof: MerkleProof = this.generateIdentityMerkleProof(keypair.getPubKey());
894-
895-
while (inputs.length !== 2 && inputs.length < 16) {
896-
inputs.push(
897-
await CircomUtxo.generateUtxo({
898-
curve: 'Bn254',
899-
backend: 'Circom',
900-
chainId: chainId.toString(),
901-
originChainId: chainId.toString(),
902-
amount: '0',
903-
blinding: hexToU8a(randomBN(31).toHexString()),
904-
keypair: randomKeypair,
905-
})
906-
);
795+
if (wrapUnwrapToken.length === 0) {
796+
wrapUnwrapToken = this.token;
907797
}
908798

909-
if (outputs.length < 2) {
910-
while (outputs.length < 2) {
911-
outputs.push(
912-
await CircomUtxo.generateUtxo({
913-
curve: 'Bn254',
914-
backend: 'Circom',
915-
chainId: chainId.toString(),
916-
originChainId: chainId.toString(),
917-
amount: '0',
918-
keypair: randomKeypair,
919-
})
920-
);
921-
}
922-
}
923-
let extAmount = BigNumber.from(fee)
924-
.add(outputs.reduce((sum, x) => sum.add(x.amount), BigNumber.from(0)))
925-
.sub(inputs.reduce((sum, x) => sum.add(x.amount), BigNumber.from(0)));
926-
927799
const { extData, extDataHash } = await this.generateExtData(
928800
recipient,
929801
extAmount,
930802
relayer,
931803
BigNumber.from(fee),
932804
BigNumber.from(refund),
805+
wrapUnwrapToken,
933806
outputs[0].encrypt(),
934807
outputs[1].encrypt()
935808
);
@@ -954,46 +827,38 @@ export class IdentityVAnchor implements IAnchor {
954827
extDataHash.toString()
955828
);
956829

957-
let tx: ContractTransaction;
958-
if (extAmount.gt(0) && checkNativeAddress(tokenAddress)) {
959-
let tokenWrapper = TokenWrapper__factory.connect(await this.contract.token(), this.signer);
960-
let valueToSend = await tokenWrapper.getAmountToWrap(extAmount);
961-
962-
tx = await this.contract.transactWrap(
963-
{
964-
...publicInputs,
965-
outputCommitments: [publicInputs.outputCommitments[0], publicInputs.outputCommitments[1]],
966-
},
967-
extData,
968-
tokenAddress,
969-
{
970-
value: valueToSend.toHexString(),
971-
gasLimit: '0x5B8D80',
972-
}
973-
);
974-
} else {
975-
tx = await this.contract.transactWrap(
976-
{
977-
...publicInputs,
978-
outputCommitments: [publicInputs.outputCommitments[0], publicInputs.outputCommitments[1]],
979-
},
980-
extData,
981-
tokenAddress,
982-
{ gasLimit: '0x5B8D80' }
983-
);
984-
}
985-
// const receipt = await tx.wait();
830+
let tx = await this.contract.transact(
831+
publicInputs.proof,
832+
ZERO_BYTES32,
833+
{
834+
recipient: extData.recipient,
835+
extAmount: extData.extAmount,
836+
relayer: extData.relayer,
837+
fee: extData.fee,
838+
refund: extData.refund,
839+
token: extData.token,
840+
},
841+
{
842+
roots: publicInputs.vanchorRoots,
843+
extensionRoots: publicInputs.identityRoots,
844+
inputNullifiers: publicInputs.inputNullifiers,
845+
outputCommitments: [publicInputs.outputCommitments[0], publicInputs.outputCommitments[1]],
846+
publicAmount: publicInputs.publicAmount,
847+
extDataHash: publicInputs.extDataHash,
848+
},
849+
extData,
850+
{ gasLimit: '0x5B8D80' }
851+
);
852+
const receipt = await tx.wait();
986853

987854
// Add the leaves to the tree
988855
outputs.forEach((x) => {
989-
// Maintain tree state after insertions
990856
this.tree.insert(u8aToHex(x.commitment));
991857
let numOfElements = this.tree.number_of_elements();
992858
this.depositHistory[numOfElements - 1] = toFixedHex(this.tree.root().toString());
993859
});
994860

995861
return tx;
996-
// return receipt;
997862
}
998863
}
999864

0 commit comments

Comments
 (0)