From 3eeec9f851829f0e10312ddf941392a4a7a62a69 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 26 Jan 2022 15:29:11 -0500 Subject: [PATCH 01/15] Remove bridge and delete unused tests --- contracts/Bridge.sol | 371 ----- contracts/anchors/LinkableTree.sol | 6 +- packages/bridges/src/Bridge.ts | 405 ----- packages/bridges/src/BridgeSide.ts | 290 ---- packages/bridges/src/index.ts | 2 - packages/contracts/src/Bridge.d.ts | 1363 ----------------- .../src/factories/Bridge__factory.ts | 931 ----------- packages/contracts/src/index.ts | 3 - packages/vbridge/src/VBridge.ts | 58 +- packages/vbridge/src/VBridgeSide.ts | 187 --- packages/vbridge/src/index.ts | 9 +- scripts/bash/copyTypechain.sh | 2 - test/bridge/admin.test.ts | 94 -- test/bridge/bridgeSide.test.ts | 332 ---- test/bridge/cancelUpdateProposal.test.ts | 227 --- test/bridge/constructor.test.ts | 38 - test/bridge/createUpdateProposal.test.ts | 385 ----- test/bridge/executeUpdateProposal.test.ts | 294 ---- test/bridge/nativeBridge.test.ts | 106 -- test/bridge/voteUpdateProposal.test.ts | 318 ---- test/integration/bridge.test.ts | 557 ------- .../historicalRootWithdraw.test.ts | 388 ----- test/integration/simpleWithdrawals.test.ts | 391 ----- test/vbridge/signatureVBridge.test.ts | 6 +- test/vbridge/vbridge.test.ts | 516 ------- 25 files changed, 31 insertions(+), 7248 deletions(-) delete mode 100644 contracts/Bridge.sol delete mode 100644 packages/bridges/src/Bridge.ts delete mode 100644 packages/bridges/src/BridgeSide.ts delete mode 100644 packages/contracts/src/Bridge.d.ts delete mode 100644 packages/contracts/src/factories/Bridge__factory.ts delete mode 100644 packages/vbridge/src/VBridgeSide.ts delete mode 100644 test/bridge/admin.test.ts delete mode 100644 test/bridge/bridgeSide.test.ts delete mode 100644 test/bridge/cancelUpdateProposal.test.ts delete mode 100644 test/bridge/constructor.test.ts delete mode 100644 test/bridge/createUpdateProposal.test.ts delete mode 100644 test/bridge/executeUpdateProposal.test.ts delete mode 100644 test/bridge/nativeBridge.test.ts delete mode 100644 test/bridge/voteUpdateProposal.test.ts delete mode 100644 test/integration/bridge.test.ts delete mode 100644 test/integration/historicalRootWithdraw.test.ts delete mode 100644 test/integration/simpleWithdrawals.test.ts delete mode 100644 test/vbridge/vbridge.test.ts diff --git a/contracts/Bridge.sol b/contracts/Bridge.sol deleted file mode 100644 index 4a66ef81a..000000000 --- a/contracts/Bridge.sol +++ /dev/null @@ -1,371 +0,0 @@ -/** - * Copyright 2021 Webb Technologies - * SPDX-License-Identifier: GPL-3.0-or-later-only - */ - -pragma solidity ^0.8.0; -pragma experimental ABIEncoderV2; - -import "./utils/AccessControl.sol"; -import "./utils/Pausable.sol"; -import "./utils/SafeMath.sol"; -import "./utils/SafeCast.sol"; -import "./interfaces/IExecutor.sol"; - -/** - @title Facilitates deposits, creation and voting of deposit proposals, and deposit executions. - @author ChainSafe Systems & Webb Technologies. - */ -contract Bridge is Pausable, AccessControl, SafeMath { - using SafeCast for *; - - // Limit relayers number because proposal can fit only so much votes - uint256 constant public MAX_RELAYERS = 200; - - uint256 public _chainID; - uint8 public _relayerThreshold; - uint128 public _fee; - uint40 public _expiry; - - enum ProposalStatus {Inactive, Active, Passed, Executed, Cancelled} - - struct Proposal { - ProposalStatus _status; - uint200 _yesVotes; // bitmap, 200 maximum votes - uint8 _yesVotesTotal; - uint40 _proposedBlock; // 1099511627775 maximum block - } - - // destinationChainID => number of deposits - mapping(uint256 => uint64) public _counts; - // resourceID => handler address - mapping(bytes32 => address) public _resourceIDToHandlerAddress; - // destinationChainID + nonce => dataHash => Proposal - mapping(uint72 => mapping(bytes32 => Proposal)) private _proposals; - - event RelayerThresholdChanged(uint256 newThreshold); - event RelayerAdded(address relayer); - event RelayerRemoved(address relayer); - event Deposit( - uint256 destinationChainID, - bytes32 resourceID, - uint64 nonce - ); - event ProposalEvent( - uint256 originChainID, - uint64 nonce, - ProposalStatus status, - bytes32 dataHash - ); - event ProposalVote( - uint256 originChainID, - uint64 nonce, - ProposalStatus status, - bytes32 dataHash - ); - - bytes32 public constant RELAYER_ROLE = keccak256("RELAYER_ROLE"); - - modifier onlyAdmin() { - _onlyAdmin(); - _; - } - - modifier onlyAdminOrRelayer() { - _onlyAdminOrRelayer(); - _; - } - - modifier onlyRelayers() { - _onlyRelayers(); - _; - } - - function _onlyAdminOrRelayer() private view { - require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || hasRole(RELAYER_ROLE, msg.sender), - "sender is not relayer or admin"); - } - - function _onlyAdmin() private view { - require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "sender doesn't have admin role"); - } - - function _onlyRelayers() private view { - require(hasRole(RELAYER_ROLE, msg.sender), "sender doesn't have relayer role"); - } - - function _relayerBit(address relayer) private view returns(uint) { - return uint(1) << sub(AccessControl.getRoleMemberIndex(RELAYER_ROLE, relayer), 1); - } - - function _hasVoted(Proposal memory proposal, address relayer) private view returns(bool) { - return (_relayerBit(relayer) & uint(proposal._yesVotes)) > 0; - } - - /** - @notice Initializes Bridge, creates and grants {msg.sender} the admin role, - creates and grants {initialRelayers} the relayer role. - @param chainID ID of chain the Bridge contract exists on. - @param initialRelayers Addresses that should be initially granted the relayer role. - @param initialRelayerThreshold Number of votes needed for a update proposal to be considered passed. - */ - constructor (uint256 chainID, address[] memory initialRelayers, uint256 initialRelayerThreshold, uint256 fee, uint256 expiry) { - _chainID = chainID; - _relayerThreshold = initialRelayerThreshold.toUint8(); - _fee = fee.toUint128(); - _expiry = expiry.toUint40(); - - _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); - - for (uint256 i; i < initialRelayers.length; i++) { - grantRole(RELAYER_ROLE, initialRelayers[i]); - } - } - - /** - @notice Returns true if {relayer} has voted on {destNonce} {dataHash} proposal. - @notice Naming left unchanged for backward compatibility. - @param destNonce destinationChainID + nonce of the proposal. - @param dataHash Hash of data to be provided when update proposal is executed. - @param relayer Address to check. - */ - function _hasVotedOnProposal(uint72 destNonce, bytes32 dataHash, address relayer) public view returns(bool) { - return _hasVoted(_proposals[destNonce][dataHash], relayer); - } - - /** - @notice Returns true if {relayer} has the relayer role. - @param relayer Address to check. - */ - function isRelayer(address relayer) external view returns (bool) { - return hasRole(RELAYER_ROLE, relayer); - } - - /** - @notice Removes admin role from {msg.sender} and grants it to {newAdmin}. - @notice Only callable by an address that currently has the admin role. - @param newAdmin Address that admin role will be granted to. - */ - function renounceAdmin(address newAdmin) external onlyAdmin { - require(msg.sender != newAdmin, 'Cannot renounce oneself'); - grantRole(DEFAULT_ADMIN_ROLE, newAdmin); - renounceRole(DEFAULT_ADMIN_ROLE, msg.sender); - } - - /** - @notice Pauses deposits, proposal creation and voting, and deposit executions. - @notice Only callable by an address that currently has the admin role. - */ - function adminPauseTransfers() external onlyAdmin { - _pause(); - } - - /** - @notice Unpauses deposits, proposal creation and voting, and deposit executions. - @notice Only callable by an address that currently has the admin role. - */ - function adminUnpauseTransfers() external onlyAdmin { - _unpause(); - } - - /** - @notice Modifies the number of votes required for a proposal to be considered passed. - @notice Only callable by an address that currently has the admin role. - @param newThreshold Value {_relayerThreshold} will be changed to. - @notice Emits {RelayerThresholdChanged} event. - */ - function adminChangeRelayerThreshold(uint256 newThreshold) external onlyAdmin { - _relayerThreshold = newThreshold.toUint8(); - emit RelayerThresholdChanged(newThreshold); - } - - /** - @notice Grants {relayerAddress} the relayer role. - @notice Only callable by an address that currently has the admin role, which is - checked in grantRole(). - @param relayerAddress Address of relayer to be added. - @notice Emits {RelayerAdded} event. - */ - function adminAddRelayer(address relayerAddress) external { - require(!hasRole(RELAYER_ROLE, relayerAddress), "addr already has relayer role!"); - require(_totalRelayers() < MAX_RELAYERS, "relayers limit reached"); - grantRole(RELAYER_ROLE, relayerAddress); - emit RelayerAdded(relayerAddress); - } - - /** - @notice Removes relayer role for {relayerAddress}. - @notice Only callable by an address that currently has the admin role, which is - checked in revokeRole(). - @param relayerAddress Address of relayer to be removed. - @notice Emits {RelayerRemoved} event. - */ - function adminRemoveRelayer(address relayerAddress) external { - require(hasRole(RELAYER_ROLE, relayerAddress), "addr doesn't have relayer role!"); - revokeRole(RELAYER_ROLE, relayerAddress); - emit RelayerRemoved(relayerAddress); - } - - /** - @notice Sets a new resource for handler contracts that use the IExecutor interface, - and maps the {handlerAddress} to {resourceID} in {_resourceIDToHandlerAddress}. - @notice Only callable by an address that currently has the admin role. - @param handlerAddress Address of handler resource will be set for. - @param resourceID ResourceID to be used when making deposits. - @param executionContextAddress Address of contract to be called when a proposal is ready to execute on it - */ - function adminSetResource(address handlerAddress, bytes32 resourceID, address executionContextAddress) external onlyAdmin { - _resourceIDToHandlerAddress[resourceID] = handlerAddress; - IExecutor handler = IExecutor(handlerAddress); - handler.setResource(resourceID, executionContextAddress); - } - - /** - @notice Returns a proposal. - @param originChainID Chain ID deposit originated from. - @param nonce ID of proposal generated by proposal's origin Bridge contract. - @param dataHash Hash of data to be provided when deposit proposal is executed. - @return Proposal which consists of: - - _dataHash Hash of data to be provided when deposit proposal is executed. - - _yesVotes Number of votes in favor of proposal. - - _noVotes Number of votes against proposal. - - _status Current status of proposal. - */ - function getProposal(uint256 originChainID, uint64 nonce, bytes32 dataHash) external view returns (Proposal memory) { - uint72 nonceAndID = (uint72(nonce) << 8) | uint72(originChainID); - return _proposals[nonceAndID][dataHash]; - } - - /** - @notice Returns total relayers number. - @notice Added for backwards compatibility. - */ - function _totalRelayers() public view returns (uint) { - return AccessControl.getRoleMemberCount(RELAYER_ROLE); - } - /** - @notice Changes deposit fee. - @notice Only callable by admin. - @param newFee Value {_fee} will be updated to. - */ - function adminChangeFee(uint256 newFee) external onlyAdmin { - require(_fee != newFee, "Current fee is equal to new fee"); - _fee = newFee.toUint128(); - } - - /** - "Creates" the proposal upon first vote. - @notice When called, {msg.sender} will be marked as voting in favor of proposal. - @notice Only callable by relayers when Bridge is not paused. - @param chainID ID of chain deposit originated from. // TO BE REMOVED SINCE WE WANT PRIVACY - @param nonce ID of deposited generated by origin Bridge contract. - @param dataHash Hash of data provided when deposit was made. - @notice Proposal must not have already been passed or executed. - @notice {msg.sender} must not have already voted on proposal. - @notice Emits {ProposalEvent} event with status indicating the proposal status. - @notice Emits {ProposalVote} event. - */ - function voteProposal(uint256 chainID, uint64 nonce, bytes32 resourceID, bytes32 dataHash) external onlyRelayers whenNotPaused { - uint72 nonceAndID = (uint72(nonce) << 8) | uint72(chainID); - Proposal memory proposal = _proposals[nonceAndID][dataHash]; - - require(_resourceIDToHandlerAddress[resourceID] != address(0), "no handler for resourceID"); - require(uint(proposal._status) <= 1, "proposal already passed/executed/cancelled"); - require(!_hasVoted(proposal, msg.sender), "relayer already voted"); - - if (proposal._status == ProposalStatus.Inactive) { - proposal = Proposal({ - _status : ProposalStatus.Active, - _yesVotes : 0, - _yesVotesTotal : 0, - _proposedBlock : uint40(block.number) // Overflow is desired. - }); - - emit ProposalEvent(chainID, nonce, ProposalStatus.Active, dataHash); - } else if (uint40(sub(block.number, proposal._proposedBlock)) > _expiry) { - // if the number of blocks that has passed since this proposal was - // submitted exceeds the expiry threshold set, cancel the proposal - proposal._status = ProposalStatus.Cancelled; - - emit ProposalEvent(chainID, nonce, ProposalStatus.Cancelled, dataHash); - } - - if (proposal._status != ProposalStatus.Cancelled) { - proposal._yesVotes = (proposal._yesVotes | _relayerBit(msg.sender)).toUint200(); - proposal._yesVotesTotal++; // TODO: check if bit counting is cheaper. - - emit ProposalVote(chainID, nonce, proposal._status, dataHash); - - // Finalize if _relayerThreshold has been reached - if (proposal._yesVotesTotal >= _relayerThreshold) { - proposal._status = ProposalStatus.Passed; - - emit ProposalEvent(chainID, nonce, ProposalStatus.Passed, dataHash); - } - } - _proposals[nonceAndID][dataHash] = proposal; - } - - /** - @notice Cancels a deposit proposal that has not been executed yet. - @notice Only callable by relayers when Bridge is not paused. - @param chainID ID of chain deposit originated from. - @param nonce ID of deposited generated by origin Bridge contract. - @param dataHash Hash of data originally provided when deposit was made. - @notice Proposal must be past expiry threshold. - @notice Emits {ProposalEvent} event with status {Cancelled}. - */ - function cancelProposal(uint256 chainID, uint64 nonce, bytes32 dataHash) public onlyAdminOrRelayer { - uint72 nonceAndID = (uint72(nonce) << 8) | uint72(chainID); - Proposal memory proposal = _proposals[nonceAndID][dataHash]; - ProposalStatus currentStatus = proposal._status; - - require(currentStatus == ProposalStatus.Active || currentStatus == ProposalStatus.Passed, - "Proposal cannot be cancelled"); - require(uint40(sub(block.number, proposal._proposedBlock)) > _expiry, "Proposal not at expiry threshold"); - - proposal._status = ProposalStatus.Cancelled; - _proposals[nonceAndID][dataHash] = proposal; - - emit ProposalEvent(chainID, nonce, ProposalStatus.Cancelled, dataHash); - } - - /** - @notice Executes a deposit proposal that is considered passed using a specified handler contract. - @notice Only callable by relayers when Bridge is not paused. - @param chainID ID of chain deposit originated from. - @param resourceID ResourceID to be used when making deposits. - @param nonce ID of action generated by origin Bridge contract. - @param data Data originally provided when deposit was made. - @notice Proposal must have Passed status. - @notice Hash of {data} must equal proposal's {dataHash}. - @notice Emits {ProposalEvent} event with status {Executed}. - */ - function executeProposal(uint256 chainID, uint64 nonce, bytes calldata data, bytes32 resourceID) external onlyRelayers whenNotPaused { - address handler = _resourceIDToHandlerAddress[resourceID]; - uint72 nonceAndID = (uint72(nonce) << 8) | uint72(chainID); - bytes32 dataHash = keccak256(abi.encodePacked(handler, data)); - Proposal storage proposal = _proposals[nonceAndID][dataHash]; - - require(proposal._status == ProposalStatus.Passed, "Proposal must have Passed status"); - - proposal._status = ProposalStatus.Executed; - - IExecutor executionHandler = IExecutor(handler); - executionHandler.executeProposal(resourceID, data); - - emit ProposalEvent(chainID, nonce, ProposalStatus.Executed, dataHash); - } - - /** - @notice Transfers eth in the contract to the specified addresses. The parameters addrs and amounts are mapped 1-1. - This means that the address at index 0 for addrs will receive the amount (in WEI) from amounts at index 0. - @param addrs Array of addresses to transfer {amounts} to. - @param amounts Array of amonuts to transfer to {addrs}. - */ - function transferFunds(address payable[] calldata addrs, uint[] calldata amounts) external onlyAdmin { - for (uint256 i = 0; i < addrs.length; i++) { - addrs[i].transfer(amounts[i]); - } - } -} diff --git a/contracts/anchors/LinkableTree.sol b/contracts/anchors/LinkableTree.sol index d08a350cc..c6b5900fd 100644 --- a/contracts/anchors/LinkableTree.sol +++ b/contracts/anchors/LinkableTree.sol @@ -16,7 +16,7 @@ abstract contract LinkableTree is MerkleTreePoseidon, ReentrancyGuard { uint8 public immutable maxEdges; struct Edge { - uint256 chainID; + uint64 chainID; bytes32 root; uint256 latestLeafIndex; } @@ -32,8 +32,8 @@ abstract contract LinkableTree is MerkleTreePoseidon, ReentrancyGuard { mapping(uint256 => uint32) public currentNeighborRootIndex; // linking events - event EdgeAddition(uint256 chainID, uint256 latestLeafIndex, bytes32 merkleRoot); - event EdgeUpdate(uint256 chainID, uint256 latestLeafIndex, bytes32 merkleRoot); + event EdgeAddition(uint64 chainID, uint256 latestLeafIndex, bytes32 merkleRoot); + event EdgeUpdate(uint64 chainID, uint256 latestLeafIndex, bytes32 merkleRoot); /** @dev The constructor diff --git a/packages/bridges/src/Bridge.ts b/packages/bridges/src/Bridge.ts deleted file mode 100644 index d29a0af6f..000000000 --- a/packages/bridges/src/Bridge.ts +++ /dev/null @@ -1,405 +0,0 @@ -import { ethers } from 'ethers'; -import { ZkComponents } from "@webb-tools/utils"; -import { PoseidonT3__factory } from "@webb-tools/contracts"; -import { IAnchor, AnchorIdentifier, BridgeConfig, BridgeInput, DeployerConfig, IAnchorDeposit } from '@webb-tools/interfaces'; -import { Anchor, AnchorHandler } from '@webb-tools/anchors'; -import { MintableToken, GovernedTokenWrapper } from "@webb-tools/tokens"; -import { BridgeSide } from './BridgeSide'; -import { Verifier } from "./Verifier"; - -const zeroAddress = "0x0000000000000000000000000000000000000000"; - -function checkNativeAddress(tokenAddress: string): boolean { - if (tokenAddress === zeroAddress || tokenAddress === '0') { - return true; - } - return false; -} - -// A bridge is -export class Bridge { - private constructor( - // Mapping of chainId => bridgeSide - public bridgeSides: Map, - - // chainID => GovernedTokenWrapper (webbToken) address - public webbTokenAddresses: Map, - - // Mapping of resourceID => linkedAnchor[]; so we know which - // anchors need updating when the anchor for resourceID changes state. - public linkedAnchors: Map, - - // Mapping of anchorIdString => Anchor for easy anchor access - public anchors: Map, - ) {} - - public static createAnchorIdString(anchorIdentifier: AnchorIdentifier): string { - return `${anchorIdentifier.chainId.toString()}-${anchorIdentifier.anchorSize.toString()}`; - } - - public static createAnchorIdentifier(anchorString: string): AnchorIdentifier | null { - const identifyingInfo = anchorString.split('-'); - if (identifyingInfo.length != 2) { - return null; - } - return { - chainId: Number(identifyingInfo[0]), - anchorSize: identifyingInfo[1], - } - } - - // Takes as input a 2D array [[anchors to link together], [...]] - // And returns a map of resourceID => linkedAnchor[] - public static async createLinkedAnchorMap(createdAnchors: IAnchor[][]): Promise> { - let linkedAnchorMap = new Map(); - for (let groupedAnchors of createdAnchors) { - for (let i=0; i { - let webbTokenAddresses: Map = new Map(); - let bridgeSides: Map = new Map(); - let anchors: Map = new Map(); - // createdAnchors have the form of [[Anchors created on chainID], [...]] - // and anchors in the subArrays of thhe same index should be linked together - let createdAnchors: IAnchor[][] = []; - - for (let chainID of bridgeInput.chainIDs) { - const adminAddress = await deployers[chainID].getAddress(); - - // Create the bridgeSide - const bridgeInstance = await BridgeSide.createBridgeSide( - [adminAddress], - 1, - 0, - 100, - deployers[chainID], - ); - - const handler = await AnchorHandler.createAnchorHandler(bridgeInstance.contract.address, [],[], bridgeInstance.admin); - bridgeInstance.setAnchorHandler(handler); - - bridgeSides.set(chainID, bridgeInstance); - - // Create the Hasher and Verifier for the chain - const hasherFactory = new PoseidonT3__factory(deployers[chainID]); - let hasherInstance = await hasherFactory.deploy({ gasLimit: '0x5B8D80' }); - await hasherInstance.deployed(); - - const verifier = await Verifier.createVerifier(deployers[chainID]); - let verifierInstance = verifier.contract; - - // Check the addresses of the asset. If it is zero, deploy a native token wrapper - let allowedNative: boolean = false; - for (const tokenToBeWrapped of bridgeInput.anchorInputs.asset[chainID]!) { - // If passed '0' or zero address, token to be wrapped should support native. - if (checkNativeAddress(tokenToBeWrapped)) { - allowedNative = true; - } - } - - let tokenInstance: GovernedTokenWrapper = await GovernedTokenWrapper.createGovernedTokenWrapper( - `webbETH-test-1`, - `webbETH-test-1`, - await deployers[chainID].getAddress(), - '10000000000000000000000000', - allowedNative, - deployers[chainID], - ); - - //console.log(`created GovernedTokenWrapper on ${chainID}: ${tokenInstance.contract.address}`); - - // Add all token addresses to the governed token instance. - for (const tokenToBeWrapped of bridgeInput.anchorInputs.asset[chainID]!) { - // if the address is not '0', then add it - if (!checkNativeAddress(tokenToBeWrapped)) { - const tx = await tokenInstance.contract.add(tokenToBeWrapped, (await tokenInstance.contract.proposalNonce()).add(1)); - const receipt = await tx.wait(); - } - } - - // append each token - webbTokenAddresses.set( - chainID, - tokenInstance.contract.address - ); - - let chainGroupedAnchors: IAnchor[] = []; - - // loop through all the anchor sizes on the token - for (let anchorSize of bridgeInput.anchorInputs.anchorSizes) { - const anchorInstance = await Anchor.createAnchor( - verifierInstance.address, - hasherInstance.address, - anchorSize, - 30, - tokenInstance.contract.address, - // TODO: Use handler address - handler.contract.address, - bridgeInput.chainIDs.length-1, - zkComponents, - deployers[chainID] - ); - - //console.log(`createdAnchor: ${anchorInstance.contract.address}`); - - // grant minting rights to the anchor - await tokenInstance.grantMinterRole(anchorInstance.contract.address); - - chainGroupedAnchors.push(anchorInstance); - anchors.set( - Bridge.createAnchorIdString({anchorSize, chainId: chainID}), - anchorInstance - ); - } - - await Bridge.setPermissions(bridgeInstance, chainGroupedAnchors); - createdAnchors.push(chainGroupedAnchors); - } - - // All anchors created, massage data to group anchors which should be linked together - let groupLinkedAnchors: IAnchor[][] = []; - - // all subarrays will have the same number of elements - for(let i=0; i { - for (let anchor of anchors) { - await bridgeSide.connectAnchor(anchor); - } - } - - /** - * Updates the state of the BridgeSides and Anchors with - * the new state of the @param srcAnchor. - * @param srcAnchor The anchor that has updated. - * @returns - */ - public async updateLinkedAnchors(srcAnchor: IAnchor) { - // Find the bridge sides that are connected to this Anchor - const linkedResourceID = await srcAnchor.createResourceId(); - const anchorsToUpdate = this.linkedAnchors.get(linkedResourceID); - if (!anchorsToUpdate) { - return; - } - - // update the sides - for (let anchor of anchorsToUpdate) { - // get the bridge side which corresponds to this anchor - const chainId = await anchor.signer.getChainId(); - const resourceID = await anchor.createResourceId(); - const bridgeSide = this.bridgeSides.get(chainId); - await bridgeSide!.voteAnchorProposal(srcAnchor, resourceID); - await bridgeSide!.executeAnchorProposal(srcAnchor, resourceID); - } - }; - - public async update(chainId: number, anchorSize: ethers.BigNumberish) { - const anchor = this.getAnchor(chainId, anchorSize); - if (!anchor) { - return; - } - await this.updateLinkedAnchors(anchor); - } - - public getBridgeSide(chainId: number) { - return this.bridgeSides.get(chainId); - } - - public getAnchor(chainId: number, anchorSize: ethers.BigNumberish) { - let intendedAnchor: IAnchor | undefined = undefined; - intendedAnchor = this.anchors.get(Bridge.createAnchorIdString({anchorSize, chainId})); - return intendedAnchor; - } - - // Returns the address of the webbToken which wraps the given token name. - public getWebbTokenAddress(chainId: number): string | undefined { - return this.webbTokenAddresses.get(chainId); - } - - public exportConfig(): BridgeConfig { - return { - webbTokenAddresses: this.webbTokenAddresses, - anchors: this.anchors, - bridgeSides: this.bridgeSides - }; - } - - public async deposit(destinationChainId: number, anchorSize: ethers.BigNumberish, signer: ethers.Signer) { - const chainId = await signer.getChainId(); - const signerAddress = await signer.getAddress(); - const anchor = this.getAnchor(chainId, anchorSize); - if (!anchor) { - throw new Error("Anchor is not supported for the given token and size"); - } - - const tokenAddress = await anchor.contract.token(); - - if (!tokenAddress) { - throw new Error("Token not supported"); - } - - // Check if appropriate balance from user - const tokenInstance = await MintableToken.tokenFromAddress(tokenAddress, signer); - const userTokenBalance = await tokenInstance.getBalance(signerAddress); - - if (userTokenBalance.lt(anchorSize)) { - throw new Error("Not enough balance in webbTokens"); - } - - // Approve spending if needed - const userTokenAllowance = await tokenInstance.getAllowance(signerAddress, anchor.contract.address); - if (userTokenAllowance.lt(anchorSize)) { - await tokenInstance.approveSpending(anchor.contract.address); - } - - // return some error code value for deposit note if signer invalid - if (!(await anchor.setSigner(signer))) { - throw new Error("Invalid signer for deposit, check the signer's chainID"); - } - const deposit = await anchor.deposit(destinationChainId); - await this.updateLinkedAnchors(anchor); - return deposit; - } - - public async wrapAndDeposit(destinationChainId: number, tokenAddress: string, anchorSize: ethers.BigNumberish, signer: ethers.Signer) { - const chainId = await signer.getChainId(); - const signerAddress = await signer.getAddress(); - const anchor = this.getAnchor(chainId, anchorSize); - if (!anchor) { - throw new Error("Anchor is not supported for the given token and size"); - } - - // Different wrapAndDeposit flows for native vs erc20 tokens - if (checkNativeAddress(tokenAddress)) { - // Check if appropriate balance from user - const nativeBalance = await signer.getBalance(); - if (nativeBalance < anchorSize) { - throw new Error("Not enough native token balance") - } - - if (!(await anchor.setSigner(signer))) { - throw new Error("Invalid signer for deposit, check the signer's chainID"); - } - const deposit = await anchor.wrapAndDeposit(zeroAddress, destinationChainId); - await this.updateLinkedAnchors(anchor); - return deposit; - } - else { - // Check if appropriate balance from user - const originTokenInstance = await MintableToken.tokenFromAddress(tokenAddress, signer); - const userOriginTokenBalance = await originTokenInstance.getBalance(signerAddress); - if (userOriginTokenBalance.lt(anchorSize)) { - throw new Error("Not enough ERC20 balance"); - } - - // Continue with deposit flow for wrapAndDeposit: - // Approve spending if needed - let userOriginTokenAllowance = await originTokenInstance.getAllowance(signerAddress, anchor.contract.address); - if (userOriginTokenAllowance.lt(anchorSize)) { - const wrapperTokenAddress = await anchor.contract.token(); - const tx = await originTokenInstance.approveSpending(wrapperTokenAddress); - await tx.wait(); - } - - // return some error code value for deposit note if signer invalid - if (!(await anchor.setSigner(signer))) { - throw new Error("Invalid signer for deposit, check the signer's chainID"); - } - - const deposit = await anchor.wrapAndDeposit(originTokenInstance.contract.address, destinationChainId); - await this.updateLinkedAnchors(anchor); - return deposit; - } - } - - public async withdraw( - depositInfo: IAnchorDeposit, - anchorSize: ethers.BigNumberish, - recipient: string, - relayer: string, - signer: ethers.Signer - ) { - // Construct the proof from the origin anchor - const anchorToProve = this.getAnchor(depositInfo.originChainId, anchorSize); - if (!anchorToProve) { - throw new Error("Could not find anchor to prove against"); - } - - const merkleProof = anchorToProve.tree.path(depositInfo.index); - - // Submit the proof and arguments on the destination anchor - const anchorToWithdraw = this.getAnchor(Number(depositInfo.deposit.chainID.toString()), anchorSize); - - if (!anchorToWithdraw) { - throw new Error("Could not find anchor to withdraw from"); - } - - if (!(await anchorToWithdraw.setSigner(signer))) { - throw new Error("Could not set signer"); - } - - await anchorToWithdraw.bridgedWithdraw(depositInfo, merkleProof, recipient, relayer, '0', '0', '0'); - return true; - } - - public async withdrawAndUnwrap( - depositInfo: IAnchorDeposit, - tokenAddress: string, - anchorSize: ethers.BigNumberish, - recipient: string, - relayer: string, - signer: ethers.Signer - ) { - // Construct the proof from the origin anchor - const anchorToProve = this.getAnchor(depositInfo.originChainId, anchorSize); - if (!anchorToProve) { - throw new Error("Could not find anchor to prove against"); - } - - const merkleProof = anchorToProve.tree.path(depositInfo.index); - - // Submit the proof and arguments on the destination anchor - const anchorToWithdraw = this.getAnchor(Number(depositInfo.deposit.chainID.toString()), anchorSize); - - if (!anchorToWithdraw) { - throw new Error("Could not find anchor to withdraw from"); - } - - if (!(await anchorToWithdraw.setSigner(signer))) { - throw new Error("Could not set signer"); - } - - await anchorToWithdraw.bridgedWithdrawAndUnwrap(depositInfo, merkleProof, recipient, relayer, '0', '0', '0', tokenAddress); - return true; - } -} diff --git a/packages/bridges/src/BridgeSide.ts b/packages/bridges/src/BridgeSide.ts deleted file mode 100644 index 3cd4d3be9..000000000 --- a/packages/bridges/src/BridgeSide.ts +++ /dev/null @@ -1,290 +0,0 @@ -import { ethers } from 'ethers'; -import { Bridge, Bridge__factory } from '@webb-tools/contracts'; -import { GovernedTokenWrapper, TokenWrapperHandler } from "@webb-tools/tokens"; -import { AnchorHandler } from "@webb-tools/anchors"; -import { IAnchor, IBridgeSide, Proposal } from "@webb-tools/interfaces"; - -export class BridgeSide implements IBridgeSide { - contract: Bridge; - admin: ethers.Signer; - handler: AnchorHandler | TokenWrapperHandler | null; - proposals: Proposal[]; - - private constructor( - contract: Bridge, - signer: ethers.Signer, - ) { - this.contract = contract; - this.admin = signer; - this.handler = null; - this.proposals = []; - } - - public static async createBridgeSide( - initialRelayers: string[], - initialRelayerThreshold: ethers.BigNumberish, - fee: ethers.BigNumberish, - expiry: ethers.BigNumberish, - admin: ethers.Signer - ): Promise { - const bridgeFactory = new Bridge__factory(admin); - const chainId = await admin.getChainId(); - const deployedBridge = await bridgeFactory.deploy(chainId, initialRelayers, initialRelayerThreshold, fee, expiry); - await deployedBridge.deployed(); - const bridgeSide = new BridgeSide(deployedBridge, admin); - return bridgeSide; - } - - public static async connect(address: string, admin: ethers.Signer) { - const deployedBridge = Bridge__factory.connect(address, admin); - const bridgeSide = new BridgeSide(deployedBridge, admin); - return bridgeSide; - } - - /** - * Creates the proposal data for updating an execution anchor - * with the latest state of a source anchor (i.e. most recent deposit). - * @param srcAnchor The anchor instance whose state has updated. - * @param executionResourceId The resource id of the execution anchor instance. - * @returns Promise - */ - public async createAnchorUpdateProposalData(srcAnchor: IAnchor, executionResourceID: string): Promise { - const proposalData = await srcAnchor.getProposalData(executionResourceID); - return proposalData; - } - - public async createHandlerUpdateProposalData(anchor: IAnchor, newHandler: string) { - const proposalData = await anchor.getHandlerProposalData(newHandler); - return proposalData; - } - - /** - * Creates the proposal data for updating the wrapping fee - * of a governed token wrapper. - * @param governedToken The governed token wrapper whose fee will be updated. - * @param fee The new fee percentage - * @returns Promise - */ - public async createFeeUpdateProposalData(governedToken: GovernedTokenWrapper, fee: number): Promise { - // TODO: Validate fee is between [0, 100] - const proposalData = await governedToken.getFeeProposalData(fee); - return proposalData; - } - - public async createAddTokenUpdateProposalData(governedToken: GovernedTokenWrapper, tokenAddress: string) { - const proposalData = await governedToken.getAddTokenProposalData(tokenAddress); - return proposalData; - } - - public async createRemoveTokenUpdateProposalData(governedToken: GovernedTokenWrapper, tokenAddress: string) { - const proposalData = await governedToken.getRemoveTokenProposalData(tokenAddress); - return proposalData; - } - - public setAnchorHandler(handler: AnchorHandler) { - this.handler = handler; - } - - public setTokenWrapperHandler(handler: TokenWrapperHandler) { - this.handler = handler; - } - - // Connects the bridgeSide, anchor handler, and anchor. - // Returns the resourceID used to connect them all - public async connectAnchor(anchor: IAnchor): Promise { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const resourceId = await anchor.createResourceId(); - const tx = await this.contract.adminSetResource(this.handler.contract.address, resourceId, anchor.contract.address); - await tx.wait(); - // await this.handler.setResource(resourceId, anchor.contract.address); covered in above call - await this.voteHandlerProposal(anchor, this.handler.contract.address); - await this.executeHandlerProposal(anchor, this.handler.contract.address); - - return resourceId; - } - - public async setGovernedTokenResource(governedToken: GovernedTokenWrapper): Promise { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - const resourceId = await governedToken.createResourceId(); - - await this.contract.adminSetResource(this.handler.contract.address, resourceId, governedToken.contract.address); - return resourceId; - } - - /** - * Votes on an anchor proposal by creating the proposal data and submitting it to the bridge. - * @param srcAnchor The anchor instance whose state has updated. - * @param executionResourceID The resource id of the execution anchor instance. - * @returns - */ - public async voteAnchorProposal(srcAnchor: IAnchor, executionResourceID: string) { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const proposalData = await this.createAnchorUpdateProposalData(srcAnchor, executionResourceID); - const dataHash = ethers.utils.keccak256(this.handler.contract.address + proposalData.substr(2)); - - const chainId = await srcAnchor.signer.getChainId(); - const nonce = srcAnchor.tree.number_of_elements() - 1; - - const tx = await this.contract.voteProposal(chainId, nonce, executionResourceID, dataHash); - const receipt = await tx.wait(); - - return receipt; - } - - /** - * Executes a proposal by calling the bridge's executeProposal function - * with the anchor update proposal data. - * @param srcAnchor The anchor instance whose state has updated. - * @param executionResourceID The resource id of the execution anchor instance. - * @returns - */ - public async executeAnchorProposal(srcAnchor: IAnchor, executionResourceID: string) { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const proposalData = await this.createAnchorUpdateProposalData(srcAnchor, executionResourceID); - const chainId = await srcAnchor.signer.getChainId(); - const nonce = srcAnchor.tree.number_of_elements() - 1; - - const tx = await this.contract.executeProposal(chainId, nonce, proposalData, executionResourceID); - const receipt = await tx.wait(); - - return receipt; - } - - public async voteHandlerProposal(anchor: IAnchor, newHandler: string) { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const proposalData = await this.createHandlerUpdateProposalData(anchor, newHandler); - const dataHash = ethers.utils.keccak256(this.handler.contract.address + proposalData.substr(2)); - - const chainId = await anchor.signer.getChainId(); - const nonce = 1; - const resourceID = await anchor.createResourceId(); - const tx = await this.contract.voteProposal(chainId, nonce, resourceID, dataHash); - const receipt = await tx.wait(); - - return receipt; - } - - public async executeHandlerProposal(anchor: IAnchor, newHandler: string) { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const proposalData = await this.createHandlerUpdateProposalData(anchor, newHandler); - const chainId = await anchor.signer.getChainId(); - const nonce = 1; - const resourceID = await anchor.createResourceId() - const tx = await this.contract.executeProposal(chainId, nonce, proposalData, resourceID); - const receipt = await tx.wait(); - - return receipt; - } - - public async voteFeeProposal(governedToken: GovernedTokenWrapper, fee: number) { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const proposalData = await this.createFeeUpdateProposalData(governedToken, fee); - const dataHash = ethers.utils.keccak256(this.handler.contract.address + proposalData.substr(2)); - const resourceId = await governedToken.createResourceId(); - const chainId = await governedToken.signer.getChainId(); - const nonce = (await governedToken.contract.proposalNonce()).add(1); - - const tx = await this.contract.voteProposal(chainId, nonce, resourceId, dataHash); - const receipt = await tx.wait(); - - return receipt; - } - - public async executeFeeProposal(governedToken: GovernedTokenWrapper, fee: number) { - if (!this.handler) { - throw new Error("Cannot connect to token wrapper without a handler"); - } - const proposalData = await this.createFeeUpdateProposalData(governedToken, fee); - const resourceId = await governedToken.createResourceId(); - const chainId = await governedToken.signer.getChainId(); - const nonce = (await governedToken.contract.proposalNonce()).add(1); - const tx = await this.contract.executeProposal(chainId, nonce, proposalData, resourceId); - const receipt = await tx.wait(); - - return receipt; - } - - public async voteAddTokenProposal(governedToken: GovernedTokenWrapper, tokenAddress: string) { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const proposalData = await this.createAddTokenUpdateProposalData(governedToken, tokenAddress); - const dataHash = ethers.utils.keccak256(this.handler.contract.address + proposalData.substr(2)); - const resourceId = await governedToken.createResourceId(); - const chainId = await governedToken.signer.getChainId(); - const nonce = (await governedToken.contract.proposalNonce()).add(1); - - const tx = await this.contract.voteProposal(chainId, nonce, resourceId, dataHash); - const receipt = await tx.wait(); - - return receipt; - } - - public async executeAddTokenProposal(governedToken: GovernedTokenWrapper, tokenAddress: string) { - if (!this.handler) { - throw new Error("Cannot connect to token wrapper without a handler"); - } - - const proposalData = await this.createAddTokenUpdateProposalData(governedToken, tokenAddress); - const resourceId = await governedToken.createResourceId(); - const chainId = await governedToken.signer.getChainId(); - const nonce = (await governedToken.contract.proposalNonce()).add(1); - const tx = await this.contract.executeProposal(chainId, nonce, proposalData, resourceId); - const receipt = await tx.wait(); - - return receipt; - } - - public async voteRemoveTokenProposal(governedToken: GovernedTokenWrapper, tokenAddress: string) { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const proposalData = await this.createRemoveTokenUpdateProposalData(governedToken, tokenAddress); - const dataHash = ethers.utils.keccak256(this.handler.contract.address + proposalData.substr(2)); - const resourceId = await governedToken.createResourceId(); - const chainId = await governedToken.signer.getChainId(); - const nonce = (await governedToken.contract.proposalNonce()).add(1); - - const tx = await this.contract.voteProposal(chainId, nonce, resourceId, dataHash); - const receipt = await tx.wait(); - - return receipt; - } - - public async executeRemoveTokenProposal(governedToken: GovernedTokenWrapper, tokenAddress: string) { - if (!this.handler) { - throw new Error("Cannot connect to token wrapper without a handler"); - } - - const proposalData = await this.createRemoveTokenUpdateProposalData(governedToken, tokenAddress); - const resourceId = await governedToken.createResourceId(); - const chainId = await governedToken.signer.getChainId(); - const nonce = (await governedToken.contract.proposalNonce()).add(1); - const tx = await this.contract.executeProposal(chainId, nonce, proposalData, resourceId); - const receipt = await tx.wait(); - - return receipt; - } -} diff --git a/packages/bridges/src/index.ts b/packages/bridges/src/index.ts index 2b3d3dba0..d1cc8e525 100644 --- a/packages/bridges/src/index.ts +++ b/packages/bridges/src/index.ts @@ -1,5 +1,3 @@ -export { Bridge } from './Bridge'; export { SignatureBridge, SignatureBridgeConfig } from './SignatureBridge'; -export { BridgeSide } from './BridgeSide'; export { SignatureBridgeSide } from './SignatureBridgeSide'; export { Verifier } from './Verifier'; diff --git a/packages/contracts/src/Bridge.d.ts b/packages/contracts/src/Bridge.d.ts deleted file mode 100644 index 755eafc7a..000000000 --- a/packages/contracts/src/Bridge.d.ts +++ /dev/null @@ -1,1363 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ - -import { - ethers, - EventFilter, - Signer, - BigNumber, - BigNumberish, - PopulatedTransaction, - BaseContract, - ContractTransaction, - Overrides, - CallOverrides, -} from "ethers"; -import { BytesLike } from "@ethersproject/bytes"; -import { Listener, Provider } from "@ethersproject/providers"; -import { FunctionFragment, EventFragment, Result } from "@ethersproject/abi"; -import type { TypedEventFilter, TypedEvent, TypedListener } from "./common"; - -interface BridgeInterface extends ethers.utils.Interface { - functions: { - "DEFAULT_ADMIN_ROLE()": FunctionFragment; - "MAX_RELAYERS()": FunctionFragment; - "RELAYER_ROLE()": FunctionFragment; - "_chainID()": FunctionFragment; - "_counts(uint256)": FunctionFragment; - "_expiry()": FunctionFragment; - "_fee()": FunctionFragment; - "_hasVotedOnProposal(uint72,bytes32,address)": FunctionFragment; - "_relayerThreshold()": FunctionFragment; - "_resourceIDToHandlerAddress(bytes32)": FunctionFragment; - "_totalRelayers()": FunctionFragment; - "adminAddRelayer(address)": FunctionFragment; - "adminChangeFee(uint256)": FunctionFragment; - "adminChangeRelayerThreshold(uint256)": FunctionFragment; - "adminPauseTransfers()": FunctionFragment; - "adminRemoveRelayer(address)": FunctionFragment; - "adminSetResource(address,bytes32,address)": FunctionFragment; - "adminUnpauseTransfers()": FunctionFragment; - "cancelProposal(uint256,uint64,bytes32)": FunctionFragment; - "executeProposal(uint256,uint64,bytes,bytes32)": FunctionFragment; - "getProposal(uint256,uint64,bytes32)": FunctionFragment; - "getRoleAdmin(bytes32)": FunctionFragment; - "getRoleMember(bytes32,uint256)": FunctionFragment; - "getRoleMemberCount(bytes32)": FunctionFragment; - "getRoleMemberIndex(bytes32,address)": FunctionFragment; - "grantRole(bytes32,address)": FunctionFragment; - "hasRole(bytes32,address)": FunctionFragment; - "isRelayer(address)": FunctionFragment; - "paused()": FunctionFragment; - "renounceAdmin(address)": FunctionFragment; - "renounceRole(bytes32,address)": FunctionFragment; - "revokeRole(bytes32,address)": FunctionFragment; - "transferFunds(address[],uint256[])": FunctionFragment; - "voteProposal(uint256,uint64,bytes32,bytes32)": FunctionFragment; - }; - - encodeFunctionData( - functionFragment: "DEFAULT_ADMIN_ROLE", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "MAX_RELAYERS", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "RELAYER_ROLE", - values?: undefined - ): string; - encodeFunctionData(functionFragment: "_chainID", values?: undefined): string; - encodeFunctionData( - functionFragment: "_counts", - values: [BigNumberish] - ): string; - encodeFunctionData(functionFragment: "_expiry", values?: undefined): string; - encodeFunctionData(functionFragment: "_fee", values?: undefined): string; - encodeFunctionData( - functionFragment: "_hasVotedOnProposal", - values: [BigNumberish, BytesLike, string] - ): string; - encodeFunctionData( - functionFragment: "_relayerThreshold", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "_resourceIDToHandlerAddress", - values: [BytesLike] - ): string; - encodeFunctionData( - functionFragment: "_totalRelayers", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "adminAddRelayer", - values: [string] - ): string; - encodeFunctionData( - functionFragment: "adminChangeFee", - values: [BigNumberish] - ): string; - encodeFunctionData( - functionFragment: "adminChangeRelayerThreshold", - values: [BigNumberish] - ): string; - encodeFunctionData( - functionFragment: "adminPauseTransfers", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "adminRemoveRelayer", - values: [string] - ): string; - encodeFunctionData( - functionFragment: "adminSetResource", - values: [string, BytesLike, string] - ): string; - encodeFunctionData( - functionFragment: "adminUnpauseTransfers", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "cancelProposal", - values: [BigNumberish, BigNumberish, BytesLike] - ): string; - encodeFunctionData( - functionFragment: "executeProposal", - values: [BigNumberish, BigNumberish, BytesLike, BytesLike] - ): string; - encodeFunctionData( - functionFragment: "getProposal", - values: [BigNumberish, BigNumberish, BytesLike] - ): string; - encodeFunctionData( - functionFragment: "getRoleAdmin", - values: [BytesLike] - ): string; - encodeFunctionData( - functionFragment: "getRoleMember", - values: [BytesLike, BigNumberish] - ): string; - encodeFunctionData( - functionFragment: "getRoleMemberCount", - values: [BytesLike] - ): string; - encodeFunctionData( - functionFragment: "getRoleMemberIndex", - values: [BytesLike, string] - ): string; - encodeFunctionData( - functionFragment: "grantRole", - values: [BytesLike, string] - ): string; - encodeFunctionData( - functionFragment: "hasRole", - values: [BytesLike, string] - ): string; - encodeFunctionData(functionFragment: "isRelayer", values: [string]): string; - encodeFunctionData(functionFragment: "paused", values?: undefined): string; - encodeFunctionData( - functionFragment: "renounceAdmin", - values: [string] - ): string; - encodeFunctionData( - functionFragment: "renounceRole", - values: [BytesLike, string] - ): string; - encodeFunctionData( - functionFragment: "revokeRole", - values: [BytesLike, string] - ): string; - encodeFunctionData( - functionFragment: "transferFunds", - values: [string[], BigNumberish[]] - ): string; - encodeFunctionData( - functionFragment: "voteProposal", - values: [BigNumberish, BigNumberish, BytesLike, BytesLike] - ): string; - - decodeFunctionResult( - functionFragment: "DEFAULT_ADMIN_ROLE", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "MAX_RELAYERS", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "RELAYER_ROLE", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "_chainID", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "_counts", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "_expiry", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "_fee", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "_hasVotedOnProposal", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "_relayerThreshold", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "_resourceIDToHandlerAddress", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "_totalRelayers", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "adminAddRelayer", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "adminChangeFee", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "adminChangeRelayerThreshold", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "adminPauseTransfers", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "adminRemoveRelayer", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "adminSetResource", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "adminUnpauseTransfers", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "cancelProposal", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "executeProposal", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getProposal", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getRoleAdmin", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getRoleMember", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getRoleMemberCount", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getRoleMemberIndex", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "grantRole", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "hasRole", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "isRelayer", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "paused", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "renounceAdmin", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "renounceRole", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "revokeRole", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "transferFunds", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "voteProposal", - data: BytesLike - ): Result; - - events: { - "Deposit(uint256,bytes32,uint64)": EventFragment; - "Paused(address)": EventFragment; - "ProposalEvent(uint256,uint64,uint8,bytes32)": EventFragment; - "ProposalVote(uint256,uint64,uint8,bytes32)": EventFragment; - "RelayerAdded(address)": EventFragment; - "RelayerRemoved(address)": EventFragment; - "RelayerThresholdChanged(uint256)": EventFragment; - "RoleGranted(bytes32,address,address)": EventFragment; - "RoleRevoked(bytes32,address,address)": EventFragment; - "Unpaused(address)": EventFragment; - }; - - getEvent(nameOrSignatureOrTopic: "Deposit"): EventFragment; - getEvent(nameOrSignatureOrTopic: "Paused"): EventFragment; - getEvent(nameOrSignatureOrTopic: "ProposalEvent"): EventFragment; - getEvent(nameOrSignatureOrTopic: "ProposalVote"): EventFragment; - getEvent(nameOrSignatureOrTopic: "RelayerAdded"): EventFragment; - getEvent(nameOrSignatureOrTopic: "RelayerRemoved"): EventFragment; - getEvent(nameOrSignatureOrTopic: "RelayerThresholdChanged"): EventFragment; - getEvent(nameOrSignatureOrTopic: "RoleGranted"): EventFragment; - getEvent(nameOrSignatureOrTopic: "RoleRevoked"): EventFragment; - getEvent(nameOrSignatureOrTopic: "Unpaused"): EventFragment; -} - -export type DepositEvent = TypedEvent< - [BigNumber, string, BigNumber] & { - destinationChainID: BigNumber; - resourceID: string; - nonce: BigNumber; - } ->; - -export type PausedEvent = TypedEvent<[string] & { account: string }>; - -export type ProposalEventEvent = TypedEvent< - [BigNumber, BigNumber, number, string] & { - originChainID: BigNumber; - nonce: BigNumber; - status: number; - dataHash: string; - } ->; - -export type ProposalVoteEvent = TypedEvent< - [BigNumber, BigNumber, number, string] & { - originChainID: BigNumber; - nonce: BigNumber; - status: number; - dataHash: string; - } ->; - -export type RelayerAddedEvent = TypedEvent<[string] & { relayer: string }>; - -export type RelayerRemovedEvent = TypedEvent<[string] & { relayer: string }>; - -export type RelayerThresholdChangedEvent = TypedEvent< - [BigNumber] & { newThreshold: BigNumber } ->; - -export type RoleGrantedEvent = TypedEvent< - [string, string, string] & { role: string; account: string; sender: string } ->; - -export type RoleRevokedEvent = TypedEvent< - [string, string, string] & { role: string; account: string; sender: string } ->; - -export type UnpausedEvent = TypedEvent<[string] & { account: string }>; - -export class Bridge extends BaseContract { - connect(signerOrProvider: Signer | Provider | string): this; - attach(addressOrName: string): this; - deployed(): Promise; - - listeners, EventArgsObject>( - eventFilter?: TypedEventFilter - ): Array>; - off, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - on, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - once, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - removeListener, EventArgsObject>( - eventFilter: TypedEventFilter, - listener: TypedListener - ): this; - removeAllListeners, EventArgsObject>( - eventFilter: TypedEventFilter - ): this; - - listeners(eventName?: string): Array; - off(eventName: string, listener: Listener): this; - on(eventName: string, listener: Listener): this; - once(eventName: string, listener: Listener): this; - removeListener(eventName: string, listener: Listener): this; - removeAllListeners(eventName?: string): this; - - queryFilter, EventArgsObject>( - event: TypedEventFilter, - fromBlockOrBlockhash?: string | number | undefined, - toBlock?: string | number | undefined - ): Promise>>; - - interface: BridgeInterface; - - functions: { - DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise<[string]>; - - MAX_RELAYERS(overrides?: CallOverrides): Promise<[BigNumber]>; - - RELAYER_ROLE(overrides?: CallOverrides): Promise<[string]>; - - _chainID(overrides?: CallOverrides): Promise<[BigNumber]>; - - _counts( - arg0: BigNumberish, - overrides?: CallOverrides - ): Promise<[BigNumber]>; - - _expiry(overrides?: CallOverrides): Promise<[number]>; - - _fee(overrides?: CallOverrides): Promise<[BigNumber]>; - - _hasVotedOnProposal( - destNonce: BigNumberish, - dataHash: BytesLike, - relayer: string, - overrides?: CallOverrides - ): Promise<[boolean]>; - - _relayerThreshold(overrides?: CallOverrides): Promise<[number]>; - - _resourceIDToHandlerAddress( - arg0: BytesLike, - overrides?: CallOverrides - ): Promise<[string]>; - - _totalRelayers(overrides?: CallOverrides): Promise<[BigNumber]>; - - adminAddRelayer( - relayerAddress: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminChangeFee( - newFee: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminChangeRelayerThreshold( - newThreshold: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminPauseTransfers( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminRemoveRelayer( - relayerAddress: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminSetResource( - handlerAddress: string, - resourceID: BytesLike, - executionContextAddress: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminUnpauseTransfers( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - cancelProposal( - chainID: BigNumberish, - nonce: BigNumberish, - dataHash: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - executeProposal( - chainID: BigNumberish, - nonce: BigNumberish, - data: BytesLike, - resourceID: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - getProposal( - originChainID: BigNumberish, - nonce: BigNumberish, - dataHash: BytesLike, - overrides?: CallOverrides - ): Promise< - [ - [number, BigNumber, number, number] & { - _status: number; - _yesVotes: BigNumber; - _yesVotesTotal: number; - _proposedBlock: number; - } - ] - >; - - getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise<[string]>; - - getRoleMember( - role: BytesLike, - index: BigNumberish, - overrides?: CallOverrides - ): Promise<[string]>; - - getRoleMemberCount( - role: BytesLike, - overrides?: CallOverrides - ): Promise<[BigNumber]>; - - getRoleMemberIndex( - role: BytesLike, - account: string, - overrides?: CallOverrides - ): Promise<[BigNumber]>; - - grantRole( - role: BytesLike, - account: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - hasRole( - role: BytesLike, - account: string, - overrides?: CallOverrides - ): Promise<[boolean]>; - - isRelayer(relayer: string, overrides?: CallOverrides): Promise<[boolean]>; - - paused(overrides?: CallOverrides): Promise<[boolean]>; - - renounceAdmin( - newAdmin: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - renounceRole( - role: BytesLike, - account: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - revokeRole( - role: BytesLike, - account: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - transferFunds( - addrs: string[], - amounts: BigNumberish[], - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - voteProposal( - chainID: BigNumberish, - nonce: BigNumberish, - resourceID: BytesLike, - dataHash: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - }; - - DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise; - - MAX_RELAYERS(overrides?: CallOverrides): Promise; - - RELAYER_ROLE(overrides?: CallOverrides): Promise; - - _chainID(overrides?: CallOverrides): Promise; - - _counts(arg0: BigNumberish, overrides?: CallOverrides): Promise; - - _expiry(overrides?: CallOverrides): Promise; - - _fee(overrides?: CallOverrides): Promise; - - _hasVotedOnProposal( - destNonce: BigNumberish, - dataHash: BytesLike, - relayer: string, - overrides?: CallOverrides - ): Promise; - - _relayerThreshold(overrides?: CallOverrides): Promise; - - _resourceIDToHandlerAddress( - arg0: BytesLike, - overrides?: CallOverrides - ): Promise; - - _totalRelayers(overrides?: CallOverrides): Promise; - - adminAddRelayer( - relayerAddress: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminChangeFee( - newFee: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminChangeRelayerThreshold( - newThreshold: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminPauseTransfers( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminRemoveRelayer( - relayerAddress: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminSetResource( - handlerAddress: string, - resourceID: BytesLike, - executionContextAddress: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminUnpauseTransfers( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - cancelProposal( - chainID: BigNumberish, - nonce: BigNumberish, - dataHash: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - executeProposal( - chainID: BigNumberish, - nonce: BigNumberish, - data: BytesLike, - resourceID: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - getProposal( - originChainID: BigNumberish, - nonce: BigNumberish, - dataHash: BytesLike, - overrides?: CallOverrides - ): Promise< - [number, BigNumber, number, number] & { - _status: number; - _yesVotes: BigNumber; - _yesVotesTotal: number; - _proposedBlock: number; - } - >; - - getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise; - - getRoleMember( - role: BytesLike, - index: BigNumberish, - overrides?: CallOverrides - ): Promise; - - getRoleMemberCount( - role: BytesLike, - overrides?: CallOverrides - ): Promise; - - getRoleMemberIndex( - role: BytesLike, - account: string, - overrides?: CallOverrides - ): Promise; - - grantRole( - role: BytesLike, - account: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - hasRole( - role: BytesLike, - account: string, - overrides?: CallOverrides - ): Promise; - - isRelayer(relayer: string, overrides?: CallOverrides): Promise; - - paused(overrides?: CallOverrides): Promise; - - renounceAdmin( - newAdmin: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - renounceRole( - role: BytesLike, - account: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - revokeRole( - role: BytesLike, - account: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - transferFunds( - addrs: string[], - amounts: BigNumberish[], - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - voteProposal( - chainID: BigNumberish, - nonce: BigNumberish, - resourceID: BytesLike, - dataHash: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - callStatic: { - DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise; - - MAX_RELAYERS(overrides?: CallOverrides): Promise; - - RELAYER_ROLE(overrides?: CallOverrides): Promise; - - _chainID(overrides?: CallOverrides): Promise; - - _counts(arg0: BigNumberish, overrides?: CallOverrides): Promise; - - _expiry(overrides?: CallOverrides): Promise; - - _fee(overrides?: CallOverrides): Promise; - - _hasVotedOnProposal( - destNonce: BigNumberish, - dataHash: BytesLike, - relayer: string, - overrides?: CallOverrides - ): Promise; - - _relayerThreshold(overrides?: CallOverrides): Promise; - - _resourceIDToHandlerAddress( - arg0: BytesLike, - overrides?: CallOverrides - ): Promise; - - _totalRelayers(overrides?: CallOverrides): Promise; - - adminAddRelayer( - relayerAddress: string, - overrides?: CallOverrides - ): Promise; - - adminChangeFee( - newFee: BigNumberish, - overrides?: CallOverrides - ): Promise; - - adminChangeRelayerThreshold( - newThreshold: BigNumberish, - overrides?: CallOverrides - ): Promise; - - adminPauseTransfers(overrides?: CallOverrides): Promise; - - adminRemoveRelayer( - relayerAddress: string, - overrides?: CallOverrides - ): Promise; - - adminSetResource( - handlerAddress: string, - resourceID: BytesLike, - executionContextAddress: string, - overrides?: CallOverrides - ): Promise; - - adminUnpauseTransfers(overrides?: CallOverrides): Promise; - - cancelProposal( - chainID: BigNumberish, - nonce: BigNumberish, - dataHash: BytesLike, - overrides?: CallOverrides - ): Promise; - - executeProposal( - chainID: BigNumberish, - nonce: BigNumberish, - data: BytesLike, - resourceID: BytesLike, - overrides?: CallOverrides - ): Promise; - - getProposal( - originChainID: BigNumberish, - nonce: BigNumberish, - dataHash: BytesLike, - overrides?: CallOverrides - ): Promise< - [number, BigNumber, number, number] & { - _status: number; - _yesVotes: BigNumber; - _yesVotesTotal: number; - _proposedBlock: number; - } - >; - - getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise; - - getRoleMember( - role: BytesLike, - index: BigNumberish, - overrides?: CallOverrides - ): Promise; - - getRoleMemberCount( - role: BytesLike, - overrides?: CallOverrides - ): Promise; - - getRoleMemberIndex( - role: BytesLike, - account: string, - overrides?: CallOverrides - ): Promise; - - grantRole( - role: BytesLike, - account: string, - overrides?: CallOverrides - ): Promise; - - hasRole( - role: BytesLike, - account: string, - overrides?: CallOverrides - ): Promise; - - isRelayer(relayer: string, overrides?: CallOverrides): Promise; - - paused(overrides?: CallOverrides): Promise; - - renounceAdmin(newAdmin: string, overrides?: CallOverrides): Promise; - - renounceRole( - role: BytesLike, - account: string, - overrides?: CallOverrides - ): Promise; - - revokeRole( - role: BytesLike, - account: string, - overrides?: CallOverrides - ): Promise; - - transferFunds( - addrs: string[], - amounts: BigNumberish[], - overrides?: CallOverrides - ): Promise; - - voteProposal( - chainID: BigNumberish, - nonce: BigNumberish, - resourceID: BytesLike, - dataHash: BytesLike, - overrides?: CallOverrides - ): Promise; - }; - - filters: { - "Deposit(uint256,bytes32,uint64)"( - destinationChainID?: null, - resourceID?: null, - nonce?: null - ): TypedEventFilter< - [BigNumber, string, BigNumber], - { destinationChainID: BigNumber; resourceID: string; nonce: BigNumber } - >; - - Deposit( - destinationChainID?: null, - resourceID?: null, - nonce?: null - ): TypedEventFilter< - [BigNumber, string, BigNumber], - { destinationChainID: BigNumber; resourceID: string; nonce: BigNumber } - >; - - "Paused(address)"( - account?: null - ): TypedEventFilter<[string], { account: string }>; - - Paused(account?: null): TypedEventFilter<[string], { account: string }>; - - "ProposalEvent(uint256,uint64,uint8,bytes32)"( - originChainID?: null, - nonce?: null, - status?: null, - dataHash?: null - ): TypedEventFilter< - [BigNumber, BigNumber, number, string], - { - originChainID: BigNumber; - nonce: BigNumber; - status: number; - dataHash: string; - } - >; - - ProposalEvent( - originChainID?: null, - nonce?: null, - status?: null, - dataHash?: null - ): TypedEventFilter< - [BigNumber, BigNumber, number, string], - { - originChainID: BigNumber; - nonce: BigNumber; - status: number; - dataHash: string; - } - >; - - "ProposalVote(uint256,uint64,uint8,bytes32)"( - originChainID?: null, - nonce?: null, - status?: null, - dataHash?: null - ): TypedEventFilter< - [BigNumber, BigNumber, number, string], - { - originChainID: BigNumber; - nonce: BigNumber; - status: number; - dataHash: string; - } - >; - - ProposalVote( - originChainID?: null, - nonce?: null, - status?: null, - dataHash?: null - ): TypedEventFilter< - [BigNumber, BigNumber, number, string], - { - originChainID: BigNumber; - nonce: BigNumber; - status: number; - dataHash: string; - } - >; - - "RelayerAdded(address)"( - relayer?: null - ): TypedEventFilter<[string], { relayer: string }>; - - RelayerAdded( - relayer?: null - ): TypedEventFilter<[string], { relayer: string }>; - - "RelayerRemoved(address)"( - relayer?: null - ): TypedEventFilter<[string], { relayer: string }>; - - RelayerRemoved( - relayer?: null - ): TypedEventFilter<[string], { relayer: string }>; - - "RelayerThresholdChanged(uint256)"( - newThreshold?: null - ): TypedEventFilter<[BigNumber], { newThreshold: BigNumber }>; - - RelayerThresholdChanged( - newThreshold?: null - ): TypedEventFilter<[BigNumber], { newThreshold: BigNumber }>; - - "RoleGranted(bytes32,address,address)"( - role?: BytesLike | null, - account?: string | null, - sender?: string | null - ): TypedEventFilter< - [string, string, string], - { role: string; account: string; sender: string } - >; - - RoleGranted( - role?: BytesLike | null, - account?: string | null, - sender?: string | null - ): TypedEventFilter< - [string, string, string], - { role: string; account: string; sender: string } - >; - - "RoleRevoked(bytes32,address,address)"( - role?: BytesLike | null, - account?: string | null, - sender?: string | null - ): TypedEventFilter< - [string, string, string], - { role: string; account: string; sender: string } - >; - - RoleRevoked( - role?: BytesLike | null, - account?: string | null, - sender?: string | null - ): TypedEventFilter< - [string, string, string], - { role: string; account: string; sender: string } - >; - - "Unpaused(address)"( - account?: null - ): TypedEventFilter<[string], { account: string }>; - - Unpaused(account?: null): TypedEventFilter<[string], { account: string }>; - }; - - estimateGas: { - DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise; - - MAX_RELAYERS(overrides?: CallOverrides): Promise; - - RELAYER_ROLE(overrides?: CallOverrides): Promise; - - _chainID(overrides?: CallOverrides): Promise; - - _counts(arg0: BigNumberish, overrides?: CallOverrides): Promise; - - _expiry(overrides?: CallOverrides): Promise; - - _fee(overrides?: CallOverrides): Promise; - - _hasVotedOnProposal( - destNonce: BigNumberish, - dataHash: BytesLike, - relayer: string, - overrides?: CallOverrides - ): Promise; - - _relayerThreshold(overrides?: CallOverrides): Promise; - - _resourceIDToHandlerAddress( - arg0: BytesLike, - overrides?: CallOverrides - ): Promise; - - _totalRelayers(overrides?: CallOverrides): Promise; - - adminAddRelayer( - relayerAddress: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminChangeFee( - newFee: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminChangeRelayerThreshold( - newThreshold: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminPauseTransfers( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminRemoveRelayer( - relayerAddress: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminSetResource( - handlerAddress: string, - resourceID: BytesLike, - executionContextAddress: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminUnpauseTransfers( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - cancelProposal( - chainID: BigNumberish, - nonce: BigNumberish, - dataHash: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - executeProposal( - chainID: BigNumberish, - nonce: BigNumberish, - data: BytesLike, - resourceID: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - getProposal( - originChainID: BigNumberish, - nonce: BigNumberish, - dataHash: BytesLike, - overrides?: CallOverrides - ): Promise; - - getRoleAdmin( - role: BytesLike, - overrides?: CallOverrides - ): Promise; - - getRoleMember( - role: BytesLike, - index: BigNumberish, - overrides?: CallOverrides - ): Promise; - - getRoleMemberCount( - role: BytesLike, - overrides?: CallOverrides - ): Promise; - - getRoleMemberIndex( - role: BytesLike, - account: string, - overrides?: CallOverrides - ): Promise; - - grantRole( - role: BytesLike, - account: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - hasRole( - role: BytesLike, - account: string, - overrides?: CallOverrides - ): Promise; - - isRelayer(relayer: string, overrides?: CallOverrides): Promise; - - paused(overrides?: CallOverrides): Promise; - - renounceAdmin( - newAdmin: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - renounceRole( - role: BytesLike, - account: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - revokeRole( - role: BytesLike, - account: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - transferFunds( - addrs: string[], - amounts: BigNumberish[], - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - voteProposal( - chainID: BigNumberish, - nonce: BigNumberish, - resourceID: BytesLike, - dataHash: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - }; - - populateTransaction: { - DEFAULT_ADMIN_ROLE( - overrides?: CallOverrides - ): Promise; - - MAX_RELAYERS(overrides?: CallOverrides): Promise; - - RELAYER_ROLE(overrides?: CallOverrides): Promise; - - _chainID(overrides?: CallOverrides): Promise; - - _counts( - arg0: BigNumberish, - overrides?: CallOverrides - ): Promise; - - _expiry(overrides?: CallOverrides): Promise; - - _fee(overrides?: CallOverrides): Promise; - - _hasVotedOnProposal( - destNonce: BigNumberish, - dataHash: BytesLike, - relayer: string, - overrides?: CallOverrides - ): Promise; - - _relayerThreshold(overrides?: CallOverrides): Promise; - - _resourceIDToHandlerAddress( - arg0: BytesLike, - overrides?: CallOverrides - ): Promise; - - _totalRelayers(overrides?: CallOverrides): Promise; - - adminAddRelayer( - relayerAddress: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminChangeFee( - newFee: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminChangeRelayerThreshold( - newThreshold: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminPauseTransfers( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminRemoveRelayer( - relayerAddress: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminSetResource( - handlerAddress: string, - resourceID: BytesLike, - executionContextAddress: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - adminUnpauseTransfers( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - cancelProposal( - chainID: BigNumberish, - nonce: BigNumberish, - dataHash: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - executeProposal( - chainID: BigNumberish, - nonce: BigNumberish, - data: BytesLike, - resourceID: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - getProposal( - originChainID: BigNumberish, - nonce: BigNumberish, - dataHash: BytesLike, - overrides?: CallOverrides - ): Promise; - - getRoleAdmin( - role: BytesLike, - overrides?: CallOverrides - ): Promise; - - getRoleMember( - role: BytesLike, - index: BigNumberish, - overrides?: CallOverrides - ): Promise; - - getRoleMemberCount( - role: BytesLike, - overrides?: CallOverrides - ): Promise; - - getRoleMemberIndex( - role: BytesLike, - account: string, - overrides?: CallOverrides - ): Promise; - - grantRole( - role: BytesLike, - account: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - hasRole( - role: BytesLike, - account: string, - overrides?: CallOverrides - ): Promise; - - isRelayer( - relayer: string, - overrides?: CallOverrides - ): Promise; - - paused(overrides?: CallOverrides): Promise; - - renounceAdmin( - newAdmin: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - renounceRole( - role: BytesLike, - account: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - revokeRole( - role: BytesLike, - account: string, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - transferFunds( - addrs: string[], - amounts: BigNumberish[], - overrides?: Overrides & { from?: string | Promise } - ): Promise; - - voteProposal( - chainID: BigNumberish, - nonce: BigNumberish, - resourceID: BytesLike, - dataHash: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - }; -} diff --git a/packages/contracts/src/factories/Bridge__factory.ts b/packages/contracts/src/factories/Bridge__factory.ts deleted file mode 100644 index 6dc5c634e..000000000 --- a/packages/contracts/src/factories/Bridge__factory.ts +++ /dev/null @@ -1,931 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ - -import { - Signer, - utils, - BigNumberish, - Contract, - ContractFactory, - Overrides, -} from "ethers"; -import { Provider, TransactionRequest } from "@ethersproject/providers"; -import type { Bridge, BridgeInterface } from "../Bridge"; - -const _abi = [ - { - inputs: [ - { - internalType: "uint256", - name: "chainID", - type: "uint256", - }, - { - internalType: "address[]", - name: "initialRelayers", - type: "address[]", - }, - { - internalType: "uint256", - name: "initialRelayerThreshold", - type: "uint256", - }, - { - internalType: "uint256", - name: "fee", - type: "uint256", - }, - { - internalType: "uint256", - name: "expiry", - type: "uint256", - }, - ], - stateMutability: "nonpayable", - type: "constructor", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint256", - name: "destinationChainID", - type: "uint256", - }, - { - indexed: false, - internalType: "bytes32", - name: "resourceID", - type: "bytes32", - }, - { - indexed: false, - internalType: "uint64", - name: "nonce", - type: "uint64", - }, - ], - name: "Deposit", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "address", - name: "account", - type: "address", - }, - ], - name: "Paused", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint256", - name: "originChainID", - type: "uint256", - }, - { - indexed: false, - internalType: "uint64", - name: "nonce", - type: "uint64", - }, - { - indexed: false, - internalType: "enum Bridge.ProposalStatus", - name: "status", - type: "uint8", - }, - { - indexed: false, - internalType: "bytes32", - name: "dataHash", - type: "bytes32", - }, - ], - name: "ProposalEvent", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint256", - name: "originChainID", - type: "uint256", - }, - { - indexed: false, - internalType: "uint64", - name: "nonce", - type: "uint64", - }, - { - indexed: false, - internalType: "enum Bridge.ProposalStatus", - name: "status", - type: "uint8", - }, - { - indexed: false, - internalType: "bytes32", - name: "dataHash", - type: "bytes32", - }, - ], - name: "ProposalVote", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "address", - name: "relayer", - type: "address", - }, - ], - name: "RelayerAdded", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "address", - name: "relayer", - type: "address", - }, - ], - name: "RelayerRemoved", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint256", - name: "newThreshold", - type: "uint256", - }, - ], - name: "RelayerThresholdChanged", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "bytes32", - name: "role", - type: "bytes32", - }, - { - indexed: true, - internalType: "address", - name: "account", - type: "address", - }, - { - indexed: true, - internalType: "address", - name: "sender", - type: "address", - }, - ], - name: "RoleGranted", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "bytes32", - name: "role", - type: "bytes32", - }, - { - indexed: true, - internalType: "address", - name: "account", - type: "address", - }, - { - indexed: true, - internalType: "address", - name: "sender", - type: "address", - }, - ], - name: "RoleRevoked", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "address", - name: "account", - type: "address", - }, - ], - name: "Unpaused", - type: "event", - }, - { - inputs: [], - name: "DEFAULT_ADMIN_ROLE", - outputs: [ - { - internalType: "bytes32", - name: "", - type: "bytes32", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "MAX_RELAYERS", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "RELAYER_ROLE", - outputs: [ - { - internalType: "bytes32", - name: "", - type: "bytes32", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "_chainID", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - name: "_counts", - outputs: [ - { - internalType: "uint64", - name: "", - type: "uint64", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "_expiry", - outputs: [ - { - internalType: "uint40", - name: "", - type: "uint40", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "_fee", - outputs: [ - { - internalType: "uint128", - name: "", - type: "uint128", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "uint72", - name: "destNonce", - type: "uint72", - }, - { - internalType: "bytes32", - name: "dataHash", - type: "bytes32", - }, - { - internalType: "address", - name: "relayer", - type: "address", - }, - ], - name: "_hasVotedOnProposal", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "_relayerThreshold", - outputs: [ - { - internalType: "uint8", - name: "", - type: "uint8", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "", - type: "bytes32", - }, - ], - name: "_resourceIDToHandlerAddress", - outputs: [ - { - internalType: "address", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "_totalRelayers", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "relayerAddress", - type: "address", - }, - ], - name: "adminAddRelayer", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "newFee", - type: "uint256", - }, - ], - name: "adminChangeFee", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "newThreshold", - type: "uint256", - }, - ], - name: "adminChangeRelayerThreshold", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [], - name: "adminPauseTransfers", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "relayerAddress", - type: "address", - }, - ], - name: "adminRemoveRelayer", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "handlerAddress", - type: "address", - }, - { - internalType: "bytes32", - name: "resourceID", - type: "bytes32", - }, - { - internalType: "address", - name: "executionContextAddress", - type: "address", - }, - ], - name: "adminSetResource", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [], - name: "adminUnpauseTransfers", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "chainID", - type: "uint256", - }, - { - internalType: "uint64", - name: "nonce", - type: "uint64", - }, - { - internalType: "bytes32", - name: "dataHash", - type: "bytes32", - }, - ], - name: "cancelProposal", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "chainID", - type: "uint256", - }, - { - internalType: "uint64", - name: "nonce", - type: "uint64", - }, - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - { - internalType: "bytes32", - name: "resourceID", - type: "bytes32", - }, - ], - name: "executeProposal", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "originChainID", - type: "uint256", - }, - { - internalType: "uint64", - name: "nonce", - type: "uint64", - }, - { - internalType: "bytes32", - name: "dataHash", - type: "bytes32", - }, - ], - name: "getProposal", - outputs: [ - { - components: [ - { - internalType: "enum Bridge.ProposalStatus", - name: "_status", - type: "uint8", - }, - { - internalType: "uint200", - name: "_yesVotes", - type: "uint200", - }, - { - internalType: "uint8", - name: "_yesVotesTotal", - type: "uint8", - }, - { - internalType: "uint40", - name: "_proposedBlock", - type: "uint40", - }, - ], - internalType: "struct Bridge.Proposal", - name: "", - type: "tuple", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "role", - type: "bytes32", - }, - ], - name: "getRoleAdmin", - outputs: [ - { - internalType: "bytes32", - name: "", - type: "bytes32", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "role", - type: "bytes32", - }, - { - internalType: "uint256", - name: "index", - type: "uint256", - }, - ], - name: "getRoleMember", - outputs: [ - { - internalType: "address", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "role", - type: "bytes32", - }, - ], - name: "getRoleMemberCount", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "role", - type: "bytes32", - }, - { - internalType: "address", - name: "account", - type: "address", - }, - ], - name: "getRoleMemberIndex", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "role", - type: "bytes32", - }, - { - internalType: "address", - name: "account", - type: "address", - }, - ], - name: "grantRole", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "role", - type: "bytes32", - }, - { - internalType: "address", - name: "account", - type: "address", - }, - ], - name: "hasRole", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "relayer", - type: "address", - }, - ], - name: "isRelayer", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "paused", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "newAdmin", - type: "address", - }, - ], - name: "renounceAdmin", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "role", - type: "bytes32", - }, - { - internalType: "address", - name: "account", - type: "address", - }, - ], - name: "renounceRole", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "role", - type: "bytes32", - }, - { - internalType: "address", - name: "account", - type: "address", - }, - ], - name: "revokeRole", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address payable[]", - name: "addrs", - type: "address[]", - }, - { - internalType: "uint256[]", - name: "amounts", - type: "uint256[]", - }, - ], - name: "transferFunds", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "chainID", - type: "uint256", - }, - { - internalType: "uint64", - name: "nonce", - type: "uint64", - }, - { - internalType: "bytes32", - name: "resourceID", - type: "bytes32", - }, - { - internalType: "bytes32", - name: "dataHash", - type: "bytes32", - }, - ], - name: "voteProposal", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, -]; - -const _bytecode = - "0x60806040523480156200001157600080fd5b50604051620027f8380380620027f8833981016040819052620000349162000458565b6000805460ff1916905560028590556200005a8362000176602090811b620015f517901c565b600360006101000a81548160ff021916908360ff1602179055506200008a82620001d360201b6200164c1760201c565b600360016101000a8154816001600160801b0302191690836001600160801b03160217905550620000c6816200022a60201b620016a11760201c565b6003805464ffffffffff92909216600160881b0264ffffffffff60881b19909216919091179055620000fa60003362000283565b60005b84518110156200016a57620001557fe2b7fb3b832174769106daebcfd6d1970523240dda11281102db9363b83b0dc486838151811062000141576200014162000582565b60200260200101516200029360201b60201c565b80620001618162000558565b915050620000fd565b505050505050620005ae565b60006101008210620001cf5760405162461bcd60e51b815260206004820152601c60248201527f76616c756520646f6573206e6f742066697420696e203820626974730000000060448201526064015b60405180910390fd5b5090565b6000600160801b8210620001cf5760405162461bcd60e51b815260206004820152601e60248201527f76616c756520646f6573206e6f742066697420696e20313238206269747300006044820152606401620001c6565b6000650100000000008210620001cf5760405162461bcd60e51b815260206004820152601d60248201527f76616c756520646f6573206e6f742066697420696e20343020626974730000006044820152606401620001c6565b6200028f828262000317565b5050565b600082815260016020526040902060020154620002b1903362000380565b620002835760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60448201526e0818591b5a5b881d1bc819dc985b9d608a1b6064820152608401620001c6565b60008281526001602090815260409091206200033e918390620016f8620003af821b17901c565b156200028f5760405133906001600160a01b0383169084907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d90600090a45050565b60008281526001602090815260408220620003a69184906200170d620003c6821b17901c565b90505b92915050565b6000620003a6836001600160a01b038416620003e9565b6001600160a01b03811660009081526001830160205260408120541515620003a6565b60008181526001830160205260408120546200043257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003a9565b506000620003a9565b80516001600160a01b03811681146200045357600080fd5b919050565b600080600080600060a086880312156200047157600080fd5b8551602080880151919650906001600160401b03808211156200049357600080fd5b818901915089601f830112620004a857600080fd5b815181811115620004bd57620004bd62000598565b8060051b604051601f19603f83011681018181108582111715620004e557620004e562000598565b604052828152858101935084860182860187018e10156200050557600080fd5b600095505b8386101562000533576200051e816200043b565b8552600195909501949386019386016200050a565b5060408c015160608d01516080909d01519b9e919d509b9a9950975050505050505050565b60006000198214156200057b57634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b61223a80620005be6000396000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c8063926d7d7f1161011a578063c5ec8970116100ad578063d547741f1161007c578063d547741f1461049e578063d75a0683146104b1578063d7a9cd79146104f4578063dfef9a5314610513578063ffaac0eb1461052657600080fd5b8063c5ec897014610437578063ca15c87314610465578063cb10f21514610478578063cdb0f73a1461048b57600080fd5b8063a06fa09b116100e9578063a06fa09b146103e3578063a217fddf146103f6578063beab7131146103fe578063c5b37c221461040757600080fd5b8063926d7d7f146103935780639b303d7a146103a85780639d82dd63146103c85780639debb3bd146103db57600080fd5b80635e1fab0f1161019d57806380ae1c281161016c57806380ae1c281461031157806384db809f146103195780639010d07c1461035a57806391c404ac1461036d57806391d148541461038057600080fd5b80635e1fab0f146102d0578063709940e6146102e35780637febe63f146102f6578063802aabe81461030957600080fd5b80634e056005116101d95780634e0560051461027c5780634e0df3f61461028f578063541d5548146102a25780635c975abb146102c557600080fd5b8063248a9ca31461020b5780632f2ff15d1461024157806336568abe146102565780634603ae3814610269575b600080fd5b61022e610219366004611e1a565b60009081526001602052604090206002015490565b6040519081526020015b60405180910390f35b61025461024f366004611e33565b61052e565b005b610254610264366004611e33565b6105c1565b610254610277366004611dae565b61063b565b61025461028a366004611e1a565b6106df565b61022e61029d366004611e33565b61073b565b6102b56102b0366004611d4f565b610767565b6040519015158152602001610238565b60005460ff166102b5565b6102546102de366004611d4f565b610781565b6102546102f1366004611e85565b6107fb565b6102b5610304366004611f84565b610a90565b61022e610b34565b610254610b52565b610342610327366004611e1a565b6005602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610238565b610342610368366004611e63565b610b64565b61025461037b366004611e1a565b610b83565b6102b561038e366004611e33565b610c1d565b61022e6000805160206121c583398151915281565b6103bb6103b6366004611e85565b610c35565b6040516102389190612089565b6102546103d6366004611d4f565b610d03565b61022e60c881565b6102546103f1366004611eba565b610db8565b61022e600081565b61022e60025481565b60035461041f9061010090046001600160801b031681565b6040516001600160801b039091168152602001610238565b60035461044f90600160881b900464ffffffffff1681565b60405164ffffffffff9091168152602001610238565b61022e610473366004611e1a565b611219565b610254610486366004611d6c565b611230565b610254610499366004611d4f565b6112c4565b6102546104ac366004611e33565b6113ca565b6104db6104bf366004611e1a565b60046020526000908152604090205467ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610238565b6003546105019060ff1681565b60405160ff9091168152602001610238565b610254610521366004611ef5565b61144b565b6102546115e5565b60008281526001602052604090206002015461054a9033610c1d565b6105b35760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60448201526e0818591b5a5b881d1bc819dc985b9d608a1b60648201526084015b60405180910390fd5b6105bd828261172f565b5050565b6001600160a01b03811633146106315760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016105aa565b6105bd8282611788565b6106436117e1565b60005b838110156106d85784848281811061066057610660612199565b90506020020160208101906106759190611d4f565b6001600160a01b03166108fc84848481811061069357610693612199565b905060200201359081150290604051600060405180830381858888f193505050501580156106c5573d6000803e3d6000fd5b50806106d08161211c565b915050610646565b5050505050565b6106e76117e1565b6106f0816115f5565b6003805460ff191660ff929092169190911790556040518181527fa20d6b84cd798a24038be305eff8a45ca82ef54a2aa2082005d8e14c0a4746c8906020015b60405180910390a150565b60008281526001602081815260408084206001600160a01b038616855290920190529020545b92915050565b60006107616000805160206121c583398151915283610c1d565b6107896117e1565b336001600160a01b03821614156107e25760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f742072656e6f756e6365206f6e6573656c6600000000000000000060448201526064016105aa565b6107ed60008261052e565b6107f86000336105c1565b50565b610803611838565b600882901b68ffffffffffffffff00166001600160481b03841681176000908152600660209081526040808320858452909152808220815160808101909252805493871793829060ff16600481111561085e5761085e61216d565b600481111561086f5761086f61216d565b8152905461010081046001600160c81b03166020830152600160d01b810460ff166040830152600160d81b900464ffffffffff16606090910152805190915060018160048111156108c2576108c261216d565b14806108df575060028160048111156108dd576108dd61216d565b145b61092b5760405162461bcd60e51b815260206004820152601c60248201527f50726f706f73616c2063616e6e6f742062652063616e63656c6c65640000000060448201526064016105aa565b600354606083015164ffffffffff600160881b909204821691610950914391166118ad565b64ffffffffff16116109a45760405162461bcd60e51b815260206004820181905260248201527f50726f706f73616c206e6f7420617420657870697279207468726573686f6c6460448201526064016105aa565b60048083526001600160481b03841660009081526006602090815260408083208884529091529020835181548593839160ff19169060019084908111156109ed576109ed61216d565b02179055506020820151815460408085015160609095015164ffffffffff16600160d81b026001600160d81b0360ff909616600160d01b0260ff60d01b196001600160c81b039095166101000294909416610100600160d81b0319909316929092179290921793909316929092179055516000805160206121e583398151915290610a80908890889060049089906120d2565b60405180910390a1505050505050565b6001600160481b03831660009081526006602090815260408083208584529091528082208151608081019092528054610b2c929190829060ff166004811115610adb57610adb61216d565b6004811115610aec57610aec61216d565b8152905461010081046001600160c81b03166020830152600160d01b810460ff166040830152600160d81b900464ffffffffff16606090910152836118ef565b949350505050565b6000610b4d6000805160206121c5833981519152611219565b905090565b610b5a6117e1565b610b62611912565b565b6000828152600160205260408120610b7c908361195d565b9392505050565b610b8b6117e1565b60035461010090046001600160801b0316811415610beb5760405162461bcd60e51b815260206004820152601f60248201527f43757272656e742066656520697320657175616c20746f206e6577206665650060448201526064016105aa565b610bf48161164c565b600360016101000a8154816001600160801b0302191690836001600160801b0316021790555050565b6000828152600160205260408120610b7c908361170d565b60408051608080820183526000808352602080840182905283850182905260608401829052600887901b68ffffffffffffffff00166001600160481b03891681178352600682528583208784529091529084902084519283019094528354929390871792829060ff166004811115610caf57610caf61216d565b6004811115610cc057610cc061216d565b8152905461010081046001600160c81b03166020830152600160d01b810460ff166040830152600160d81b900464ffffffffff1660609091015295945050505050565b610d1b6000805160206121c583398151915282610c1d565b610d675760405162461bcd60e51b815260206004820152601f60248201527f6164647220646f65736e277420686176652072656c6179657220726f6c65210060448201526064016105aa565b610d7f6000805160206121c5833981519152826113ca565b6040516001600160a01b03821681527f10e1f7ce9fd7d1b90a66d13a2ab3cb8dd7f29f3f8d520b143b063ccfbab6906b90602001610730565b610dc0611969565b610dc86119cd565b600883901b68ffffffffffffffff00166001600160481b03851681176000908152600660209081526040808320858452909152808220815160808101909252805493881793829060ff166004811115610e2357610e2361216d565b6004811115610e3457610e3461216d565b8152905461010081046001600160c81b0316602080840191909152600160d01b820460ff16604080850191909152600160d81b90920464ffffffffff16606090930192909252600087815260059092529020549091506001600160a01b0316610edf5760405162461bcd60e51b815260206004820152601960248201527f6e6f2068616e646c657220666f72207265736f7572636549440000000000000060448201526064016105aa565b80516001906004811115610ef557610ef561216d565b1115610f565760405162461bcd60e51b815260206004820152602a60248201527f70726f706f73616c20616c7265616479207061737365642f65786563757465646044820152690bd8d85b98d95b1b195960b21b60648201526084016105aa565b610f6081336118ef565b15610fa55760405162461bcd60e51b81526020600482015260156024820152741c995b185e595c88185b1c9958591e481d9bdd1959605a1b60448201526064016105aa565b600081516004811115610fba57610fba61216d565b141561101b57506040805160808101825260018082526000602083018190528284015264ffffffffff43166060830152915190916000805160206121e58339815191529161100e91899189919088906120d2565b60405180910390a161107d565b600354606082015164ffffffffff600160881b909204821691611040914391166118ad565b64ffffffffff16111561107d5760048082526040516000805160206121e583398151915291611074918991899188906120d2565b60405180910390a15b6004815160048111156110925761109261216d565b1461115d576110b76110a333611a13565b82602001516001600160c81b031617611a41565b6001600160c81b03166020820152604081018051906110d582612137565b60ff1690525080516040517f9bce7387b7d9942d29cffae8898ffe045a4b66dc7b0a6fa81606e41772ed12a991611111918991899188906120d2565b60405180910390a1600354604082015160ff91821691161061115d5760028082526040516000805160206121e583398151915291611154918991899188906120d2565b60405180910390a15b6001600160481b038216600090815260066020908152604080832086845290915290208151815483929190829060ff191660018360048111156111a2576111a261216d565b021790555060208201518154604084015160609094015164ffffffffff16600160d81b026001600160d81b0360ff909516600160d01b0260ff60d01b196001600160c81b039094166101000293909316610100600160d81b0319909216919091179190911792909216919091179055505050505050565b600081815260016020526040812061076190611a96565b6112386117e1565b6000828152600560205260409081902080546001600160a01b0319166001600160a01b038681169182179092559151635c7d1b9b60e11b815260048101859052908316602482015284919063b8fa373690604401600060405180830381600087803b1580156112a657600080fd5b505af11580156112ba573d6000803e3d6000fd5b5050505050505050565b6112dc6000805160206121c583398151915282610c1d565b156113295760405162461bcd60e51b815260206004820152601e60248201527f6164647220616c7265616479206861732072656c6179657220726f6c6521000060448201526064016105aa565b60c8611333610b34565b106113795760405162461bcd60e51b81526020600482015260166024820152751c995b185e595c9cc81b1a5b5a5d081c995858da195960521b60448201526064016105aa565b6113916000805160206121c58339815191528261052e565b6040516001600160a01b03821681527f03580ee9f53a62b7cb409a2cb56f9be87747dd15017afc5cef6eef321e4fb2c590602001610730565b6000828152600160205260409020600201546113e69033610c1d565b6106315760405162461bcd60e51b815260206004820152603060248201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60448201526f2061646d696e20746f207265766f6b6560801b60648201526084016105aa565b611453611969565b61145b6119cd565b60008181526005602090815260408083205490516001600160a01b039091169268ffffffffffffffff00600889901b1689179290916114a09185918991899101611fd2565b60408051601f1981840301815291815281516020928301206001600160481b03851660009081526006845282812082825290935291209091506002815460ff1660048111156114f1576114f161216d565b1461153e5760405162461bcd60e51b815260206004820181905260248201527f50726f706f73616c206d7573742068617665205061737365642073746174757360448201526064016105aa565b805460ff1916600317815560405163712467f960e11b815284906001600160a01b0382169063e248cff29061157b9089908c908c90600401611ffe565b600060405180830381600087803b15801561159557600080fd5b505af11580156115a9573d6000803e3d6000fd5b505050506000805160206121e58339815191528a8a6003866040516115d194939291906120d2565b60405180910390a150505050505050505050565b6115ed6117e1565b610b62611aa0565b600061010082106116485760405162461bcd60e51b815260206004820152601c60248201527f76616c756520646f6573206e6f742066697420696e203820626974730000000060448201526064016105aa565b5090565b6000600160801b82106116485760405162461bcd60e51b815260206004820152601e60248201527f76616c756520646f6573206e6f742066697420696e203132382062697473000060448201526064016105aa565b60006501000000000082106116485760405162461bcd60e51b815260206004820152601d60248201527f76616c756520646f6573206e6f742066697420696e203430206269747300000060448201526064016105aa565b6000610b7c836001600160a01b038416611ae2565b6001600160a01b03811660009081526001830160205260408120541515610b7c565b600082815260016020526040902061174790826116f8565b156105bd5760405133906001600160a01b0383169084907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d90600090a45050565b60008281526001602052604090206117a09082611b31565b156105bd5760405133906001600160a01b0383169084907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b90600090a45050565b6117ec600033610c1d565b610b625760405162461bcd60e51b815260206004820152601e60248201527f73656e64657220646f65736e277420686176652061646d696e20726f6c65000060448201526064016105aa565b611843600033610c1d565b8061186157506118616000805160206121c583398151915233610c1d565b610b625760405162461bcd60e51b815260206004820152601e60248201527f73656e646572206973206e6f742072656c61796572206f722061646d696e000060448201526064016105aa565b6000610b7c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611b46565b60008083602001516001600160c81b031661190984611a13565b16119392505050565b61191a6119cd565b6000805460ff191660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020015b60405180910390a1565b6000610b7c8383611b80565b6119816000805160206121c583398151915233610c1d565b610b625760405162461bcd60e51b815260206004820181905260248201527f73656e64657220646f65736e277420686176652072656c6179657220726f6c6560448201526064016105aa565b60005460ff1615610b625760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016105aa565b6000611a37611a306000805160206121c58339815191528461073b565b60016118ad565b6001901b92915050565b6000600160c81b82106116485760405162461bcd60e51b815260206004820152601e60248201527f76616c756520646f6573206e6f742066697420696e203230302062697473000060448201526064016105aa565b6000610761825490565b611aa8611baa565b6000805460ff191690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602001611953565b6000818152600183016020526040812054611b2957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610761565b506000610761565b6000610b7c836001600160a01b038416611bf3565b60008184841115611b6a5760405162461bcd60e51b81526004016105aa9190612034565b506000611b778486612105565b95945050505050565b6000826000018281548110611b9757611b97612199565b9060005260206000200154905092915050565b60005460ff16610b625760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016105aa565b60008181526001830160205260408120548015611cdc576000611c17600183612105565b8554909150600090611c2b90600190612105565b9050818114611c90576000866000018281548110611c4b57611c4b612199565b9060005260206000200154905080876000018481548110611c6e57611c6e612199565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611ca157611ca1612183565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610761565b6000915050610761565b60008083601f840112611cf857600080fd5b50813567ffffffffffffffff811115611d1057600080fd5b6020830191508360208260051b8501011115611d2b57600080fd5b9250929050565b803567ffffffffffffffff81168114611d4a57600080fd5b919050565b600060208284031215611d6157600080fd5b8135610b7c816121af565b600080600060608486031215611d8157600080fd5b8335611d8c816121af565b9250602084013591506040840135611da3816121af565b809150509250925092565b60008060008060408587031215611dc457600080fd5b843567ffffffffffffffff80821115611ddc57600080fd5b611de888838901611ce6565b90965094506020870135915080821115611e0157600080fd5b50611e0e87828801611ce6565b95989497509550505050565b600060208284031215611e2c57600080fd5b5035919050565b60008060408385031215611e4657600080fd5b823591506020830135611e58816121af565b809150509250929050565b60008060408385031215611e7657600080fd5b50508035926020909101359150565b600080600060608486031215611e9a57600080fd5b83359250611eaa60208501611d32565b9150604084013590509250925092565b60008060008060808587031215611ed057600080fd5b84359350611ee060208601611d32565b93969395505050506040820135916060013590565b600080600080600060808688031215611f0d57600080fd5b85359450611f1d60208701611d32565b9350604086013567ffffffffffffffff80821115611f3a57600080fd5b818801915088601f830112611f4e57600080fd5b813581811115611f5d57600080fd5b896020828501011115611f6f57600080fd5b96999598505060200195606001359392505050565b600080600060608486031215611f9957600080fd5b83356001600160481b0381168114611d8c57600080fd5b60058110611fce57634e487b7160e01b600052602160045260246000fd5b9052565b6bffffffffffffffffffffffff198460601b168152818360148301376000910160140190815292915050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b600060208083528351808285015260005b8181101561206157858101830151858201604001528201612045565b81811115612073576000604083870101525b50601f01601f1916929092016040019392505050565b600060808201905061209c828451611fb0565b60018060c81b03602084015116602083015260ff604084015116604083015264ffffffffff606084015116606083015292915050565b84815267ffffffffffffffff84166020820152608081016120f66040830185611fb0565b82606083015295945050505050565b60008282101561211757612117612157565b500390565b600060001982141561213057612130612157565b5060010190565b600060ff821660ff81141561214e5761214e612157565b60010192915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03811681146107f857600080fdfee2b7fb3b832174769106daebcfd6d1970523240dda11281102db9363b83b0dc44cb7956f27653ed00ab0902269b3f51178752f9eb2b4ec82146afdddc5a0d41ca2646970667358221220b23439b208dff4997c9173cdf2dda8de949c01317b346c547b3ee0ea3e37cec964736f6c63430008050033"; - -export class Bridge__factory extends ContractFactory { - constructor( - ...args: [signer: Signer] | ConstructorParameters - ) { - if (args.length === 1) { - super(_abi, _bytecode, args[0]); - } else { - super(...args); - } - } - - deploy( - chainID: BigNumberish, - initialRelayers: string[], - initialRelayerThreshold: BigNumberish, - fee: BigNumberish, - expiry: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise { - return super.deploy( - chainID, - initialRelayers, - initialRelayerThreshold, - fee, - expiry, - overrides || {} - ) as Promise; - } - getDeployTransaction( - chainID: BigNumberish, - initialRelayers: string[], - initialRelayerThreshold: BigNumberish, - fee: BigNumberish, - expiry: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): TransactionRequest { - return super.getDeployTransaction( - chainID, - initialRelayers, - initialRelayerThreshold, - fee, - expiry, - overrides || {} - ); - } - attach(address: string): Bridge { - return super.attach(address) as Bridge; - } - connect(signer: Signer): Bridge__factory { - return super.connect(signer) as Bridge__factory; - } - static readonly bytecode = _bytecode; - static readonly abi = _abi; - static createInterface(): BridgeInterface { - return new utils.Interface(_abi) as BridgeInterface; - } - static connect(address: string, signerOrProvider: Signer | Provider): Bridge { - return new Contract(address, _abi, signerOrProvider) as Bridge; - } -} diff --git a/packages/contracts/src/index.ts b/packages/contracts/src/index.ts index 44381c43b..df1ee900d 100644 --- a/packages/contracts/src/index.ts +++ b/packages/contracts/src/index.ts @@ -18,9 +18,6 @@ export { AnchorBase__factory } from "./factories/AnchorBase__factory"; export type { LinkableAnchor } from "./LinkableAnchor"; export { LinkableAnchor__factory } from "./factories/LinkableAnchor__factory"; -export type { Bridge } from "./Bridge"; -export { Bridge__factory } from "./factories/Bridge__factory"; - export type { SignatureBridge } from "./SignatureBridge"; export { SignatureBridge__factory } from "./factories/SignatureBridge__factory"; diff --git a/packages/vbridge/src/VBridge.ts b/packages/vbridge/src/VBridge.ts index 0fd66c47f..0c9b1e0c6 100644 --- a/packages/vbridge/src/VBridge.ts +++ b/packages/vbridge/src/VBridge.ts @@ -1,5 +1,4 @@ import { ethers, BigNumber, BigNumberish } from 'ethers'; -import VBridgeSide from './VBridgeSide'; import { SignatureBridgeSide } from '@webb-tools/bridges'; import { MintableToken, GovernedTokenWrapper } from "@webb-tools/tokens"; import { PoseidonT3__factory } from "@webb-tools/contracts"; @@ -38,7 +37,7 @@ export type BridgeConfig = { vAnchors: Map, // The addresses of the Bridge contracts (bridgeSides) to interact with - vBridgeSides: Map, + vBridgeSides: Map, } const zeroAddress = "0x0000000000000000000000000000000000000000"; @@ -54,7 +53,7 @@ function checkNativeAddress(tokenAddress: string): boolean { export class VBridge { private constructor( // Mapping of chainId => vBridgeSide - public vBridgeSides: Map, + public vBridgeSides: Map, // chainID => GovernedTokenWrapper (webbToken) address public webbTokenAddresses: Map, @@ -103,10 +102,10 @@ export class VBridge { return linkedVAnchorMap; } - public static async deployVariableAnchorBridge(vBridgeInput: VBridgeInput, deployers: DeployerConfig, isVBridgeSide: boolean): Promise { + public static async deployVariableAnchorBridge(vBridgeInput: VBridgeInput, deployers: DeployerConfig): Promise { let webbTokenAddresses: Map = new Map(); - let vBridgeSides: Map = new Map(); + let vBridgeSides: Map = new Map(); let vAnchors: Map = new Map(); // createdAnchors have the form of [[Anchors created on chainID], [...]] // and anchors in the subArrays of thhe same index should be linked together @@ -116,22 +115,12 @@ export class VBridge { const adminAddress = await deployers[chainID].getAddress(); let vBridgeInstance; // Create the bridgeSide - if (isVBridgeSide) { - vBridgeInstance = await VBridgeSide.createVBridgeSide( - [adminAddress], - 1, - 0, - 100, - deployers[chainID], - ); - } else { - vBridgeInstance = await SignatureBridgeSide.createBridgeSide( - adminAddress, - 0, - 100, - deployers[chainID], - ); - } + vBridgeInstance = await SignatureBridgeSide.createBridgeSide( + adminAddress, + 0, + 100, + deployers[chainID], + ); const handler = await AnchorHandler.createAnchorHandler(vBridgeInstance.contract.address, [], [], vBridgeInstance.admin); @@ -238,20 +227,15 @@ export class VBridge { // The setPermissions method accepts initialized bridgeSide and anchors. // it creates the anchor handler and sets the appropriate permissions // for the bridgeSide/anchorHandler/anchor - public static async setPermissions(vBridgeSide: VBridgeSide | SignatureBridgeSide, vAnchors: IAnchor[]): Promise { + public static async setPermissions(vBridgeSide: SignatureBridgeSide, vAnchors: IAnchor[]): Promise { let tokenDenomination = '1000000000000000000' // 1 ether for (let vAnchor of vAnchors) { - if (vBridgeSide instanceof VBridgeSide) { - await vBridgeSide.connectAnchor(vAnchor); - - await vBridgeSide.voteConfigLimitsProposal(vAnchor, BigNumber.from(0).toString(), BigNumber.from(tokenDenomination).mul(1_000_000).toString()); - - await vBridgeSide.executeConfigLimitsProposal(vAnchor, BigNumber.from(0).toString(), BigNumber.from(tokenDenomination).mul(1_000_000).toString()); - } else { - await vBridgeSide.connectAnchorWithSignature(vAnchor); - - await vBridgeSide.executeConfigLimitsProposalWithSig(vAnchor, BigNumber.from(0).toString(), BigNumber.from(tokenDenomination).mul(1_000_000).toString()); - } + await vBridgeSide.connectAnchorWithSignature(vAnchor); + await vBridgeSide.executeConfigLimitsProposalWithSig( + vAnchor, + BigNumber.from(0).toString(), + BigNumber.from(tokenDenomination).mul(1_000_000).toString() + ); } } @@ -275,13 +259,7 @@ export class VBridge { const chainId = await vAnchor.signer.getChainId(); const resourceID = await vAnchor.createResourceId(); const vBridgeSide = this.vBridgeSides.get(chainId); - if (vBridgeSide instanceof VBridgeSide) { - await vBridgeSide!.voteAnchorProposal(srcAnchor, resourceID); - await vBridgeSide!.executeProposal(srcAnchor, resourceID); - } else { - await vBridgeSide!.executeAnchorProposalWithSig(srcAnchor, resourceID); - } - + await vBridgeSide!.executeAnchorProposalWithSig(srcAnchor, resourceID); } }; diff --git a/packages/vbridge/src/VBridgeSide.ts b/packages/vbridge/src/VBridgeSide.ts deleted file mode 100644 index b4cb60d3a..000000000 --- a/packages/vbridge/src/VBridgeSide.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { ethers } from 'ethers'; -import { Bridge, Bridge__factory } from '@webb-tools/contracts'; -import { AnchorHandler } from '@webb-tools/anchors'; -import { IAnchor, Proposal } from '@webb-tools/interfaces'; - -export class VBridgeSide { - contract: Bridge; - admin: ethers.Signer; - handler: AnchorHandler | null; - proposals: Proposal[]; - - private constructor( - contract: Bridge, - signer: ethers.Signer, - ) { - this.contract = contract; - this.admin = signer; - this.handler = null; - this.proposals = []; - } - - public static async createVBridgeSide( - initialRelayers: string[], - initialRelayerThreshold: ethers.BigNumberish, - fee: ethers.BigNumberish, - expiry: ethers.BigNumberish, - admin: ethers.Signer - ): Promise { - const bridgeFactory = new Bridge__factory(admin); - const chainId = await admin.getChainId(); - const deployedBridge = await bridgeFactory.deploy(chainId, initialRelayers, initialRelayerThreshold, fee, expiry); - await deployedBridge.deployed(); - const vBridgeSide = new VBridgeSide(deployedBridge, admin); - return vBridgeSide; - } - - public static async connect(address: string, admin: ethers.Signer) { - const deployedBridge = Bridge__factory.connect(address, admin); - const vBridgeSide = new VBridgeSide(deployedBridge, admin); - return vBridgeSide; - } - - /** - * Creates the proposal data for updating an execution anchor - * with the latest state of a source anchor (i.e. most recent deposit). - * @param srcAnchor The anchor instance whose state has updated. - * @param executionResourceId The resource id of the execution anchor instance. - * @returns Promise - */ - public async createAnchorUpdateProposalData(srcAnchor: IAnchor, executionResourceID: string): Promise { - const proposalData = await srcAnchor.getProposalData(executionResourceID); - return proposalData; - } - - public async createHandlerUpdateProposalData(vAnchor: IAnchor, newHandler: string) { - const proposalData = await vAnchor.getHandlerProposalData(newHandler); - return proposalData; - } - - public async createConfigLimitsProposalData(vAnchor: IAnchor, _minimalWithdrawalAmount: string, _maximumDepositAmount: string) { - const proposalData = await vAnchor.getConfigLimitsProposalData(_minimalWithdrawalAmount,_maximumDepositAmount); - return proposalData; - } - - public setAnchorHandler(handler: AnchorHandler) { - this.handler = handler; - } - - // Connects the vBridgeSide, anchor handler, and anchor. - // Returns the resourceID used to connect them all - public async connectAnchor(anchor: IAnchor): Promise { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const resourceId = await anchor.createResourceId(); - const tx = await this.contract.adminSetResource(this.handler.contract.address, resourceId, anchor.contract.address); - await tx.wait(); - await this.voteHandlerProposal(anchor, this.handler.contract.address); - await this.executeHandlerProposal(anchor, this.handler.contract.address); - - return resourceId; - } - - /** - * Votes on an anchor proposal by creating the proposal data and submitting it to the bridge. - * @param srcAnchor The anchor instance whose state has updated. - * @param executionResourceID The resource id of the execution anchor instance. - * @returns - */ - public async voteAnchorProposal(srcAnchor: IAnchor, executionResourceID: string) { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const proposalData = await this.createAnchorUpdateProposalData(srcAnchor, executionResourceID); - const dataHash = ethers.utils.keccak256(this.handler.contract.address + proposalData.substr(2)); - const chainId = await srcAnchor.signer.getChainId(); - const nonce = srcAnchor.tree.number_of_elements() - 1; - - const tx = await this.contract.voteProposal(chainId, nonce, executionResourceID, dataHash); - const receipt = await tx.wait(); - - return receipt; - } - - // emit ProposalEvent(chainID, nonce, ProposalStatus.Executed, dataHash); - public async executeProposal(srcAnchor: IAnchor, executionResourceId: string) { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const proposalData = await this.createAnchorUpdateProposalData(srcAnchor, executionResourceId); - const chainId = await srcAnchor.signer.getChainId(); - const nonce = srcAnchor.tree.number_of_elements() - 1; - const tx = await this.contract.executeProposal(chainId, nonce, proposalData, executionResourceId); - const receipt = await tx.wait(); - - return receipt; - } - - public async voteHandlerProposal(anchor: IAnchor, newHandler: string) { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const proposalData = await this.createHandlerUpdateProposalData(anchor, newHandler); - const dataHash = ethers.utils.keccak256(this.handler.contract.address + proposalData.substr(2)); - - const chainId = await anchor.signer.getChainId(); - const nonce = 1; - const resourceID = await anchor.createResourceId(); - const tx = await this.contract.voteProposal(chainId, nonce, resourceID, dataHash); - const receipt = await tx.wait(); - - return receipt; - } - - public async executeHandlerProposal(anchor: IAnchor, newHandler: string) { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const proposalData = await this.createHandlerUpdateProposalData(anchor, newHandler); - const chainId = await anchor.signer.getChainId(); - const nonce = 1; - const resourceID = await anchor.createResourceId() - const tx = await this.contract.executeProposal(chainId, nonce, proposalData, resourceID); - const receipt = await tx.wait(); - - return receipt; - } - - public async voteConfigLimitsProposal(anchor: IAnchor, _minimalWithdrawalAmount: string, _maximumDepositAmount: string) { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const proposalData = await this.createConfigLimitsProposalData(anchor, _minimalWithdrawalAmount, _maximumDepositAmount); - const dataHash = ethers.utils.keccak256(this.handler.contract.address + proposalData.substr(2)); - - const chainId = await anchor.signer.getChainId(); - const nonce = 1; - const resourceID = await anchor.createResourceId(); - const tx = await this.contract.voteProposal(chainId, nonce, resourceID, dataHash); - const receipt = await tx.wait(); - - return receipt; - } - - public async executeConfigLimitsProposal(anchor: IAnchor, _minimalWithdrawalAmount: string, _maximumDepositAmount: string) { - if (!this.handler) { - throw new Error("Cannot connect an anchor without a handler"); - } - - const proposalData = await this.createConfigLimitsProposalData(anchor, _minimalWithdrawalAmount,_maximumDepositAmount); - const chainId = await anchor.signer.getChainId(); - const nonce = 1; - const resourceID = await anchor.createResourceId() - const tx = await this.contract.executeProposal(chainId, nonce, proposalData, resourceID); - const receipt = await tx.wait(); - - return receipt; - } -} - -export default VBridgeSide; diff --git a/packages/vbridge/src/index.ts b/packages/vbridge/src/index.ts index d88f1eddc..af4b92935 100644 --- a/packages/vbridge/src/index.ts +++ b/packages/vbridge/src/index.ts @@ -1,3 +1,8 @@ -export { VBridge, BridgeConfig, VBridgeInput, DeployerConfig, ExistingAssetInput} from './VBridge'; -export { VBridgeSide } from './VBridgeSide'; +export { + VBridge, + BridgeConfig, + VBridgeInput, + DeployerConfig, + ExistingAssetInput +} from './VBridge'; export { Verifier } from './Verifier'; diff --git a/scripts/bash/copyTypechain.sh b/scripts/bash/copyTypechain.sh index 2f8d66651..5fd3b0a54 100644 --- a/scripts/bash/copyTypechain.sh +++ b/scripts/bash/copyTypechain.sh @@ -8,7 +8,6 @@ cp ./typechain/FixedDepositAnchor.d.ts ./packages/contracts/src/FixedDepositAnch cp ./typechain/AnchorBase.d.ts ./packages/contracts/src/AnchorBase.d.ts cp ./typechain/AnchorHandler.d.ts ./packages/contracts/src/AnchorHandler.d.ts cp ./typechain/AnchorProxy.d.ts ./packages/contracts/src/AnchorProxy.d.ts -cp ./typechain/Bridge.d.ts ./packages/contracts/src/Bridge.d.ts cp ./typechain/SignatureBridge.d.ts ./packages/contracts/src/SignatureBridge.d.ts cp ./typechain/common.d.ts ./packages/contracts/src/common.d.ts cp ./typechain/ERC20.d.ts ./packages/contracts/src/ERC20.d.ts @@ -38,7 +37,6 @@ cp ./typechain/factories/FixedDepositAnchor__factory.ts ./packages/contracts/src cp ./typechain/factories/AnchorBase__factory.ts ./packages/contracts/src/factories/AnchorBase__factory.ts cp ./typechain/factories/AnchorHandler__factory.ts ./packages/contracts/src/factories/AnchorHandler__factory.ts cp ./typechain/factories/AnchorProxy__factory.ts ./packages/contracts/src/factories/AnchorProxy__factory.ts -cp ./typechain/factories/Bridge__factory.ts ./packages/contracts/src/factories/Bridge__factory.ts cp ./typechain/factories/SignatureBridge__factory.ts ./packages/contracts/src/factories/SignatureBridge__factory.ts cp ./typechain/factories/ERC20__factory.ts ./packages/contracts/src/factories/ERC20__factory.ts cp ./typechain/factories/ERC20PresetMinterPauser__factory.ts ./packages/contracts/src/factories/ERC20PresetMinterPauser__factory.ts diff --git a/test/bridge/admin.test.ts b/test/bridge/admin.test.ts deleted file mode 100644 index 7a292738b..000000000 --- a/test/bridge/admin.test.ts +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright 2021 Webb Technologies - * SPDX-License-Identifier: GPL-3.0-or-later-only - */ - -import { artifacts, assert, contract } from "hardhat"; -const TruffleAssert = require('truffle-assertions'); -const BridgeContract = artifacts.require("Bridge"); - -// This test does NOT include all getter methods, just -// getters that should work with only the constructor called -contract('Bridge - [admin]', async accounts => { - const chainID = 1; - const initialRelayers = accounts.slice(0, 3); - const initialRelayerThreshold = 2; - - const expectedBridgeAdmin = accounts[0]; - let ADMIN_ROLE; - - let BridgeInstance; - - beforeEach(async () => { - BridgeInstance = await BridgeContract.new(chainID, initialRelayers, initialRelayerThreshold, 0, 100); - ADMIN_ROLE = await BridgeInstance.DEFAULT_ADMIN_ROLE() - }); - - // Testing pausable methods - - it('Bridge should not be paused', async () => { - assert.isFalse(await BridgeInstance.paused()); - }); - - it('Bridge should be paused', async () => { - await TruffleAssert.passes(BridgeInstance.adminPauseTransfers()); - assert.isTrue(await BridgeInstance.paused()); - }); - - it('Bridge should be unpaused after being paused', async () => { - await TruffleAssert.passes(BridgeInstance.adminPauseTransfers()); - assert.isTrue(await BridgeInstance.paused()); - await TruffleAssert.passes(BridgeInstance.adminUnpauseTransfers()); - assert.isFalse(await BridgeInstance.paused()); - }); - - // Testing relayer methods - - it('_relayerThreshold should be initialRelayerThreshold', async () => { - assert.equal(await BridgeInstance._relayerThreshold.call(), initialRelayerThreshold); - }); - - it('_relayerThreshold should be initialRelayerThreshold', async () => { - const newRelayerThreshold = 1; - await TruffleAssert.passes(BridgeInstance.adminChangeRelayerThreshold(newRelayerThreshold)); - assert.equal(await BridgeInstance._relayerThreshold.call(), newRelayerThreshold); - }); - - it('newRelayer should be added as a relayer', async () => { - const newRelayer = accounts[4]; - await TruffleAssert.passes(BridgeInstance.adminAddRelayer(newRelayer)); - assert.isTrue(await BridgeInstance.isRelayer(newRelayer)); - }); - - it('newRelayer should be removed as a relayer after being added', async () => { - const newRelayer = accounts[4]; - await TruffleAssert.passes(BridgeInstance.adminAddRelayer(newRelayer)); - assert.isTrue(await BridgeInstance.isRelayer(newRelayer)) - await TruffleAssert.passes(BridgeInstance.adminRemoveRelayer(newRelayer)); - assert.isFalse(await BridgeInstance.isRelayer(newRelayer)); - }); - - it('existingRelayer should not be able to be added as a relayer', async () => { - const existingRelayer = accounts[1]; - await TruffleAssert.reverts(BridgeInstance.adminAddRelayer(existingRelayer)); - assert.isTrue(await BridgeInstance.isRelayer(existingRelayer)); - }); - - it('nonRelayerAddr should not be able to be added as a relayer', async () => { - const nonRelayerAddr = accounts[4]; - await TruffleAssert.reverts(BridgeInstance.adminRemoveRelayer(nonRelayerAddr)); - assert.isFalse(await BridgeInstance.isRelayer(nonRelayerAddr)); - }); - - // Testing ownership methods - - it('Bridge admin should be expectedBridgeAdmin', async () => { - assert.isTrue(await BridgeInstance.hasRole(ADMIN_ROLE, expectedBridgeAdmin)); - }); - - it('Bridge admin should be changed to expectedBridgeAdmin', async () => { - const expectedBridgeAdmin2 = accounts[1]; - await TruffleAssert.passes(BridgeInstance.renounceAdmin(expectedBridgeAdmin2)) - assert.isTrue(await BridgeInstance.hasRole(ADMIN_ROLE, expectedBridgeAdmin2)); - }); -}); diff --git a/test/bridge/bridgeSide.test.ts b/test/bridge/bridgeSide.test.ts deleted file mode 100644 index 54621c567..000000000 --- a/test/bridge/bridgeSide.test.ts +++ /dev/null @@ -1,332 +0,0 @@ -/** - * Copyright 2021 Webb Technologies - * SPDX-License-Identifier: GPL-3.0-or-later - */ -const assert = require('assert'); -const path = require('path'); -import { ethers } from 'hardhat'; -const TruffleAssert = require('truffle-assertions'); - -// Convenience wrapper classes for contract classes -import { Verifier } from '@webb-tools/bridges'; -import { Anchor, AnchorHandler } from '@webb-tools/anchors'; -import { BridgeSide } from '../../packages/bridges/src/BridgeSide' -import { MintableToken } from '@webb-tools/tokens'; -import { fetchComponentsFromFilePaths, ZkComponents } from '@webb-tools/utils'; -import { PoseidonT3__factory } from '../../typechain'; -import { GovernedTokenWrapper } from '../../packages/tokens/src/GovernedTokenWrapper'; -import { TokenWrapperHandler } from '../../packages/tokens/src/TokenWrapperHandler'; - -describe('BridgeSideConstruction', () => { - - let zkComponents: ZkComponents; - - before(async () => { - zkComponents = await fetchComponentsFromFilePaths( - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/2/poseidon_bridge_2.wasm'), - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/2/witness_calculator.js'), - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/2/circuit_final.zkey') - ); - }) - - it('should create the bridge side which can affect the anchor state', async () => { - const signers = await ethers.getSigners(); - const admin = signers[1]; - const relayer = signers[1]; - const recipient = signers[1]; - - const bridgeSide = await BridgeSide.createBridgeSide([relayer.address], 1, 0, 100, admin); - - // Create the Hasher and Verifier for the chain - const hasherFactory = new PoseidonT3__factory(admin); - let hasherInstance = await hasherFactory.deploy({ gasLimit: '0x5B8D80' }); - await hasherInstance.deployed(); - - const verifier = await Verifier.createVerifier(admin); - - const tokenInstance = await MintableToken.createToken('testToken', 'TEST', admin); - await tokenInstance.mintTokens(admin.address, '100000000000000000000000'); - - const anchorHandler = await AnchorHandler.createAnchorHandler(bridgeSide.contract.address, [], [], admin); - - const anchor = await Anchor.createAnchor( - verifier.contract.address, - hasherInstance.address, - '1000000000000', - 30, - tokenInstance.contract.address, - anchorHandler.contract.address, - 5, - zkComponents, - admin - ); - - await tokenInstance.approveSpending(anchor.contract.address); - - await bridgeSide.setAnchorHandler(anchorHandler); - // //Function call below sets resource with signature - await bridgeSide.connectAnchor(anchor); - //Check that proposal nonce is updated on anchor contract since handler prposal has been executed - assert.strictEqual(await anchor.contract.getProposalNonce(), 1); - }) - - it('execute fee proposal bridgeside', async () => { - const signers = await ethers.getSigners(); - const admin = signers[1]; - const bridgeSide = await BridgeSide.createBridgeSide([admin.address], 1, 0, 100, admin); - - //Deploy TokenWrapperHandler - const tokenWrapperHandler = await TokenWrapperHandler.createTokenWrapperHandler(bridgeSide.contract.address, [], [], admin); - - //Create a GovernedTokenWrapper - const governedToken = await GovernedTokenWrapper.createGovernedTokenWrapper( - `webbETH-test-1`, - `webbETH-test-1`, - tokenWrapperHandler.contract.address, - '10000000000000000000000000', - false, - admin, - ); - - //Set bridgeSide handler to tokenWrapperHandler - bridgeSide.setTokenWrapperHandler(tokenWrapperHandler); - - //Connect resourceID of GovernedTokenWrapper with TokenWrapperHandler - await bridgeSide.setGovernedTokenResource(governedToken); - - //Vote on fee Proposal - await bridgeSide.voteFeeProposal(governedToken, 5); - - //Execute change fee proposal - await bridgeSide.executeFeeProposal(governedToken, 5); - - //Check that fee actually changed - assert.strictEqual((await governedToken.contract.getFee()).toString(), '5'); - }) - - it('cannot set fee > 100 bridgeside', async () => { - const signers = await ethers.getSigners(); - const admin = signers[1]; - const bridgeSide = await BridgeSide.createBridgeSide([admin.address], 1, 0, 100, admin); - - //Deploy TokenWrapperHandler - const tokenWrapperHandler = await TokenWrapperHandler.createTokenWrapperHandler(bridgeSide.contract.address, [], [], admin); - - //Create a GovernedTokenWrapper - const governedToken = await GovernedTokenWrapper.createGovernedTokenWrapper( - `webbETH-test-1`, - `webbETH-test-1`, - tokenWrapperHandler.contract.address, - '10000000000000000000000000', - false, - admin, - ); - - //Set bridgeSide handler to tokenWrapperHandler - bridgeSide.setTokenWrapperHandler(tokenWrapperHandler); - - //Connect resourceID of GovernedTokenWrapper with TokenWrapperHandler - await bridgeSide.setGovernedTokenResource(governedToken); - - //Vote on fee Proposal - await bridgeSide.voteFeeProposal(governedToken, 101); - - await TruffleAssert.reverts( - bridgeSide.executeFeeProposal(governedToken, 101), - 'invalid fee percentage' - ); - }) - - it('execute add token proposal bridgeside', async () => { - const signers = await ethers.getSigners(); - const admin = signers[1]; - const bridgeSide = await BridgeSide.createBridgeSide([admin.address], 1, 0, 100, admin); - - //Deploy TokenWrapperHandler - const tokenWrapperHandler = await TokenWrapperHandler.createTokenWrapperHandler(bridgeSide.contract.address, [], [], admin); - - //Create a GovernedTokenWrapper - const governedToken = await GovernedTokenWrapper.createGovernedTokenWrapper( - `webbETH-test-1`, - `webbETH-test-1`, - tokenWrapperHandler.contract.address, - '10000000000000000000000000', - false, - admin, - ); - - //Set bridgeSide handler to tokenWrapperHandler - bridgeSide.setTokenWrapperHandler(tokenWrapperHandler); - - //Connect resourceID of GovernedTokenWrapper with TokenWrapperHandler - await bridgeSide.setGovernedTokenResource(governedToken); - - //Create an ERC20 Token - const tokenInstance = await MintableToken.createToken('testToken', 'TEST', admin); - await tokenInstance.mintTokens(admin.address, '100000000000000000000000'); - - //Vote on add token Proposal - await bridgeSide.voteAddTokenProposal(governedToken, tokenInstance.contract.address); - - //Execute Proposal to add that token to the governedToken - await bridgeSide.executeAddTokenProposal(governedToken, tokenInstance.contract.address); - - //Check that governedToken contains the added token - assert((await governedToken.contract.getTokens()).includes(tokenInstance.contract.address)); - }) - - it('execute remove token proposal bridgeside', async () => { - const signers = await ethers.getSigners(); - const admin = signers[1]; - const bridgeSide = await BridgeSide.createBridgeSide([admin.address], 1, 0, 100, admin); - - //Deploy TokenWrapperHandler - const tokenWrapperHandler = await TokenWrapperHandler.createTokenWrapperHandler(bridgeSide.contract.address, [], [], admin); - - //Create a GovernedTokenWrapper - const governedToken = await GovernedTokenWrapper.createGovernedTokenWrapper( - `webbETH-test-1`, - `webbETH-test-1`, - tokenWrapperHandler.contract.address, - '10000000000000000000000000', - false, - admin, - ); - - //Set bridgeSide handler to tokenWrapperHandler - bridgeSide.setTokenWrapperHandler(tokenWrapperHandler); - - //Connect resourceID of GovernedTokenWrapper with TokenWrapperHandler - await bridgeSide.setGovernedTokenResource(governedToken); - - //Create an ERC20 Token - const tokenInstance = await MintableToken.createToken('testToken', 'TEST', admin); - await tokenInstance.mintTokens(admin.address, '100000000000000000000000'); - - //Vote on fee Proposal - await bridgeSide.voteAddTokenProposal(governedToken, tokenInstance.contract.address); - - //Execute Proposal to add that token to the governedToken - await bridgeSide.executeAddTokenProposal(governedToken, tokenInstance.contract.address); - - //Check that governedToken contains the added token - assert((await governedToken.contract.getTokens()).includes(tokenInstance.contract.address)); - - //Vote on remove token Proposal - await bridgeSide.voteRemoveTokenProposal(governedToken, tokenInstance.contract.address); - - //Execute Proposal to add that token to the governedToken - await bridgeSide.executeRemoveTokenProposal(governedToken, tokenInstance.contract.address); - - assert((await governedToken.contract.getTokens()).length === 0); - }) - - it('check nonce is incrementing across multiple executions bridgeside', async () => { - const signers = await ethers.getSigners(); - const admin = signers[1]; - const bridgeSide = await BridgeSide.createBridgeSide([admin.address], 1, 0, 100, admin); - - //Deploy TokenWrapperHandler - const tokenWrapperHandler = await TokenWrapperHandler.createTokenWrapperHandler(bridgeSide.contract.address, [], [], admin); - - //Create a GovernedTokenWrapper - const governedToken = await GovernedTokenWrapper.createGovernedTokenWrapper( - `webbETH-test-1`, - `webbETH-test-1`, - tokenWrapperHandler.contract.address, - '10000000000000000000000000', - false, - admin, - ); - - //Set bridgeSide handler to tokenWrapperHandler - bridgeSide.setTokenWrapperHandler(tokenWrapperHandler); - - //Connect resourceID of GovernedTokenWrapper with TokenWrapperHandler - await bridgeSide.setGovernedTokenResource(governedToken); - - //Vote on fee Proposal - await bridgeSide.voteFeeProposal(governedToken, 5); - - //Execute change fee proposal - await bridgeSide.executeFeeProposal(governedToken, 5); - - //Check that fee actually changed - assert.strictEqual((await governedToken.contract.getFee()).toString(), '5'); - //Check nonce - assert.strictEqual((await governedToken.contract.proposalNonce()).toString(), '1'); - - //Create an ERC20 Token - const tokenInstance = await MintableToken.createToken('testToken', 'TEST', admin); - await tokenInstance.mintTokens(admin.address, '100000000000000000000000'); - - //Vote on fee Proposal - await bridgeSide.voteAddTokenProposal(governedToken, tokenInstance.contract.address); - - //Execute Proposal to add that token to the governedToken - await bridgeSide.executeAddTokenProposal(governedToken, tokenInstance.contract.address); - - //Check that governedToken contains the added token - assert((await governedToken.contract.getTokens()).includes(tokenInstance.contract.address)); - assert.strictEqual((await governedToken.contract.proposalNonce()).toString(), '2'); - - //Vote on remove token Proposal - await bridgeSide.voteRemoveTokenProposal(governedToken, tokenInstance.contract.address); - - //Execute Proposal to add that token to the governedToken - await bridgeSide.executeRemoveTokenProposal(governedToken, tokenInstance.contract.address); - - assert((await governedToken.contract.getTokens()).length === 0); - assert.strictEqual((await governedToken.contract.proposalNonce()).toString(), '3'); - }) - - it('nonce should update upon handler proposal executing', async () => { - const signers = await ethers.getSigners(); - const admin = signers[1]; - const relayer = signers[1]; - - const bridgeSide = await BridgeSide.createBridgeSide([relayer.address], 1, 0, 100, admin); - - // Create the Hasher and Verifier for the chain - const hasherFactory = new PoseidonT3__factory(admin); - let hasherInstance = await hasherFactory.deploy({ gasLimit: '0x5B8D80' }); - await hasherInstance.deployed(); - - const verifier = await Verifier.createVerifier(admin); - - const tokenInstance = await MintableToken.createToken('testToken', 'TEST', admin); - await tokenInstance.mintTokens(admin.address, '100000000000000000000000'); - - const anchorHandler = await AnchorHandler.createAnchorHandler(bridgeSide.contract.address, [], [], admin); - - const anchor = await Anchor.createAnchor( - verifier.contract.address, - hasherInstance.address, - '1000000000000', - 30, - tokenInstance.contract.address, - anchorHandler.contract.address, - 5, - zkComponents, - admin - ); - - await tokenInstance.approveSpending(anchor.contract.address); - - await bridgeSide.setAnchorHandler(anchorHandler); - // //Function call below sets resource with signature - await bridgeSide.connectAnchor(anchor); - //Check that proposal nonce is updated on anchor contract since handler prposal has been executed - assert.strictEqual(await anchor.contract.getProposalNonce(), 1); - - await bridgeSide.connectAnchor(anchor); - assert.strictEqual(await anchor.contract.getProposalNonce(), 2); - - await bridgeSide.connectAnchor(anchor); - assert.strictEqual(await anchor.contract.getProposalNonce(), 3); - - await bridgeSide.connectAnchor(anchor); - assert.strictEqual(await anchor.contract.getProposalNonce(), 4); - }) - -}) diff --git a/test/bridge/cancelUpdateProposal.test.ts b/test/bridge/cancelUpdateProposal.test.ts deleted file mode 100644 index f2b8d4468..000000000 --- a/test/bridge/cancelUpdateProposal.test.ts +++ /dev/null @@ -1,227 +0,0 @@ -/** - * Copyright 2021 Webb Technologies - * SPDX-License-Identifier: GPL-3.0-or-later-only - */ - -import { artifacts, assert, contract } from "hardhat"; -const TruffleAssert = require('truffle-assertions'); -const Ethers = require('ethers'); - -const Helpers = require('../helpers'); - -const BridgeContract = artifacts.require("Bridge"); -const AnchorHandlerContract = artifacts.require("AnchorHandler"); -const AnchorContract = artifacts.require("FixedDepositAnchor"); -const Hasher = artifacts.require("PoseidonT3"); -const Verifier = artifacts.require('Verifier'); -const Verifier2 = artifacts.require('Verifier2'); -const Verifier3 = artifacts.require('Verifier3'); -const Verifier4 = artifacts.require('Verifier4'); -const Verifier5 = artifacts.require('Verifier5'); -const Verifier6 = artifacts.require('Verifier6'); -const Token = artifacts.require("ERC20Mock"); - -contract('Bridge - [CancelUpdateProposal with relayerThreshold == 3]', async (accounts) => { - const originChainID = 1; - const destinationChainID = 2; - const relayer1Address = accounts[0]; - const relayer2Address = accounts[1]; - const relayer3Address = accounts[2]; - const relayer4Address = accounts[3]; - const relayer1Bit = 1 << 0; - const relayer2Bit = 1 << 1; - const relayer3Bit = 1 << 2; - const expectedUpdateNonce = 1; - const relayerThreshold = 3; - const merkleTreeHeight = 31; - const sender = accounts[5] - let merkleRoot; - let AnchorInstance; - let v2, v3, v4, v5, v6; - let hasher, verifier; - let token; - let tokenDenomination = '1000';// 1 ether - - let BridgeInstance; - let DestinationAnchorHandlerInstance; - let data = ''; - let dataHash = ''; - let resourceID = ''; - let initialResourceIDs; - let initialContractAddresses; - - let vote; - let executeProposal; - const MAX_EDGES = 1; - - beforeEach(async () => { - // create all contracts - await Promise.all([ - BridgeContract.new(destinationChainID, [ - relayer1Address, - relayer2Address, - relayer3Address, - relayer4Address], - relayerThreshold, - 0, - 10 - ).then(instance => BridgeInstance = instance), - Hasher.new().then(instance => hasher = instance), - Verifier2.new().then(instance => v2 = instance), - Verifier3.new().then(instance => v3 = instance), - Verifier4.new().then(instance => v4 = instance), - Verifier5.new().then(instance => v5 = instance), - Verifier6.new().then(instance => v6 = instance), - Token.new().then(instance => token = instance), - ]); - verifier = await Verifier.new( - v2.address, - v3.address, - v4.address, - v5.address, - v6.address - ); - - AnchorInstance = await AnchorContract.new( - sender, - token.address, - verifier.address, - hasher.address, - tokenDenomination, - merkleTreeHeight, - MAX_EDGES, - ); - - await token.mint(sender, tokenDenomination); - await token.increaseAllowance(AnchorInstance.address, 1000000000, { from: sender }); - let { logs } = await AnchorInstance.deposit('0x1111111111111111111111111111111111111111111111111111111111111111', { from: sender }); - let latestLeafIndex = logs[0].args.leafIndex; - merkleRoot = await AnchorInstance.getLastRoot(); - - resourceID = Helpers.createResourceID(AnchorInstance.address, originChainID); - initialResourceIDs = [resourceID]; - initialContractAddresses = [AnchorInstance.address]; - - DestinationAnchorHandlerInstance = await AnchorHandlerContract.new( - BridgeInstance.address, - initialResourceIDs, - initialContractAddresses, - ); - - data = Helpers.createUpdateProposalData(originChainID, latestLeafIndex, merkleRoot, '0x1111111111111111111111111111111111111111', destinationChainID); - dataHash = Ethers.utils.keccak256(DestinationAnchorHandlerInstance.address + data.substr(2)); - - await Promise.all([ - BridgeInstance.adminSetResource(DestinationAnchorHandlerInstance.address, resourceID, DestinationAnchorHandlerInstance.address) - ]); - - vote = (relayer) => BridgeInstance.voteProposal(originChainID, expectedUpdateNonce, resourceID, dataHash, { from: relayer }); - executeProposal = (relayer) => BridgeInstance.executeProposal(originChainID, expectedUpdateNonce, data, resourceID, { from: relayer }); - }); - - it('[sanity] bridge configured with threshold, relayers, and expiry', async () => { - assert.equal(await BridgeInstance._chainID(), destinationChainID) - - assert.equal(await BridgeInstance._relayerThreshold(), relayerThreshold) - - assert.equal((await BridgeInstance._totalRelayers()).toString(), '4') - - assert.equal(await BridgeInstance._expiry(), 10) - }) - - it('[sanity] updateProposal should be created with expected values', async () => { - await TruffleAssert.passes(vote(relayer1Address)); - - const expectedUpdateProposal = { - _yesVotes: relayer1Bit.toString(), - _yesVotesTotal: '1', - _status: '1' // Active - }; - - const updateProposal = await BridgeInstance.getProposal( - originChainID, expectedUpdateNonce, dataHash); - - assert.deepInclude(Object.assign({}, updateProposal), expectedUpdateProposal); - }); - - - it("voting on updateProposal after expiration treshold results in cancelled proposal", async () => { - await TruffleAssert.passes(vote(relayer1Address)); - - for (var i = 0; i < 10; i++) { - await Helpers.advanceBlock(); - } - - await TruffleAssert.passes(vote(relayer2Address)); - - const expectedUpdateProposal = { - _yesVotes: relayer1Bit.toString(), - _yesVotesTotal: '1', - _status: '4' // Cancelled - }; - - const updateProposal = await BridgeInstance.getProposal(originChainID, expectedUpdateNonce, dataHash); - assert.deepInclude(Object.assign({}, updateProposal), expectedUpdateProposal); - await TruffleAssert.reverts(vote(relayer3Address), "proposal already passed/executed/cancelled") - }); - - - it("relayer can cancel proposal after expiration threshold blocks have passed", async () => { - await TruffleAssert.passes(vote(relayer2Address)); - - for (var i = 0; i < 10; i++) { - await Helpers.advanceBlock(); - } - - const expectedUpdateProposal = { - _yesVotes: relayer2Bit.toString(), - _yesVotesTotal: '1', - _status: '4' // Cancelled - }; - - await TruffleAssert.passes(BridgeInstance.cancelProposal(originChainID, expectedUpdateNonce, dataHash)) - const updateProposal = await BridgeInstance.getProposal(originChainID, expectedUpdateNonce, dataHash); - assert.deepInclude(Object.assign({}, updateProposal), expectedUpdateProposal); - await TruffleAssert.reverts(vote(relayer4Address), "proposal already passed/executed/cancelled") - }); - - it("relayer cannot cancel proposal before expiration threshold blocks have passed", async () => { - await TruffleAssert.passes(vote(relayer2Address)); - - await TruffleAssert.reverts(BridgeInstance.cancelProposal(originChainID, expectedUpdateNonce, dataHash), "Proposal not at expiry threshold") - }); - - it("admin can cancel proposal after expiration threshold blocks have passed", async () => { - await TruffleAssert.passes(vote(relayer3Address)); - - for (var i = 0; i < 10; i++) { - await Helpers.advanceBlock(); - } - - const expectedUpdateProposal = { - _yesVotes: relayer3Bit.toString(), - _yesVotesTotal: '1', - _status: '4' // Cancelled - }; - - await TruffleAssert.passes(BridgeInstance.cancelProposal(originChainID, expectedUpdateNonce, dataHash)) - const updateProposal = await BridgeInstance.getProposal(originChainID, expectedUpdateNonce, dataHash); - assert.deepInclude(Object.assign({}, updateProposal), expectedUpdateProposal); - await TruffleAssert.reverts(vote(relayer2Address), "proposal already passed/executed/cancelled") - }); - - it("proposal cannot be cancelled twice", async () => { - await TruffleAssert.passes(vote(relayer3Address)); - - for (var i = 0; i < 10; i++) { - await Helpers.advanceBlock(); - } - - await TruffleAssert.passes(BridgeInstance.cancelProposal(originChainID, expectedUpdateNonce, dataHash)) - await TruffleAssert.reverts(BridgeInstance.cancelProposal(originChainID, expectedUpdateNonce, dataHash), "Proposal cannot be cancelled") - }); - - it("inactive proposal cannot be cancelled", async () => { - await TruffleAssert.reverts(BridgeInstance.cancelProposal(originChainID, expectedUpdateNonce, dataHash), "Proposal cannot be cancelled") - }); -}); diff --git a/test/bridge/constructor.test.ts b/test/bridge/constructor.test.ts deleted file mode 100644 index ef7097e6b..000000000 --- a/test/bridge/constructor.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright 2021 Webb Technologies - * SPDX-License-Identifier: GPL-3.0-or-later-only - */ - -import { artifacts, contract, web3 } from "hardhat"; -const TruffleAssert = require('truffle-assertions'); -const BridgeContract = artifacts.require("Bridge"); - -contract('Bridge - [constructor]', async accounts => { - const chainID = 1; - const initialRelayers = accounts.slice(0, 3); - const initialRelayerThreshold = 2; - let ADMIN_ROLE; - let BridgeInstance; - - const BN = (num) => { - return web3.utils.toBN(num); - }; - - beforeEach(async () => { - BridgeInstance = await BridgeContract.new(chainID, initialRelayers, initialRelayerThreshold, 0, 100); - ADMIN_ROLE = await BridgeInstance.DEFAULT_ADMIN_ROLE() - }); - - it('Bridge should not allow to set initialRelayerThreshold above 255', async () => { - return TruffleAssert.reverts(BridgeContract.new(chainID, initialRelayers, 256, 0, 100), "value does not fit in 8 bits"); - }); - - it('Bridge should not allow to set fee above 2**128 - 1', async () => { - return TruffleAssert.reverts(BridgeContract.new( - chainID, initialRelayers, initialRelayerThreshold, BN(2).pow(BN(128)), 100), "value does not fit in 128 bits"); - }); - - it('Bridge should not allow to set expiry above 2**40 - 1', async () => { - return TruffleAssert.reverts(BridgeContract.new(chainID, initialRelayers, initialRelayerThreshold, 0, BN(2).pow(BN(40))), "value does not fit in 40 bits"); - }); -}); diff --git a/test/bridge/createUpdateProposal.test.ts b/test/bridge/createUpdateProposal.test.ts deleted file mode 100644 index b708f1858..000000000 --- a/test/bridge/createUpdateProposal.test.ts +++ /dev/null @@ -1,385 +0,0 @@ -/** - * Copyright 2021 Webb Technologies - * SPDX-License-Identifier: GPL-3.0-or-later-only - */ - -import { artifacts, assert, contract } from "hardhat"; -const TruffleAssert = require('truffle-assertions'); -const Ethers = require('ethers'); - -const Helpers = require('../helpers'); - -const BridgeContract = artifacts.require("Bridge"); -const AnchorHandlerContract = artifacts.require("AnchorHandler"); -const Anchor = artifacts.require("FixedDepositAnchor"); -const Hasher = artifacts.require("PoseidonT3"); -const Verifier = artifacts.require('Verifier'); -const Verifier2 = artifacts.require('Verifier2'); -const Verifier3 = artifacts.require('Verifier3'); -const Verifier4 = artifacts.require('Verifier4'); -const Verifier5 = artifacts.require('Verifier5'); -const Verifier6 = artifacts.require('Verifier6'); -const Token = artifacts.require("ERC20Mock"); - -contract('Bridge - [create a update proposal (voteProposal) with relayerThreshold = 1]', async (accounts) => { - const originChainRelayerAddress = accounts[1]; - const originChainRelayerAddress2 = accounts[4]; - const originChainRelayerBit = 1 << 0; - const depositerAddress = accounts[2]; - const originChainID = 1; - const destinationChainID = 2; - const expectedUpdateNonce = 1; - const relayerThreshold = 1; - const expectedCreateEventStatus = 1; - const merkleTreeHeight = 31; - const sender = accounts[0] - - let merkleRoot; - let AnchorInstance; - let hasher; - let v2, v3, v4, v5, v6; - let verifier; - let token; - let tokenDenomination = '1000'; - - let BridgeInstance; - let DestinationAnchorHandlerInstance; - let resourceID; - let data = ''; - let dataHash = ''; - let initialResourceIDs; - let initialContractAddresses; - - const MAX_EDGES = 1; - - beforeEach(async () => { - await Promise.all([ - BridgeContract.new(originChainID, [ - originChainRelayerAddress, - originChainRelayerAddress2], - relayerThreshold, - 0, - 100 - ).then(instance => BridgeInstance = instance), - Hasher.new().then(instance => hasher = instance), - Verifier2.new().then(instance => v2 = instance), - Verifier3.new().then(instance => v3 = instance), - Verifier4.new().then(instance => v4 = instance), - Verifier5.new().then(instance => v5 = instance), - Verifier6.new().then(instance => v6 = instance), - Token.new().then(instance => token = instance), - ]); - verifier = await Verifier.new( - v2.address, - v3.address, - v4.address, - v5.address, - v6.address - ); - AnchorInstance = await Anchor.new( - sender, - token.address, - verifier.address, - hasher.address, - tokenDenomination, - merkleTreeHeight, - MAX_EDGES, - ); - - await token.mint(sender, tokenDenomination); - await token.increaseAllowance(AnchorInstance.address, 1000000000, { from: sender }); - let { logs } = await AnchorInstance.deposit('0x1111111111111111111111111111111111111111111111111111111111111111', { from: sender }); - let latestLeafIndex = logs[0].args.leafIndex; - merkleRoot = await AnchorInstance.getLastRoot(); - - resourceID = Helpers.createResourceID(AnchorInstance.address, originChainID); - initialResourceIDs = [resourceID]; - initialContractAddresses = [AnchorInstance.address]; - - DestinationAnchorHandlerInstance = await AnchorHandlerContract.new( - BridgeInstance.address, - initialResourceIDs, - initialContractAddresses, - ); - - data = Helpers.createUpdateProposalData(originChainID, latestLeafIndex, merkleRoot, '0x1111111111111111111111111111111111111111', destinationChainID); - dataHash = Ethers.utils.keccak256(DestinationAnchorHandlerInstance.address + data.substr(2)); - - await Promise.all([ - BridgeInstance.adminSetResource(DestinationAnchorHandlerInstance.address, resourceID, DestinationAnchorHandlerInstance.address) - ]); - }); - - it('should create updateProposal successfully', async () => { - TruffleAssert.passes(await BridgeInstance.voteProposal( - destinationChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: originChainRelayerAddress } - )); - }); - - it('should revert because updaterAddress is not a relayer', async () => { - await TruffleAssert.reverts(BridgeInstance.voteProposal( - destinationChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: depositerAddress } - ), "sender doesn't have relayer role"); - }); - - it("updateProposal shouldn't be created if it has a passedstatus", async () => { - await TruffleAssert.passes(BridgeInstance.voteProposal( - destinationChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: originChainRelayerAddress } - )); - - await TruffleAssert.reverts(BridgeInstance.voteProposal( - destinationChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: originChainRelayerAddress } - ), "proposal already passed/executed/cancelled"); - }); - - it("getProposal should be called successfully", async () => { - await TruffleAssert.passes(BridgeInstance.getProposal( - destinationChainID, expectedUpdateNonce, dataHash - )); - }); - - it('updateProposal should be created with expected values', async () => { - const expectedUpdateProposal = { - _yesVotes: originChainRelayerBit.toString(), - _yesVotesTotal: '1', - _status: '2' // passed - }; - - await BridgeInstance.voteProposal( - destinationChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: originChainRelayerAddress } - ); - - const updateProposal = await BridgeInstance.getProposal( - destinationChainID, expectedUpdateNonce, dataHash); - Helpers.assertObjectsMatch(expectedUpdateProposal, Object.assign({}, updateProposal)); - }); - - it('originChainRelayerAddress should be marked as voted for proposal', async () => { - await BridgeInstance.voteProposal( - destinationChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: originChainRelayerAddress } - ); - const hasVoted = await BridgeInstance._hasVotedOnProposal.call( - Helpers.nonceAndId(expectedUpdateNonce, destinationChainID), dataHash, originChainRelayerAddress); - assert.isTrue(hasVoted); - }); - - it('UpdateProposal Created event should be emitted with expected values', async () => { - const proposalTx = await BridgeInstance.voteProposal( - originChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: originChainRelayerAddress } - ); - - TruffleAssert.eventEmitted(proposalTx, 'ProposalEvent', (event) => { - return event.originChainID.toNumber() === originChainID && - event.nonce.toNumber() === expectedUpdateNonce && - event.status.toNumber() === expectedCreateEventStatus && - event.dataHash === dataHash - }); - }); -}); - -contract('Bridge - [create an update proposal (voteProposal) with relayerThreshold > 1]', async (accounts) => { - const originChainRelayerAddress = accounts[1]; - const originChainRelayerAddress2 = accounts[4]; - const originChainRelayerBit = 1 << 0; - const depositerAddress = accounts[2]; - const originChainID = 1; - const destinationChainID = 2; - const expectedUpdateNonce = 1; - const relayerThreshold = 2; - const expectedCreateEventStatus = 1; - const merkleTreeHeight = 31; - const sender = accounts[0] - - let v2, v3, v4, v5, v6; - let merkleRoot; - let AnchorInstance; - let hasher; - let verifier; - let token; - let tokenDenomination = '1000'; - - let BridgeInstance; - let DestinationAnchorHandlerInstance; - let resourceID; - let data = ''; - let dataHash = ''; - let initialResourceIDs; - let initialContractAddresses; - - const MAX_EDGES = 1; - - beforeEach(async () => { - await Promise.all([ - BridgeContract.new(originChainID, [ - originChainRelayerAddress, - originChainRelayerAddress2], - relayerThreshold, - 0, - 100 - ).then(instance => BridgeInstance = instance), - Hasher.new().then(instance => hasher = instance), - Verifier2.new().then(instance => v2 = instance), - Verifier3.new().then(instance => v3 = instance), - Verifier4.new().then(instance => v4 = instance), - Verifier5.new().then(instance => v5 = instance), - Verifier6.new().then(instance => v6 = instance), - Token.new().then(instance => token = instance), - ]); - verifier = await Verifier.new( - v2.address, - v3.address, - v4.address, - v5.address, - v6.address - ); - - AnchorInstance = await Anchor.new( - sender, - token.address, - verifier.address, - hasher.address, - tokenDenomination, - merkleTreeHeight, - MAX_EDGES, - ); - - await token.mint(sender, tokenDenomination); - await token.increaseAllowance(AnchorInstance.address, 1000000000, { from: sender }); - let { logs } = await AnchorInstance.deposit('0x1111111111111111111111111111111111111111111111111111111111111111', { from: sender }); - let latestLeafIndex = logs[0].args.leafIndex; - merkleRoot = await AnchorInstance.getLastRoot(); - - resourceID = Helpers.createResourceID(AnchorInstance.address, originChainID); - initialResourceIDs = [resourceID]; - initialContractAddresses = [AnchorInstance.address]; - - DestinationAnchorHandlerInstance = await AnchorHandlerContract.new( - BridgeInstance.address, - initialResourceIDs, - initialContractAddresses, - ); - - data = Helpers.createUpdateProposalData(originChainID, latestLeafIndex, merkleRoot, '0x1111111111111111111111111111111111111111', destinationChainID); - dataHash = Ethers.utils.keccak256(DestinationAnchorHandlerInstance.address + data.substr(2)); - - await Promise.all([ - BridgeInstance.adminSetResource(DestinationAnchorHandlerInstance.address, resourceID, DestinationAnchorHandlerInstance.address) - ]); - }); - - it('should create updateProposal successfully', async () => { - TruffleAssert.passes(await BridgeInstance.voteProposal( - destinationChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: originChainRelayerAddress } - )); - }); - - it('should revert because depositerAddress is not a relayer', async () => { - await TruffleAssert.reverts(BridgeInstance.voteProposal( - destinationChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: depositerAddress } - ), "sender doesn't have relayer role"); - }); - - it("updateProposal shouldn't be created if it has an Active status", async () => { - await TruffleAssert.passes(BridgeInstance.voteProposal( - destinationChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: originChainRelayerAddress } - )); - - await TruffleAssert.reverts(BridgeInstance.voteProposal( - destinationChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: originChainRelayerAddress } - ), "relayer already voted"); - }); - - it('updateProposal should be created with expected values', async () => { - const expectedUpdateProposal = { - _yesVotes: originChainRelayerBit.toString(), - _yesVotesTotal: '1', - _status: '1' // active - }; - - await BridgeInstance.voteProposal( - destinationChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: originChainRelayerAddress } - ); - - const updateProposal = await BridgeInstance.getProposal( - destinationChainID, expectedUpdateNonce, dataHash); - Helpers.assertObjectsMatch(expectedUpdateProposal, Object.assign({}, updateProposal)); - }); - - it('originChainRelayerAddress should be marked as voted for proposal', async () => { - await BridgeInstance.voteProposal( - destinationChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: originChainRelayerAddress } - ); - const hasVoted = await BridgeInstance._hasVotedOnProposal.call( - Helpers.nonceAndId(expectedUpdateNonce, destinationChainID), dataHash, originChainRelayerAddress); - assert.isTrue(hasVoted); - }); - - it('updateProposalCreated event should be emitted with expected values', async () => { - const proposalTx = await BridgeInstance.voteProposal( - originChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: originChainRelayerAddress } - ); - - TruffleAssert.eventEmitted(proposalTx, 'ProposalEvent', (event) => { - return event.originChainID.toNumber() === originChainID && - event.nonce.toNumber() === expectedUpdateNonce && - event.status.toNumber() === expectedCreateEventStatus && - event.dataHash === dataHash - }); - }); -}); \ No newline at end of file diff --git a/test/bridge/executeUpdateProposal.test.ts b/test/bridge/executeUpdateProposal.test.ts deleted file mode 100644 index b57784e08..000000000 --- a/test/bridge/executeUpdateProposal.test.ts +++ /dev/null @@ -1,294 +0,0 @@ -/** - * Copyright 2021 Webb Technologies - * SPDX-License-Identifier: GPL-3.0-or-later-only - */ - -import { artifacts, assert, contract } from "hardhat"; -import { toBN } from "web3-utils"; -const TruffleAssert = require('truffle-assertions'); -const Ethers = require('ethers'); - -const Helpers = require('../helpers'); - -const BridgeContract = artifacts.require("Bridge"); -const AnchorHandlerContract = artifacts.require("AnchorHandler"); -const Anchor = artifacts.require("FixedDepositAnchor"); -const Hasher = artifacts.require("PoseidonT3"); -const Verifier = artifacts.require('Verifier'); -const Verifier2 = artifacts.require('Verifier2'); -const Verifier3 = artifacts.require('Verifier3'); -const Verifier4 = artifacts.require('Verifier4'); -const Verifier5 = artifacts.require('Verifier5'); -const Verifier6 = artifacts.require('Verifier6'); -const Token = artifacts.require("ERC20Mock"); - -contract('Bridge - [executeUpdateProposal with relayerThreshold == 3]', async (accounts) => { - const sourceChainID = 1; - const destinationChainID = 2; - const thirdChainID = 3; - const relayer1Address = accounts[0]; - const relayer2Address = accounts[1]; - const relayer3Address = accounts[2]; - const relayer4Address = accounts[3]; - const relayer1Bit = 1 << 0; - const relayerThreshold = 3; - const merkleTreeHeight = 31; - const maxRoots = 1; - const sender = accounts[5] - - let merkleRoot; - let expectedUpdateNonce = 1; - let OriginChainAnchorInstance; - let DestChainAnchorInstance; - let ThirdAnchorInstance; - let v2, v3, v4, v5, v6; - let hasher, verifier; - let token; - let tokenDenomination = '1000'; - - let BridgeInstance; - let DestinationAnchorHandlerInstance; - let data = ''; - let dataHash = ''; - let resourceID = ''; - let initialResourceIDs; - let initialContractAddresses; - - let vote, executeProposal; - - const MAX_EDGES = 1; - - beforeEach(async () => { - // create all contracts - await Promise.all([ - BridgeContract.new(destinationChainID, [ - relayer1Address, - relayer2Address, - relayer3Address, - relayer4Address], - relayerThreshold, - 0, - 100, - ).then(instance => BridgeInstance = instance), - Hasher.new().then(instance => hasher = instance), - Verifier2.new().then(instance => v2 = instance), - Verifier3.new().then(instance => v3 = instance), - Verifier4.new().then(instance => v4 = instance), - Verifier5.new().then(instance => v5 = instance), - Verifier6.new().then(instance => v6 = instance), - Token.new().then(instance => token = instance), - ]); - verifier = await Verifier.new( - v2.address, - v3.address, - v4.address, - v5.address, - v6.address - ); - - OriginChainAnchorInstance = await Anchor.new( - sender, - token.address, - verifier.address, - hasher.address, - tokenDenomination, - merkleTreeHeight, - MAX_EDGES, - { from: sender }); - DestChainAnchorInstance = await Anchor.new( - sender, - token.address, - verifier.address, - hasher.address, - tokenDenomination, - merkleTreeHeight, - MAX_EDGES, - { from: sender }); - - await token.mint(sender, toBN(tokenDenomination).mul(toBN(1000000))); - await token.increaseAllowance(OriginChainAnchorInstance.address, 1000000000, { from: sender }); - let { logs } = await OriginChainAnchorInstance.deposit('0x11111', { from: sender }); - let latestLeafIndex = logs[0].args.leafIndex; - - merkleRoot = await OriginChainAnchorInstance.getLastRoot(); - resourceID = Helpers.createResourceID(OriginChainAnchorInstance.address, sourceChainID); - initialResourceIDs = [resourceID]; - initialContractAddresses = [DestChainAnchorInstance.address]; - - DestinationAnchorHandlerInstance = await AnchorHandlerContract.new( - BridgeInstance.address, - initialResourceIDs, - initialContractAddresses, - ); - - await DestChainAnchorInstance.setHandler(DestinationAnchorHandlerInstance.address, await DestChainAnchorInstance.getProposalNonce() + 1, { from: sender }); - - data = Helpers.createUpdateProposalData(sourceChainID, latestLeafIndex, merkleRoot, DestChainAnchorInstance.address, destinationChainID); - dataHash = Ethers.utils.keccak256(DestinationAnchorHandlerInstance.address + data.substr(2)); - - await Promise.all([ - BridgeInstance.adminSetResource(DestinationAnchorHandlerInstance.address, resourceID, DestChainAnchorInstance.address) - ]); - - vote = (relayer) => BridgeInstance.voteProposal( - sourceChainID, - expectedUpdateNonce, - resourceID, - dataHash, - { from: relayer }); - executeProposal = (relayer) => BridgeInstance.executeProposal( - sourceChainID, - expectedUpdateNonce, - data, - resourceID, - { from: relayer }); - }); - - it('[sanity] bridge configured with threshold and relayers', async () => { - assert.equal(await BridgeInstance._chainID(), destinationChainID) - - assert.equal(await BridgeInstance._relayerThreshold(), relayerThreshold) - - assert.equal((await BridgeInstance._totalRelayers()).toString(), '4') - }) - - it('[sanity] updateProposal should be created with expected values', async () => { - await TruffleAssert.passes(vote(relayer1Address)); - - const expectedUpdateProposal = { - _yesVotes: relayer1Bit.toString(), - _yesVotesTotal: '1', - _status: '1' // Active - }; - - const updateProposal = await BridgeInstance.getProposal( - sourceChainID, expectedUpdateNonce, dataHash); - - assert.deepInclude(Object.assign({}, updateProposal), expectedUpdateProposal); - }); - - it("Executing an updateProposal should addEdge", async () => { - // voting on and executing an update originating from a deposit on sourceChainID - await TruffleAssert.passes(vote(relayer1Address)); - await TruffleAssert.passes(vote(relayer2Address)); - await TruffleAssert.passes(vote(relayer3Address)); - await TruffleAssert.passes(executeProposal(relayer1Address)); - - const roots = await DestChainAnchorInstance.getLatestNeighborRoots(); - - assert.strictEqual(roots.length, maxRoots); - assert.strictEqual(roots[0], merkleRoot); - - }); - - it("Voting on a proposal with a resourceID not mapped to a handler (and AnchorContract) should fail", async () => { - const faultyResourceID = Helpers.createResourceID(DestChainAnchorInstance.address, sourceChainID); - await TruffleAssert.reverts(BridgeInstance.voteProposal(sourceChainID, expectedUpdateNonce, faultyResourceID , dataHash, { from: relayer1Address}), - "no handler for resourceID"); - - }); - - it("Executing an updateProposal for existing edge should updateEdge", async () => { - // voting on and executing an update originating from a deposit on sourceChainID - await TruffleAssert.passes(vote(relayer1Address)); - await TruffleAssert.passes(vote(relayer2Address)); - await TruffleAssert.passes(vote(relayer3Address)); - await TruffleAssert.passes(executeProposal(relayer1Address)); - - // new deposit on sourceChain changes root - let { logs } = await OriginChainAnchorInstance.deposit('0x22222', { from: sender }); - let latestLeafIndex = logs[0].args.leafIndex; - merkleRoot = await OriginChainAnchorInstance.getLastRoot(); - data = Helpers.createUpdateProposalData(sourceChainID, latestLeafIndex, merkleRoot, DestChainAnchorInstance.address, destinationChainID); - dataHash = Ethers.utils.keccak256(DestinationAnchorHandlerInstance.address + data.substr(2)); - expectedUpdateNonce++; - - // update edge proposal data is voted on - await TruffleAssert.passes(BridgeInstance.voteProposal(sourceChainID, expectedUpdateNonce, resourceID, dataHash, { from: relayer1Address })); - await TruffleAssert.passes(BridgeInstance.voteProposal(sourceChainID, expectedUpdateNonce, resourceID, dataHash, { from: relayer2Address })); - await TruffleAssert.passes(BridgeInstance.voteProposal(sourceChainID, expectedUpdateNonce, resourceID, dataHash, { from: relayer3Address })); - await TruffleAssert.passes(BridgeInstance.executeProposal(sourceChainID, expectedUpdateNonce, data, resourceID, { from: relayer2Address })); - - const newRoots = await DestChainAnchorInstance.getLatestNeighborRoots(); - // bridge between ONLY 2 chains means neighbors should be length 1 - assert.strictEqual(newRoots.length, maxRoots); - assert.strictEqual(newRoots[0], merkleRoot); - - }); - - it("Executing an updateProposal for existing edge with lesser or equal height should fail", async () => { - // voting on and executing an update originating from a deposit on sourceChainID - await TruffleAssert.passes(vote(relayer1Address)); - await TruffleAssert.passes(vote(relayer2Address)); - await TruffleAssert.passes(vote(relayer3Address)); - await TruffleAssert.passes(executeProposal(relayer1Address)); - - // new deposit on sourceChain which changes root - let { logs } = await OriginChainAnchorInstance.deposit('0x22222', { from: sender }); - let latestLeafIndex = logs[0].args.leafIndex; - merkleRoot = await OriginChainAnchorInstance.getLastRoot(); - // latestLeafIndex is not greater than last leaf index so execution reverts - data = Helpers.createUpdateProposalData(sourceChainID, latestLeafIndex - 1, merkleRoot, DestChainAnchorInstance.address, destinationChainID); - dataHash = Ethers.utils.keccak256(DestinationAnchorHandlerInstance.address + data.substr(2)); - expectedUpdateNonce++; - await TruffleAssert.passes(BridgeInstance.voteProposal(sourceChainID, expectedUpdateNonce, resourceID, dataHash, { from: relayer1Address })); - await TruffleAssert.passes(BridgeInstance.voteProposal(sourceChainID, expectedUpdateNonce, resourceID, dataHash, { from: relayer2Address })); - await TruffleAssert.passes(BridgeInstance.voteProposal(sourceChainID, expectedUpdateNonce, resourceID, dataHash, { from: relayer3Address })); - await TruffleAssert.reverts( - BridgeInstance.executeProposal(sourceChainID, expectedUpdateNonce, data, resourceID, { from: relayer2Address }), - "New leaf index must be greater"); - - }); - - it("updateProposal for adding more than allowed edges should fail with capacity error", async () => { - await TruffleAssert.passes(vote(relayer1Address)); - await TruffleAssert.passes(vote(relayer2Address)); - await TruffleAssert.passes(vote(relayer3Address)); - await TruffleAssert.passes(executeProposal(relayer1Address)); - - //initializing a linkableAnchor on a third chain - hasher = await Hasher.new(); - verifier = await Verifier.new( - v2.address, - v3.address, - v4.address, - v5.address, - v6.address - ); - token = await Token.new(); - await token.mint(sender, tokenDenomination); - ThirdAnchorInstance = await Anchor.new( - sender, - token.address, - verifier.address, - hasher.address, - tokenDenomination, - merkleTreeHeight, - MAX_EDGES, - { from: sender }); - - // deposit on third chain anchor - await token.increaseAllowance(ThirdAnchorInstance.address, 1000000000, { from: sender }); - let { logs } = await ThirdAnchorInstance.deposit('0x023888', { from: sender }); - let latestLeafIndex = logs[0].args.leafIndex; - // voting on deposit data (adding another Edge) - const newMerkleRoot = await ThirdAnchorInstance.getLastRoot(); - data = Helpers.createUpdateProposalData(thirdChainID, latestLeafIndex, newMerkleRoot, DestChainAnchorInstance.address, destinationChainID); - dataHash = Ethers.utils.keccak256(DestinationAnchorHandlerInstance.address + data.substr(2)); - expectedUpdateNonce++; - - await TruffleAssert.passes(BridgeInstance.voteProposal(thirdChainID, expectedUpdateNonce, resourceID, dataHash, { from: relayer1Address })); - await TruffleAssert.passes(BridgeInstance.voteProposal(thirdChainID, expectedUpdateNonce, resourceID, dataHash, { from: relayer2Address })); - await TruffleAssert.passes(BridgeInstance.voteProposal(thirdChainID, expectedUpdateNonce, resourceID, dataHash, { from: relayer3Address })); - await TruffleAssert.reverts( - BridgeInstance.executeProposal(thirdChainID, expectedUpdateNonce, data, resourceID, { from: relayer3Address }), - "This Anchor is at capacity" - ); - - //checking roots are correct for the edge - const newRoots = await DestChainAnchorInstance.getLatestNeighborRoots(); - // bridge between ONLY 2 chains means neighbors should be length 1 - assert.strictEqual(newRoots.length, maxRoots); - assert.strictEqual(newRoots[0], merkleRoot); - }); -}); \ No newline at end of file diff --git a/test/bridge/nativeBridge.test.ts b/test/bridge/nativeBridge.test.ts deleted file mode 100644 index a2a04cf07..000000000 --- a/test/bridge/nativeBridge.test.ts +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Copyright 2021 Webb Technologies - * SPDX-License-Identifier: GPL-3.0-or-later - */ -const assert = require('assert'); -import { ethers } from 'hardhat'; - -const path = require('path'); - -// Convenience wrapper classes for contract classes -import { Bridge } from '@webb-tools/bridges' -import { Anchor } from '@webb-tools/anchors'; -import { fetchComponentsFromFilePaths, ZkComponents } from '@webb-tools/utils'; -import { GovernedTokenWrapper } from '@webb-tools/tokens'; -import { startGanacheServer } from '../helpers/startGanacheServer'; -import { BridgeInput } from '@webb-tools/interfaces'; - -export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); - -describe('multichain tests for native', () => { - - // setup ganache networks - let ganacheServer2: any; - let zkComponents: ZkComponents; - - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); - ganacheProvider2.pollingInterval = 1; - let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); - - before('setup networks', async () => { - ganacheServer2 = await startGanacheServer(1337, 1337, 'congress island collect purity dentist team gas unlock nuclear pig combine sight'); - await sleep(2000); - - zkComponents = await fetchComponentsFromFilePaths( - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/2/poseidon_bridge_2.wasm'), - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/2/witness_calculator.js'), - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/2/circuit_final.zkey') - ); - }); - - describe('BridgeConstruction', () => { - let bridge2WebbEthInput: BridgeInput; - - it('create 2 side bridge for native token', async () => { - bridge2WebbEthInput = { - anchorInputs: { - asset: { - 31337: ['0'], - 1337: ['0x0000000000000000000000000000000000000000'], - }, - anchorSizes: ['1000000000000000000', '100000000000000000000', '10000000000000000000000'], - }, - chainIDs: [31337, 1337] - }; - - const signers = await ethers.getSigners(); - - const deploymentConfig = { - 31337: signers[1], - 1337: ganacheWallet2, - }; - const bridge = await Bridge.deployFixedDepositBridge(bridge2WebbEthInput, deploymentConfig, zkComponents); - - // Should be able to retrieve individual anchors - const chainId1 = 31337; - const chainId2 = 1337; - const anchorSize = '1000000000000000000'; - const anchor1: Anchor = bridge.getAnchor(chainId1, anchorSize)! as Anchor; - const anchor2: Anchor = bridge.getAnchor(chainId2, anchorSize)! as Anchor; - - // get the balance of native token for the signer - const nativeStartingBalance = await signers[2].getBalance(); - - // wrap and deposit on the bridge - const depositNative = await bridge.wrapAndDeposit(chainId2, '0x0000000000000000000000000000000000000000', anchorSize, signers[2]); - - // Check the native token has been taken from the depositor's account - const nativeEndingBalance = await signers[2].getBalance(); - assert.deepEqual(nativeEndingBalance.lt(nativeStartingBalance.sub(anchorSize)), true); - - // Check the edge of the linked anchor is updated - let edgeIndex = await anchor2.contract.edgeIndex(chainId1); - let destAnchorEdgeAfter = await anchor2.contract.edgeList(edgeIndex); - assert.deepEqual(ethers.BigNumber.from(0), destAnchorEdgeAfter.latestLeafIndex); - - // Check the wrapped token has been added to the anchor's account - const wrappedTokenAddress = bridge.getWebbTokenAddress(chainId1); - const wrappedToken = GovernedTokenWrapper.connect(wrappedTokenAddress!, signers[2]); - const wrappedTokenAnchorBalance = await wrappedToken.contract.balanceOf(anchor1.contract.address); - assert.deepEqual(wrappedTokenAnchorBalance.eq(anchorSize), true); - - // deposit on the other side of the bridge - const depositNativeOther = await bridge.wrapAndDeposit(chainId1, '0x0000000000000000000000000000000000000000', anchorSize, ganacheWallet2); - - // withdraw and unwrap from the first native deposit - const nativeOtherStartingBalance = await ganacheProvider2.getBalance(signers[2].address); - const event = await bridge.withdrawAndUnwrap(depositNative, '0x0000000000000000000000000000000000000000', anchorSize, signers[2].address, signers[2].address, ganacheWallet2); - const nativeOtherEndingBalance = await ganacheProvider2.getBalance(signers[2].address); - assert.deepEqual(nativeOtherEndingBalance.eq(nativeOtherStartingBalance.add(anchorSize)), true); - }).timeout(30000); - }) - - after('terminate networks', async () => { - await ganacheServer2.close(); - }); -}) diff --git a/test/bridge/voteUpdateProposal.test.ts b/test/bridge/voteUpdateProposal.test.ts deleted file mode 100644 index cb69d8d57..000000000 --- a/test/bridge/voteUpdateProposal.test.ts +++ /dev/null @@ -1,318 +0,0 @@ -/** - * Copyright 2021 Webb Technologies - * SPDX-License-Identifier: GPL-3.0-or-later-only - */ - -import { artifacts, assert, contract } from "hardhat"; -import { toBN } from "web3-utils"; -const TruffleAssert = require('truffle-assertions'); -const Ethers = require('ethers'); - -const Helpers = require('../helpers'); - -const BridgeContract = artifacts.require("Bridge"); -const AnchorHandlerContract = artifacts.require("AnchorHandler"); -const Anchor = artifacts.require("FixedDepositAnchor"); -const Hasher = artifacts.require("PoseidonT3"); -const Verifier = artifacts.require('Verifier'); -const Verifier2 = artifacts.require('Verifier2'); -const Verifier3 = artifacts.require('Verifier3'); -const Verifier4 = artifacts.require('Verifier4'); -const Verifier5 = artifacts.require('Verifier5'); -const Verifier6 = artifacts.require('Verifier6'); -const Token = artifacts.require("ERC20Mock"); - -contract('Bridge - [voteUpdateProposal with relayerThreshold == 3]', async (accounts) => { - const originChainID = 1; - const destinationChainID = 2; - const relayer1Address = accounts[0]; - const relayer2Address = accounts[1]; - const relayer3Address = accounts[2]; - const relayer4Address = accounts[3]; - const relayer1Bit = 1 << 0; - const relayer2Bit = 1 << 1; - const relayer3Bit = 1 << 2; - const depositerAddress = accounts[4]; - const relayerThreshold = 3; - const expectedFinalizedEventStatus = 2; - const expectedExecutedEventStatus = 3; - const merkleTreeHeight = 31; - const sender = accounts[5] - - let merkleRoot; - let expectedUpdateNonce = 1; - let OriginChainAnchorInstance; - let DestChainAnchorInstance; - let v2, v3, v4, v5, v6; - let hasher, verifier; - let token; - let tokenDenomination = '1000'; // 1 ether - - let BridgeInstance; - let DestinationAnchorHandlerInstance; - let data = ''; - let dataHash = ''; - let resourceID = ''; - let initialResourceIDs; - let initialContractAddresses; - - let vote, executeProposal; - - const MAX_EDGES = 1; - - beforeEach(async () => { - // create all contracts - await Promise.all([ - BridgeContract.new(destinationChainID, [ - relayer1Address, - relayer2Address, - relayer3Address, - relayer4Address], - relayerThreshold, - 0, - 100, - ).then(instance => BridgeInstance = instance), - Hasher.new().then(instance => hasher = instance), - Verifier2.new().then(instance => v2 = instance), - Verifier3.new().then(instance => v3 = instance), - Verifier4.new().then(instance => v4 = instance), - Verifier5.new().then(instance => v5 = instance), - Verifier6.new().then(instance => v6 = instance), - Token.new().then(instance => token = instance), - ]); - verifier = await Verifier.new( - v2.address, - v3.address, - v4.address, - v5.address, - v6.address - ); - - OriginChainAnchorInstance = await Anchor.new( - sender, - token.address, - verifier.address, - hasher.address, - tokenDenomination, - merkleTreeHeight, - MAX_EDGES, - { from: sender }); - DestChainAnchorInstance = await Anchor.new( - sender, - token.address, - verifier.address, - hasher.address, - tokenDenomination, - merkleTreeHeight, - MAX_EDGES, - { from: sender }); - - await token.mint(sender, toBN(tokenDenomination).mul(toBN(10))); - await token.increaseAllowance(OriginChainAnchorInstance.address, 1000000000, { from: sender }); - let { logs } = await OriginChainAnchorInstance.deposit('0x11111', { from: sender }); - let latestLeafIndex = logs[0].args.leafIndex; - merkleRoot = await OriginChainAnchorInstance.getLastRoot(); - resourceID = Helpers.createResourceID(OriginChainAnchorInstance.address, originChainID); - initialResourceIDs = [resourceID]; - initialContractAddresses = [DestChainAnchorInstance.address]; - - DestinationAnchorHandlerInstance = await AnchorHandlerContract.new( - BridgeInstance.address, - initialResourceIDs, - initialContractAddresses, - ); - - await DestChainAnchorInstance.setHandler(DestinationAnchorHandlerInstance.address, await DestChainAnchorInstance.getProposalNonce() + 1, { from: sender }); - - data = Helpers.createUpdateProposalData(originChainID, latestLeafIndex, merkleRoot, DestChainAnchorInstance.address, destinationChainID); - dataHash = Ethers.utils.keccak256(DestinationAnchorHandlerInstance.address + data.substr(2)); - - await Promise.all([ - BridgeInstance.adminSetResource(DestinationAnchorHandlerInstance.address, resourceID, DestChainAnchorInstance.address) - ]); - - vote = (relayer) => BridgeInstance.voteProposal(originChainID, expectedUpdateNonce, resourceID, dataHash, { from: relayer }); - executeProposal = (relayer) => BridgeInstance.executeProposal(originChainID, expectedUpdateNonce, data, resourceID, { from: relayer }); - }); - - it('[sanity] bridge configured with threshold and relayers', async () => { - assert.equal(await BridgeInstance._chainID(), destinationChainID) - - assert.equal(await BridgeInstance._relayerThreshold(), relayerThreshold) - - assert.equal((await BridgeInstance._totalRelayers()).toString(), '4') - }) - - it('[sanity] updateProposal should be created with expected values', async () => { - await TruffleAssert.passes(vote(relayer1Address)); - - const expectedUpdateProposal = { - _yesVotes: relayer1Bit.toString(), - _yesVotesTotal: '1', - _status: '1' // Active - }; - - const updateProposal = await BridgeInstance.getProposal( - originChainID, expectedUpdateNonce, dataHash); - - assert.deepInclude(Object.assign({}, updateProposal), expectedUpdateProposal); - }); - - it('should revert because depositerAddress is not a relayer', async () => { - await TruffleAssert.reverts(vote(depositerAddress), "sender doesn't have relayer role"); - }); - - it("updateProposal shouldn't be voted on if it has a Passed status", async () => { - await TruffleAssert.passes(vote(relayer1Address)); - - await TruffleAssert.passes(vote(relayer2Address)); - - await TruffleAssert.passes(vote(relayer3Address)); - - await TruffleAssert.reverts(vote(relayer4Address), 'proposal already passed/executed/cancelled'); - }); - - it("updateProposal shouldn't be voted on if it has a Transferred status", async () => { - await TruffleAssert.passes(vote(relayer1Address)); - - await TruffleAssert.passes(vote(relayer2Address)); - - await TruffleAssert.passes(vote(relayer3Address)); - - await TruffleAssert.passes(executeProposal(relayer1Address)); - - await TruffleAssert.reverts(vote(relayer4Address), 'proposal already passed/executed/cancelled'); - - }); - - it("relayer shouldn't be able to vote on a updateProposal more than once", async () => { - await TruffleAssert.passes(vote(relayer1Address)); - - await TruffleAssert.reverts(vote(relayer1Address), 'relayer already voted'); - }); - - it("Should be able to create a proposal with a different hash", async () => { - await TruffleAssert.passes(vote(relayer1Address)); - - await TruffleAssert.passes( - BridgeInstance.voteProposal( - originChainID, expectedUpdateNonce, - resourceID, Ethers.utils.keccak256(dataHash), - { from: relayer2Address })); - }); - - it("Relayer's vote should be recorded correctly - yes vote", async () => { - await TruffleAssert.passes(vote(relayer1Address)); - - const updateProposalAfterFirstVote = await BridgeInstance.getProposal( - originChainID, expectedUpdateNonce, dataHash); - assert.equal(updateProposalAfterFirstVote._yesVotesTotal, 1); - assert.equal(updateProposalAfterFirstVote._yesVotes, relayer1Bit); - assert.strictEqual(updateProposalAfterFirstVote._status, '1'); - - await TruffleAssert.passes(vote(relayer2Address)); - - const updateProposalAfterSecondVote = await BridgeInstance.getProposal( - originChainID, expectedUpdateNonce, dataHash); - assert.equal(updateProposalAfterSecondVote._yesVotesTotal, 2); - assert.equal(updateProposalAfterSecondVote._yesVotes, relayer1Bit + relayer2Bit); - assert.strictEqual(updateProposalAfterSecondVote._status, '1'); - - await TruffleAssert.passes(vote(relayer3Address)); - - const updateProposalAfterThirdVote = await BridgeInstance.getProposal( - originChainID, expectedUpdateNonce, dataHash); - assert.equal(updateProposalAfterThirdVote._yesVotesTotal, 3); - assert.equal(updateProposalAfterThirdVote._yesVotes, relayer1Bit + relayer2Bit + relayer3Bit); - assert.strictEqual(updateProposalAfterThirdVote._status, '2'); - - await TruffleAssert.passes(executeProposal(relayer1Address)); - - const updateProposalAfterExecute = await BridgeInstance.getProposal( - originChainID, expectedUpdateNonce, dataHash); - assert.equal(updateProposalAfterExecute._yesVotesTotal, 3); - assert.equal(updateProposalAfterExecute._yesVotes, relayer1Bit + relayer2Bit + relayer3Bit); - assert.strictEqual(updateProposalAfterExecute._status, '3'); - }); - - it("Relayer's address should be marked as voted for proposal", async () => { - await TruffleAssert.passes(vote(relayer1Address)); - - const hasVoted = await BridgeInstance._hasVotedOnProposal.call( - Helpers.nonceAndId(expectedUpdateNonce, originChainID), dataHash, relayer1Address); - assert.isTrue(hasVoted); - }); - - it('UpdateProposalFinalized event should be emitted when proposal status updated to passed after numYes >= relayerThreshold', async () => { - await TruffleAssert.passes(vote(relayer1Address)); - await TruffleAssert.passes(vote(relayer2Address)); - - const voteTx = await vote(relayer3Address); - - TruffleAssert.eventEmitted(voteTx, 'ProposalEvent', (event) => { - return event.originChainID.toNumber() === originChainID && - event.nonce.toNumber() === expectedUpdateNonce && - event.status.toNumber() === expectedFinalizedEventStatus && - event.dataHash === dataHash - }); - }); - - it('UpdateProposalVote event fired when proposal vote made', async () => { - const voteTx = await vote(relayer1Address); - - TruffleAssert.eventEmitted(voteTx, 'ProposalVote', (event) => { - return event.originChainID.toNumber() === originChainID && - event.nonce.toNumber() === expectedUpdateNonce && - event.status.toNumber() === 1 - }); - }); - - it('Execution successful', async () => { - await TruffleAssert.passes(vote(relayer1Address)); - - await TruffleAssert.passes(vote(relayer2Address)); - - const voteTx = await vote(relayer3Address); - - TruffleAssert.eventEmitted(voteTx, 'ProposalEvent', (event) => { - return event.originChainID.toNumber() === originChainID && - event.nonce.toNumber() === expectedUpdateNonce && - event.status.toNumber() === expectedFinalizedEventStatus && - event.dataHash === dataHash - }); - - const executionTx = await executeProposal(relayer1Address) - - TruffleAssert.eventEmitted(executionTx, 'ProposalEvent', (event) => { - return event.originChainID.toNumber() === originChainID && - event.nonce.toNumber() === expectedUpdateNonce && - event.status.toNumber() === expectedExecutedEventStatus && - event.dataHash === dataHash - }); - }); - - it('Proposal cannot be executed twice', async () => { - await vote(relayer1Address); - await vote(relayer2Address); - await vote(relayer3Address); - await executeProposal(relayer1Address); - await TruffleAssert.reverts(executeProposal(relayer1Address), "Proposal must have Passed status"); - }); - - it('Execution requires active proposal', async () => { - await TruffleAssert.reverts(BridgeInstance.executeProposal(originChainID, expectedUpdateNonce, data, '0x0', { from: relayer1Address }), "Proposal must have Passed status"); - }); - - it('Voting requires resourceID that is mapped to a handler', async () => { - await TruffleAssert.reverts(BridgeInstance.voteProposal(originChainID, expectedUpdateNonce, '0x0', dataHash, { from: relayer1Address }), "no handler for resourceID"); - }); - - it("executed proposal cannot be cancelled", async () => { - await TruffleAssert.passes(vote(relayer1Address)); - await TruffleAssert.passes(vote(relayer2Address)); - await TruffleAssert.passes(vote(relayer3Address)); - - await TruffleAssert.passes(BridgeInstance.executeProposal(originChainID, expectedUpdateNonce, data, resourceID)); - await TruffleAssert.reverts(BridgeInstance.cancelProposal(originChainID, expectedUpdateNonce, dataHash), "Proposal cannot be cancelled") - }); -}); diff --git a/test/integration/bridge.test.ts b/test/integration/bridge.test.ts deleted file mode 100644 index f0a9d06f9..000000000 --- a/test/integration/bridge.test.ts +++ /dev/null @@ -1,557 +0,0 @@ -/** - * Copyright 2021 Webb Technologies - * SPDX-License-Identifier: GPL-3.0-or-later - */ -const TruffleAssert = require('truffle-assertions'); -const assert = require('assert'); -import { ethers, network } from 'hardhat'; - -const snarkjs = require('snarkjs') -const fs = require('fs'); -const path = require('path'); - -// Convenience wrapper classes for contract classes -import { Bridge } from '@webb-tools/bridges'; -import { Anchor } from '@webb-tools/anchors'; -import { BridgeInput } from '@webb-tools/interfaces'; -import { MintableToken } from '@webb-tools/tokens'; -import { fetchComponentsFromFilePaths, ZkComponents } from '@webb-tools/utils'; -import { BigNumber } from '@ethersproject/bignumber'; -import { Signer } from 'ethers'; -import { startGanacheServer } from '../helpers/startGanacheServer'; - -export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); - -describe('multichain tests for erc20 bridges', () => { - // setup ganache networks - let ganacheServer2: any; - let ganacheServer3: any; - let ganacheServer4: any; - - // setup zero knowledge components - let zkComponents2: ZkComponents; - let zkComponents3: ZkComponents; - let zkComponents4: ZkComponents; - - before('setup networks', async () => { - ganacheServer2 = await startGanacheServer(1337, 1337, 'congress island collect purity dentist team gas unlock nuclear pig combine sight'); - ganacheServer3 = await startGanacheServer(9999, 9999, 'aspect biology suit thought bottom popular custom rebuild recall sauce endless local'); - ganacheServer4 = await startGanacheServer(4444, 4444, 'harvest useful giraffe swim rail ostrich public awful provide amazing tank weapon'); - await sleep(2000); - - zkComponents2 = await fetchComponentsFromFilePaths( - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/2/poseidon_bridge_2.wasm'), - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/2/witness_calculator.js'), - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/2/circuit_final.zkey') - ); - zkComponents3 = await fetchComponentsFromFilePaths( - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/3/poseidon_bridge_3.wasm'), - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/3/witness_calculator.js'), - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/3/circuit_final.zkey') - ); - zkComponents4 = await fetchComponentsFromFilePaths( - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/4/poseidon_bridge_4.wasm'), - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/4/witness_calculator.js'), - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/bridge/4/circuit_final.zkey') - ); - }); - - describe('BridgeConstruction', () => { - let bridge2WebbEthInput: BridgeInput; - let bridge3WebbEthInput: BridgeInput; - let tokenName: string = 'existingERC20'; - let tokenAbbreviation: string = 'EXIST'; - let tokenInstance1: MintableToken; - let tokenInstance2: MintableToken; - let tokenInstance3: MintableToken; - - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); - ganacheProvider2.pollingInterval = 1; - let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); - let ganacheProvider3 = new ethers.providers.JsonRpcProvider('http://localhost:9999'); - ganacheProvider3.pollingInterval = 1; - let ganacheWallet3 = new ethers.Wallet('745ee040ef2b087f075dc7d314fa06797ed2ffd4ab59a4cc35c0a33e8d2b7791', ganacheProvider3); - - before('construction-tests', async () => { - const signers = await ethers.getSigners(); - - // Create a token to test bridge construction support for existing tokens - tokenInstance1 = await MintableToken.createToken(tokenName, tokenAbbreviation, signers[7]); - tokenInstance2 = await MintableToken.createToken(tokenName, tokenAbbreviation, ganacheWallet2); - tokenInstance3 = await MintableToken.createToken(tokenName, tokenAbbreviation, ganacheWallet3); - - await tokenInstance1.mintTokens(signers[1].address, '100000000000000000000000000'); - }); - - it('create 2 side bridge for one token', async () => { - - bridge2WebbEthInput = { - anchorInputs: { - asset: { - 31337: [tokenInstance1.contract.address], - 1337: [tokenInstance2.contract.address], - }, - anchorSizes: ['1000000000000000000', '100000000000000000000', '10000000000000000000000'], - }, - chainIDs: [31337, 1337] - }; - - const signers = await ethers.getSigners(); - - const deploymentConfig = { - 31337: signers[1], - 1337: ganacheWallet2, - }; - const bridge = await Bridge.deployFixedDepositBridge(bridge2WebbEthInput, deploymentConfig, zkComponents2); - - // Should be able to retrieve individual anchors - const chainId1 = 31337; - const chainId2 = 1337; - const anchorSize = '1000000000000000000'; - const anchor1: Anchor = bridge.getAnchor(chainId1, anchorSize)! as Anchor; - const anchor2: Anchor = bridge.getAnchor(chainId2, anchorSize)! as Anchor; - - // Should be able to retrieve the token address (so we can mint tokens for test scenario) - const webbTokenAddress = bridge.getWebbTokenAddress(chainId1); - const webbToken = await MintableToken.tokenFromAddress(webbTokenAddress!, signers[1]); - const tx = await webbToken.mintTokens(signers[2].address, '100000000000000000000000'); - - // get the state of anchors before deposit - const sourceAnchorRootBefore = await anchor1.contract.getLastRoot(); - - // Deposit on the bridge - const depositNote = await bridge.deposit(chainId2, anchorSize, signers[2]); - - // Check the state of anchors after deposit - let edgeIndex = await anchor2.contract.edgeIndex(chainId1); - - const sourceAnchorRootAfter = await anchor1.contract.getLastRoot(); - const destAnchorEdgeAfter = await anchor2.contract.edgeList(edgeIndex); - - // make sure the roots / anchors state have changed - assert.notEqual(sourceAnchorRootAfter, sourceAnchorRootBefore); - assert.deepEqual(ethers.BigNumber.from(0), destAnchorEdgeAfter.latestLeafIndex); - - await bridge.withdraw(depositNote, anchorSize, signers[1].address, signers[1].address, ganacheWallet2); - - const webbTokenAddress2 = bridge.getWebbTokenAddress(chainId2); - const webbToken2 = await MintableToken.tokenFromAddress(webbTokenAddress2!, ganacheWallet2); - const webbTokenBalance2 = await webbToken2.getBalance(signers[1].address); - - assert.deepEqual(webbTokenBalance2, ethers.BigNumber.from(anchorSize)); - }); - - it('create 3 side bridge for one token', async () => { - bridge3WebbEthInput = { - anchorInputs: { - asset: { - 31337: [tokenInstance1.contract.address], - 1337: [tokenInstance2.contract.address], - 9999: [tokenInstance3.contract.address], - }, - anchorSizes: ['1000000000000000000', '100000000000000000000', '10000000000000000000000'], - }, - chainIDs: [31337, 1337, 9999] - }; - - const signers = await ethers.getSigners(); - - const deploymentConfig = { - 31337: signers[1], - 1337: ganacheWallet2, - 9999: ganacheWallet3, - }; - const bridge = await Bridge.deployFixedDepositBridge(bridge3WebbEthInput, deploymentConfig, zkComponents3); - - // Should be able to retrieve individual anchors - const chainId1 = 31337; - const chainId2 = 1337; - const chainId3 = 9999; - const anchorSize = '1000000000000000000'; - const anchor1: Anchor = bridge.getAnchor(chainId1, anchorSize)! as Anchor; - const anchor2: Anchor = bridge.getAnchor(chainId2, anchorSize)! as Anchor; - const anchor3: Anchor = bridge.getAnchor(chainId3, anchorSize)! as Anchor; - - // get the state of anchors before deposit - const sourceAnchorRootBefore = await anchor1.contract.getLastRoot(); - - // Should be able to retrieve the token address (so we can mint tokens for test scenario) - const webbTokenAddress = bridge.webbTokenAddresses.get(chainId1); - const webbToken = await MintableToken.tokenFromAddress(webbTokenAddress!, signers[1]); - const tx = await webbToken.mintTokens(signers[2].address, '100000000000000000000000'); - - // Deposit on the bridge with dest chainID and - const depositNote = await bridge.deposit(chainId2, anchorSize, signers[2]); - - // Check the state of anchors after deposit - const sourceAnchorRootAfter = await anchor1.contract.getLastRoot(); - let edgeIndex = await anchor2.contract.edgeIndex(chainId1); - const destAnchorEdge2After = await anchor2.contract.edgeList(edgeIndex); - edgeIndex = await anchor3.contract.edgeIndex(chainId1); - const destAnchorEdge3After = await anchor3.contract.edgeList(edgeIndex); - - // make sure the roots / anchors state have changed - assert.notEqual(sourceAnchorRootAfter, sourceAnchorRootBefore); - assert.deepStrictEqual(destAnchorEdge2After.latestLeafIndex, destAnchorEdge3After.latestLeafIndex); - assert.deepStrictEqual(destAnchorEdge2After.root, destAnchorEdge3After.root); - }); - - it('create 2 side bridge for multiple tokens', async () => { - bridge2WebbEthInput = { - anchorInputs: { - asset: { - 31337: [tokenInstance1.contract.address], - 1337: [tokenInstance2.contract.address], - }, - anchorSizes: ['1000000000000000000', '100000000000000000000', '10000000000000000000000'], - }, - chainIDs: [31337, 1337] - }; - }); - - it('create 2 side bridge for native and erc20 token', async () => { - bridge2WebbEthInput = { - anchorInputs: { - asset: { - 31337: [tokenInstance1.contract.address, '0'], - 1337: [tokenInstance2.contract.address, '0x0000000000000000000000000000000000000000'], - }, - anchorSizes: ['1000000000000000000', '100000000000000000000', '10000000000000000000000'], - }, - chainIDs: [31337, 1337] - }; - }); - }).timeout(50000); - - describe('2 sided bridge existing token use', () => { - - // ERC20 compliant contracts that can easily create balances for test - let existingToken1: MintableToken; - let existingToken2: MintableToken; - - let bridge: Bridge; - const chainId1 = 31337; - const chainId2 = 1337; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); - ganacheProvider2.pollingInterval = 1; - let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); - - before(async () => { - const signers = await ethers.getSigners(); - - existingToken1 = await MintableToken.createToken('existingERC20', 'EXIST', signers[1]); - // Use some other signer with provider on other chain - existingToken2 = await MintableToken.createToken('existingERC20', 'EXIST', ganacheWallet2); - - // mint some tokens to the user of the bridge - await existingToken1.mintTokens(signers[1].address, '100000000000000000000000000'); - await existingToken2.mintTokens(ganacheWallet2.address, '100000000000000000000000000'); - }) - - beforeEach(async () => { - const signers = await ethers.getSigners(); - - // create the config for the bridge - const existingTokenBridgeConfig = { - anchorInputs: { - asset: { - [chainId1]: [existingToken1.contract.address], - [chainId2]: [existingToken2.contract.address], - }, - anchorSizes: ['1000000000000000000', '100000000000000000000', '10000000000000000000000'], - }, - chainIDs: [chainId1, chainId2] - }; - - // setup the config for deployers of contracts (admins) - const deploymentConfig = { - [chainId1]: signers[1], - [chainId2]: ganacheWallet2, - } - - // deploy the bridge - bridge = await Bridge.deployFixedDepositBridge(existingTokenBridgeConfig, deploymentConfig, zkComponents2); - - // make one deposit so the edge exists - await bridge.wrapAndDeposit(chainId2, existingToken1.contract.address, '1000000000000000000', signers[1]); - await bridge.wrapAndDeposit(chainId1, existingToken2.contract.address, '1000000000000000000', ganacheWallet2); - }) - - describe('#bridging', () => { - it('should withdraw successfully from latest deposit', async () => { - // Fetch information about the anchor to be updated. - const signers = await ethers.getSigners(); - const anchorSize = '1000000000000000000'; - - const anchor2: Anchor = bridge.getAnchor(chainId2, anchorSize)! as Anchor; - const anchor1: Anchor = bridge.getAnchor(chainId1, anchorSize)! as Anchor; - let edgeIndex = await anchor2.contract.edgeIndex(chainId1); - const destAnchorEdge2Before = await anchor2.contract.edgeList(edgeIndex); - const token = await MintableToken.tokenFromAddress(existingToken2.contract.address, ganacheWallet2); - const startingBalanceDest = await token.getBalance(signers[2].address); - - // Make a deposit - const depositNote1 = await bridge.wrapAndDeposit(chainId2, existingToken1.contract.address, anchorSize, signers[1]); - - // Check the leaf index is incremented - const destAnchorEdge2After = await anchor2.contract.edgeList(edgeIndex); - assert.deepEqual(destAnchorEdge2Before.latestLeafIndex.add(1), destAnchorEdge2After.latestLeafIndex); - - // Check that the anchor has the appropriate amount of wrapped token balance - const wrappedTokenAddress = bridge.getWebbTokenAddress(chainId1); - const wrappedToken = await MintableToken.tokenFromAddress(wrappedTokenAddress!, signers[1]); - const anchorWrappedTokenBalance = await wrappedToken.getBalance(anchor1.contract.address); - assert.deepEqual(anchorWrappedTokenBalance, (ethers.BigNumber.from(anchorSize)).mul(2)); - - // Check that the anchor's token wrapper has the appropriate amount of token balance - const anchorTokenWrapper = await anchor1.contract.token(); - const anchorTokenWrapperBalance = await existingToken1.getBalance(anchorTokenWrapper); - assert.deepEqual(anchorTokenWrapperBalance, (ethers.BigNumber.from(anchorSize)).mul(2)); - - // Withdraw from the bridge - await bridge.withdrawAndUnwrap(depositNote1!, existingToken2.contract.address, anchorSize, signers[2].address, signers[2].address, ganacheWallet2); - - // Check the balance of the signer - const endingBalanceDest = await token.getBalance(signers[2].address); - assert.deepEqual(endingBalanceDest, startingBalanceDest.add(anchorSize)); - }) - - it('should withdraw on hardhat from ganache deposit', async () => { - // Fetch information about the anchor to be updated. - const signers = await ethers.getSigners(); - const anchorSize = '1000000000000000000'; - - const anchor1: Anchor = bridge.getAnchor(chainId1, anchorSize)! as Anchor; - let edgeIndex = await anchor1.contract.edgeIndex(chainId2); - const destAnchorEdge2Before = await anchor1.contract.edgeList(edgeIndex); - const token = await MintableToken.tokenFromAddress(existingToken1.contract.address, signers[1]); - const startingBalanceDest = await token.getBalance(signers[2].address); - - // Make a deposit - const depositNote1 = await bridge.wrapAndDeposit(chainId1, existingToken2.contract.address, anchorSize, ganacheWallet2); - - // Check the leaf index is incremented - const destAnchorEdge2After = await anchor1.contract.edgeList(edgeIndex); - assert.deepStrictEqual(destAnchorEdge2Before.latestLeafIndex.add(1), destAnchorEdge2After.latestLeafIndex); - - // Withdraw from the bridge - await bridge.withdrawAndUnwrap(depositNote1!, existingToken1.contract.address, anchorSize, signers[2].address, signers[2].address, signers[1]); - - // Check the balance of the signer - const endingBalanceDest = await token.getBalance(signers[2].address); - assert.deepStrictEqual(endingBalanceDest, startingBalanceDest.add(anchorSize)); - }) - - it('should update multiple deposits and withdraw historic deposit', async () => { - // Fetch information about the anchor to be updated. - const signers = await ethers.getSigners(); - const anchorSize = '1000000000000000000'; - - const anchor2: Anchor = bridge.getAnchor(chainId2, anchorSize)! as Anchor; - let edgeIndex = await anchor2.contract.edgeIndex(chainId1); - const destAnchorEdge2Before = await anchor2.contract.edgeList(edgeIndex); - const webbToken = await MintableToken.tokenFromAddress(existingToken2.contract.address, ganacheWallet2); - const startingBalanceDest = await webbToken.getBalance(signers[1].address); - - // Make two deposits - const depositNote1 = await bridge.wrapAndDeposit(chainId2, existingToken1.contract.address, anchorSize, signers[1]); - const depositNote2 = await bridge.wrapAndDeposit(chainId2, existingToken1.contract.address, anchorSize, signers[1]); - - // Check the leaf index is incremented by two - const destAnchorEdge2After = await anchor2.contract.edgeList(edgeIndex); - assert.deepStrictEqual(destAnchorEdge2Before.latestLeafIndex.add(2), destAnchorEdge2After.latestLeafIndex); - - // Withdraw from the bridge with older deposit note - await bridge.withdrawAndUnwrap(depositNote1!, existingToken2.contract.address, anchorSize, signers[1].address, signers[1].address, ganacheWallet2); - - // Check the balance of the other_signer. - const endingBalanceDest = await webbToken.getBalance(signers[1].address); - assert.deepStrictEqual(endingBalanceDest, startingBalanceDest.add(anchorSize)); - }); - - it('should update multiple deposits and withdraw historic deposit from ganache', async () => { - // Fetch information about the anchor to be updated. - const signers = await ethers.getSigners(); - const anchorSize = '1000000000000000000'; - - const anchor2: Anchor = bridge.getAnchor(chainId1, anchorSize)! as Anchor; - let edgeIndex = await anchor2.contract.edgeIndex(chainId2); - const destAnchorEdge2Before = await anchor2.contract.edgeList(edgeIndex); - const webbToken = await MintableToken.tokenFromAddress(existingToken1.contract.address, signers[1]); - const startingBalanceDest = await webbToken.getBalance(signers[1].address); - - // Make two deposits - const depositNote1 = await bridge.wrapAndDeposit(chainId1, existingToken2.contract.address, anchorSize, ganacheWallet2); - const depositNote2 = await bridge.wrapAndDeposit(chainId1, existingToken2.contract.address, anchorSize, ganacheWallet2); - - // Check the leaf index is incremented by two - const destAnchorEdge2After = await anchor2.contract.edgeList(edgeIndex); - assert.deepStrictEqual(destAnchorEdge2Before.latestLeafIndex.add(2), destAnchorEdge2After.latestLeafIndex); - - // Withdraw from the bridge with older deposit note - await bridge.withdrawAndUnwrap(depositNote1!, existingToken1.contract.address, anchorSize, signers[1].address, signers[1].address, signers[1]); - - // Check the balance of the other_signer. - const endingBalanceDest = await webbToken.getBalance(signers[1].address); - assert.deepStrictEqual(endingBalanceDest, startingBalanceDest.add(anchorSize)); - }); - }); - }); - - describe('4 sided bridge wrap/unwrap token use', () => { - // ERC20 compliant contracts that can easily create balances for test - let existingTokenSrc: MintableToken; - let existingTokenSrc2: MintableToken; - let existingTokenSrc3: MintableToken; - let existingTokenSrc4: MintableToken; - - let bridge: Bridge; - const chainId1 = 31337; - const chainId2 = 1337; - const chainId3 = 9999; - const chainId4 = 4444; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); - ganacheProvider2.pollingInterval = 1; - let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); - - let ganacheProvider3 = new ethers.providers.JsonRpcProvider('http://localhost:9999'); - ganacheProvider3.pollingInterval = 1; - let ganacheWallet3 = new ethers.Wallet('745ee040ef2b087f075dc7d314fa06797ed2ffd4ab59a4cc35c0a33e8d2b7791', ganacheProvider3); - - let ganacheProvider4 = new ethers.providers.JsonRpcProvider('http://localhost:4444'); - ganacheProvider4.pollingInterval = 1; - let ganacheWallet4 = new ethers.Wallet('d897ca733460ea2c7cda5150926ade4a40e6828bb1cb0d38f097102530b3ef42', ganacheProvider4); - - let calculateCumulativeBalance: (userAddress: string, tokenAddress: string, webbTokenAddress: string, signer: Signer) => Promise; - - before(async () => { - const signers = await ethers.getSigners(); - - existingTokenSrc = await MintableToken.createToken('existingERC20', 'EXIST', signers[7]); - existingTokenSrc2 = await MintableToken.createToken('existingERC20', 'EXIST', ganacheWallet2); - existingTokenSrc3 = await MintableToken.createToken('existingERC20', 'EXIST', ganacheWallet3); - existingTokenSrc4 = await MintableToken.createToken('existingERC20', 'EXIST', ganacheWallet4); - }) - - beforeEach(async () => { - const signers = await ethers.getSigners(); - - // create the config for the bridge - const existingTokenBridgeConfig: BridgeInput = { - anchorInputs: { - asset: { - [chainId1]: [existingTokenSrc.contract.address], - [chainId2]: [existingTokenSrc2.contract.address], - [chainId3]: [existingTokenSrc3.contract.address], - [chainId4]: [existingTokenSrc4.contract.address], - }, - anchorSizes: ['1000000000000000000', '100000000000000000000'], - }, - chainIDs: [chainId1, chainId2, chainId3, chainId4] - }; - - // setup the config for deployers of contracts (admins) - const deploymentConfig = { - [chainId1]: signers[1], - [chainId2]: ganacheWallet2, - [chainId3]: ganacheWallet3, - [chainId4]: ganacheWallet4, - } - - // deploy the bridge - bridge = await Bridge.deployFixedDepositBridge(existingTokenBridgeConfig, deploymentConfig, zkComponents4); - - // Should mint tokens for test purposes - await existingTokenSrc.mintTokens(signers[1].address, '100000000000000000000000'); - await existingTokenSrc2.mintTokens(ganacheWallet2.address, '100000000000000000000000'); - await existingTokenSrc3.mintTokens(ganacheWallet3.address, '100000000000000000000000'); - await existingTokenSrc4.mintTokens(ganacheWallet4.address, '100000000000000000000000'); - - // define the calculateCumulativeBalance - calculateCumulativeBalance = async (userAddress: string, tokenAddress: string, webbTokenAddress: string, signer: Signer) => { - const tokenBalance = await (await MintableToken.tokenFromAddress(tokenAddress, signer)).getBalance(userAddress); - const webbTokenBalance = await (await MintableToken.tokenFromAddress(webbTokenAddress, signer)).getBalance(userAddress); - const totalBalance = tokenBalance.add(webbTokenBalance); - return totalBalance; - } - }) - - it('should withdraw successfully from latest deposits on all chains', async () => { - const signers = await ethers.getSigners(); - - // make deposits so edges exists - await bridge.wrapAndDeposit(chainId2, existingTokenSrc.contract.address, '1000000000000000000', signers[1]); - await bridge.wrapAndDeposit(chainId3, existingTokenSrc2.contract.address, '1000000000000000000', ganacheWallet2); - await bridge.wrapAndDeposit(chainId4, existingTokenSrc3.contract.address, '1000000000000000000', ganacheWallet3); - await bridge.wrapAndDeposit(chainId1, existingTokenSrc4.contract.address, '1000000000000000000', ganacheWallet4); - - // Fetch information about the anchor to be updated. - const anchorSize = '1000000000000000000'; - const webbTokenAddress1 = bridge.getWebbTokenAddress(chainId1)!; - const tokenAddress1 = existingTokenSrc.contract.address; - - const anchor1: Anchor = bridge.getAnchor(chainId1, anchorSize)! as Anchor; - let edgeIndex = await anchor1.contract.edgeIndex(chainId1); - const destAnchorEdge1Before = await anchor1.contract.edgeList(edgeIndex); - let cumulativeBalance = await calculateCumulativeBalance(signers[1].address, tokenAddress1, webbTokenAddress1, signers[1]); - let currentBalance = cumulativeBalance; - - // Make a deposit on the second chain - const depositNote1 = await bridge.wrapAndDeposit(chainId1, existingTokenSrc2.contract.address, anchorSize, ganacheWallet2); - - // Check the leaf index is incremented - const destAnchorEdge1After = await anchor1.contract.edgeList(edgeIndex); - assert.deepStrictEqual(destAnchorEdge1Before.latestLeafIndex.add(1), destAnchorEdge1After.latestLeafIndex); - - // Withdraw from the first chain - await bridge.withdrawAndUnwrap(depositNote1!, existingTokenSrc.contract.address, anchorSize, signers[1].address, signers[1].address, signers[1]); - - // Check the balance of the signer - cumulativeBalance = await calculateCumulativeBalance(signers[1].address, tokenAddress1, webbTokenAddress1, signers[1]); - assert.deepStrictEqual(cumulativeBalance, currentBalance.add(anchorSize)); - currentBalance = cumulativeBalance; - - // make a deposit from the third connected chain - edgeIndex = await anchor1.contract.edgeIndex(chainId3); - const destAnchorEdge3Before = await anchor1.contract.edgeList(edgeIndex); - const depositNote3 = await bridge.wrapAndDeposit(chainId1, existingTokenSrc3.contract.address, anchorSize, ganacheWallet3); - - // Check the leaf index is incremented - const destAnchorEdge3After = await anchor1.contract.edgeList(edgeIndex); - assert.deepStrictEqual(destAnchorEdge3Before.latestLeafIndex.add(1), destAnchorEdge3After.latestLeafIndex); - - // Attempting to withdraw and unwrap should fail because this anchor side does not currently have - // enough ERC20 token balance - await TruffleAssert.reverts(bridge.withdrawAndUnwrap(depositNote3!, existingTokenSrc.contract.address, anchorSize, signers[1].address, signers[1].address, signers[1])); - await bridge.withdraw(depositNote3!, anchorSize, signers[1].address, signers[1].address, signers[1]); - - cumulativeBalance = await calculateCumulativeBalance(signers[1].address, tokenAddress1, webbTokenAddress1, signers[1]); - assert.deepStrictEqual(cumulativeBalance, currentBalance.add(anchorSize)); - currentBalance = cumulativeBalance; - - // make a deposit from the fourth connected chain - edgeIndex = await anchor1.contract.edgeIndex(chainId4); - const destAnchorEdge4Before = await anchor1.contract.edgeList(edgeIndex); - const depositNote4 = await bridge.wrapAndDeposit(chainId1, existingTokenSrc4.contract.address, anchorSize, ganacheWallet4); - - // Check the leaf index is incremented - const destAnchorEdge4After = await anchor1.contract.edgeList(edgeIndex); - assert.deepStrictEqual(destAnchorEdge4Before.latestLeafIndex.add(1), destAnchorEdge4After.latestLeafIndex); - - // Withdraw from the third connected chain - await bridge.withdraw(depositNote4!, anchorSize, signers[1].address, signers[1].address, signers[1]); - - // Check the balance of the signer - const endingBalanceAfterThreeWithdraw = await existingTokenSrc.getBalance(signers[1].address); - cumulativeBalance = await calculateCumulativeBalance(signers[1].address, tokenAddress1, webbTokenAddress1, signers[1]); - assert.deepStrictEqual(cumulativeBalance, currentBalance.add(anchorSize)); - currentBalance = cumulativeBalance; - }).timeout(60000); - }); - - after('terminate networks', async function () { - await ganacheServer2.close(); - await ganacheServer3.close(); - await ganacheServer4.close(); - }); -}); diff --git a/test/integration/historicalRootWithdraw.test.ts b/test/integration/historicalRootWithdraw.test.ts deleted file mode 100644 index c1f48b864..000000000 --- a/test/integration/historicalRootWithdraw.test.ts +++ /dev/null @@ -1,388 +0,0 @@ -import { artifacts, contract } from "hardhat"; -import { MerkleTree } from "@webb-tools/merkle-tree"; -const TruffleAssert = require('truffle-assertions'); -const Ethers = require('ethers'); -const helpers = require('../helpers'); -const { toBN } = require('web3-utils') -const assert = require('assert'); -const BridgeContract = artifacts.require('Bridge'); -const Anchor = artifacts.require('FixedDepositAnchor'); -const Hasher = artifacts.require('PoseidonT3'); -const Verifier = artifacts.require('Verifier'); -const Verifier2 = artifacts.require('Verifier2'); -const Verifier3 = artifacts.require('Verifier3'); -const Verifier4 = artifacts.require('Verifier4'); -const Verifier5 = artifacts.require('Verifier5'); -const Verifier6 = artifacts.require('Verifier6'); -const Token = artifacts.require('ERC20Mock'); -const AnchorHandlerContract = artifacts.require('AnchorHandler'); - -const fs = require('fs') -const path = require('path'); -const { NATIVE_AMOUNT } = process.env -let prefix = 'poseidon-test' -const snarkjs = require('snarkjs'); -const BN = require('bn.js'); -const F = require('circomlibjs').babyjub.F; -const Scalar = require('ffjavascript').Scalar; - -contract('E2E LinkableAnchors - Cross chain withdraw using historical root should work', async accounts => { - const relayerThreshold = 1; - // Note: we have to use the same chainID for tests since Hardhat can't simulate 2 networks - const originChainID = 31337; - const destChainID = 31337; - const relayer1Address = accounts[3]; - const operator = accounts[6]; - const initialTokenMintAmount = BigInt(1e25); - const tokenDenomination = '1000000000000000000000'; - const merkleTreeHeight = 30; - const sender = accounts[5]; - const fee = BigInt((new BN(`${NATIVE_AMOUNT}`).shrn(1)).toString()) || BigInt((new BN(`${1e17}`)).toString()); - const refund = BigInt((new BN('0')).toString()); - const recipient = helpers.getRandomRecipient(); - - let originMerkleRoot; - let originUpdateNonce; - let v2, v3, v4, v5, v6; - let hasher, verifier; - let originChainToken; - let destChainToken; - let originDeposit; - let tree; - let createWitness; - let OriginChainAnchorInstance; - let originUpdateData; - let originUpdateDataHash; - let resourceID; - let initialResourceIDs; - let DestBridgeInstance; - let DestChainAnchorInstance - let DestAnchorHandlerInstance; - let destInitialContractAddresses; - let proof, publicSignals; - const MAX_EDGES = 1; - - beforeEach(async () => { - await Promise.all([ - // instantiate bridges on dest chain side - BridgeContract.new(destChainID, [relayer1Address], relayerThreshold, 0, 100).then(instance => DestBridgeInstance = instance), - // create hasher, verifier, and tokens - Hasher.new().then(instance => hasher = instance), - Verifier2.new().then(instance => v2 = instance), - Verifier3.new().then(instance => v3 = instance), - Verifier4.new().then(instance => v4 = instance), - Verifier5.new().then(instance => v5 = instance), - Verifier6.new().then(instance => v6 = instance), - Token.new().then(instance => originChainToken = instance), - Token.new().then(instance => destChainToken = instance), - ]); - verifier = await Verifier.new( - v2.address, - v3.address, - v4.address, - v5.address, - v6.address - ); - - // initialize anchors on both chains - OriginChainAnchorInstance = await Anchor.new( - sender, - originChainToken.address, - verifier.address, - hasher.address, - tokenDenomination, - merkleTreeHeight, - MAX_EDGES, - { from: sender }); - DestChainAnchorInstance = await Anchor.new( - sender, - destChainToken.address, - verifier.address, - hasher.address, - tokenDenomination, - merkleTreeHeight, - MAX_EDGES, - { from: sender }); - // create resource ID using anchor address - resourceID = helpers.createResourceID(OriginChainAnchorInstance.address, 0); - initialResourceIDs = [resourceID]; - destInitialContractAddresses = [OriginChainAnchorInstance.address]; - // initialize anchorHanders - await Promise.all([ - AnchorHandlerContract.new(DestBridgeInstance.address, initialResourceIDs, destInitialContractAddresses) - .then(instance => DestAnchorHandlerInstance = instance), - ]); - // increase allowance and set resources for bridge - await DestBridgeInstance.adminSetResource(DestAnchorHandlerInstance.address, resourceID, DestChainAnchorInstance.address) - // set bridge and handler permissions for anchor - await Promise.all([ - DestChainAnchorInstance.setHandler(DestAnchorHandlerInstance.address, await DestChainAnchorInstance.getProposalNonce() + 1, { from: sender }), - ]); - - createWitness = async (data) => { - const witnessCalculator = require("../../protocol-solidity-fixtures/fixtures/bridge/2/witness_calculator.js"); - const fileBuf = require('fs').readFileSync('./protocol-solidity-fixtures/fixtures/bridge/2/poseidon_bridge_2.wasm'); - const wtnsCalc = await witnessCalculator(fileBuf) - const wtns = await wtnsCalc.calculateWTNSBin(data,0); - return wtns; - } - - tree = new MerkleTree(merkleTreeHeight) - }); - - it('[sanity] dest chain bridge configured with threshold and relayers', async () => { - assert.equal(await DestBridgeInstance._chainID(), destChainID) - assert.equal(await DestBridgeInstance._relayerThreshold(), relayerThreshold) - assert.equal((await DestBridgeInstance._totalRelayers()).toString(), '1') - }) - - it('withdrawing across bridge after two deposits should work', async () => { - /* - * sender deposits on origin chain anchor - */ - // minting Tokens - await originChainToken.mint(sender, initialTokenMintAmount); - //increase allowance - originChainToken.approve(OriginChainAnchorInstance.address, initialTokenMintAmount, { from: sender }); - // deposit on both chains and define nonces based on events emmited - let firstOriginDeposit = helpers.generateDeposit(destChainID); - let { logs } = await OriginChainAnchorInstance.deposit( - helpers.toFixedHex(firstOriginDeposit.commitment), { from: sender }); - let latestLeafIndex = logs[0].args.leafIndex; - originUpdateNonce = latestLeafIndex; - const firstWithdrawlMerkleRoot = await OriginChainAnchorInstance.getLastRoot(); - // create correct update proposal data for the deposit on origin chain - originUpdateData = helpers.createUpdateProposalData(originChainID, latestLeafIndex, firstWithdrawlMerkleRoot, DestChainAnchorInstance.address, destChainID); - originUpdateDataHash = Ethers.utils.keccak256(DestAnchorHandlerInstance.address + originUpdateData.substr(2)); - - // deposit on origin chain leads to update addEdge proposal on dest chain - // relayer1 creates the deposit proposal for the deposit that occured in the before each loop - await TruffleAssert.passes(DestBridgeInstance.voteProposal( - originChainID, - originUpdateNonce, - resourceID, - originUpdateDataHash, - { from: relayer1Address } - )); - // relayer1 will execute the deposit proposal - await TruffleAssert.passes(DestBridgeInstance.executeProposal( - originChainID, - originUpdateNonce, - originUpdateData, - resourceID, - { from: relayer1Address } - )); - - /* - * sender generate proof - */ - // insert two commitments into the tree - await tree.insert(firstOriginDeposit.commitment); - - let { pathElements, pathIndices } = await tree.path(0); - - const destNativeRoot = await DestChainAnchorInstance.getLastRoot(); - const firstWithdrawalNeighborRoots = await DestChainAnchorInstance.getLatestNeighborRoots(); - let input = { - // public - nullifierHash: firstOriginDeposit.nullifierHash, - refreshCommitment: 0, - recipient, - relayer: operator, - fee, - refund, - chainID: firstOriginDeposit.chainID, - roots: [destNativeRoot, ...firstWithdrawalNeighborRoots], - // private - nullifier: firstOriginDeposit.nullifier, - secret: firstOriginDeposit.secret, - pathElements, - pathIndices, - diffs: [destNativeRoot, firstWithdrawalNeighborRoots[0]].map(r => { - return F.sub( - Scalar.fromString(`${r}`), - Scalar.fromString(`${firstWithdrawalNeighborRoots[0]}`), - ).toString(); - }), - }; - - let wtns = await createWitness(input); - - let res = await snarkjs.groth16.prove('protocol-solidity-fixtures/fixtures/bridge/2/circuit_final.zkey', wtns); - proof = res.proof; - publicSignals = res.publicSignals; - - // Uncomment to measure gas usage - // gas = await anchor.withdraw.estimateGas(proof, publicSignals, { from: relayer, gasPrice: '100' }) - // console.log('withdraw gas:', gas) - let args = [ - helpers.createRootsBytes(input.roots), - helpers.toFixedHex(input.nullifierHash), - helpers.toFixedHex(input.refreshCommitment), - helpers.toFixedHex(input.recipient, 20), - helpers.toFixedHex(input.relayer, 20), - helpers.toFixedHex(input.fee), - helpers.toFixedHex(input.refund), - ]; - - let proofEncoded = await helpers.generateWithdrawProofCallData(proof, publicSignals); - /* - * sender's second deposit on origin chain anchor - */ - // deposit on origin chain and define nonce based on events emmited - originDeposit = helpers.generateDeposit(destChainID, 30); - ({ logs } = await OriginChainAnchorInstance.deposit(helpers.toFixedHex(originDeposit.commitment), { from: sender })); - latestLeafIndex = logs[0].args.leafIndex; - originUpdateNonce = latestLeafIndex; - const secondWithdrawalMerkleRoot = await OriginChainAnchorInstance.getLastRoot(); - // create correct update proposal data for the deposit on origin chain - originUpdateData = helpers.createUpdateProposalData(originChainID, latestLeafIndex, secondWithdrawalMerkleRoot, DestChainAnchorInstance.address, destChainID); - originUpdateDataHash = Ethers.utils.keccak256(DestAnchorHandlerInstance.address + originUpdateData.substr(2)); - /* - * Relayers vote on dest chain - */ - // a second deposit on origin chain leads to update edge proposal on dest chain - // relayer1 creates the deposit proposal for the deposit that occured in the before each loop - await TruffleAssert.passes(DestBridgeInstance.voteProposal( - originChainID, - originUpdateNonce, - resourceID, - originUpdateDataHash, - { from: relayer1Address } - )); - // relayer1 will execute the deposit proposal - await TruffleAssert.passes(DestBridgeInstance.executeProposal( - originChainID, - originUpdateNonce, - originUpdateData, - resourceID, - { from: relayer1Address } - )); - // check initial balances before withdrawal - let balanceOperatorBefore = await destChainToken.balanceOf(operator); - let balanceReceiverBefore = await destChainToken.balanceOf(helpers.toFixedHex(recipient, 20)); - /* - * sender withdraws using first commitment - */ - // mint to anchor and track balance - await destChainToken.mint(DestChainAnchorInstance.address, initialTokenMintAmount); - let balanceDestAnchorAfterDeposits = await destChainToken.balanceOf(DestChainAnchorInstance.address); - // withdraw - ({ logs } = await DestChainAnchorInstance.withdraw(`0x${proofEncoded}`, { - _roots: args[0], - _nullifierHash: args[1], - _refreshCommitment: args[2], - _recipient: args[3], - _relayer: args[4], - _fee: args[5], - _refund: args[6], - }, { from: input.relayer })); - - let balanceDestAnchorAfter = await destChainToken.balanceOf(DestChainAnchorInstance.address); - let balanceOperatorAfter = await destChainToken.balanceOf(input.relayer); - let balanceReceiverAfter = await destChainToken.balanceOf(helpers.toFixedHex(recipient, 20)); - const feeBN = toBN(fee.toString()) - assert.strictEqual(balanceDestAnchorAfter.toString(), balanceDestAnchorAfterDeposits.sub(toBN(tokenDenomination)).toString()); - assert.strictEqual(balanceOperatorAfter.toString(), balanceOperatorBefore.add(feeBN).toString()); - assert.strictEqual(balanceReceiverAfter.toString(), balanceReceiverBefore.add(toBN(tokenDenomination)).sub(feeBN).toString()); - const isSpent = await DestChainAnchorInstance.isSpent(helpers.toFixedHex(input.nullifierHash)); - assert(isSpent); - /* - * generate proof for second deposit - */ - // insert second deposit in tree and get path for withdrawal proof - await tree.insert(originDeposit.commitment); - let root; - let result = await tree.path(1); - ({ root, pathElements, pathIndices } = result); - const secondWithdrawalNeighborRoots = await DestChainAnchorInstance.getLatestNeighborRoots(); - input = { - // public - nullifierHash: originDeposit.nullifierHash, - refreshCommitment: 0, - recipient, - relayer: operator, - fee, - refund, - chainID: originDeposit.chainID, - roots: [destNativeRoot, ...secondWithdrawalNeighborRoots], - // private - nullifier: originDeposit.nullifier, - secret: originDeposit.secret, - pathElements, - pathIndices, - diffs: [destNativeRoot, secondWithdrawalNeighborRoots[0]].map(r => { - return F.sub( - Scalar.fromString(`${r}`), - Scalar.fromString(`${secondWithdrawalNeighborRoots[0]}`), - ).toString(); - }), - }; - - wtns = await createWitness(input); - - res = await snarkjs.groth16.prove('protocol-solidity-fixtures/fixtures/bridge/2/circuit_final.zkey', wtns); - proof = res.proof; - publicSignals = res.publicSignals; - const vKey = await snarkjs.zKey.exportVerificationKey('protocol-solidity-fixtures/fixtures/bridge/2/circuit_final.zkey'); - res = await snarkjs.groth16.verify(vKey, publicSignals, proof); - assert.strictEqual(res, true); - - args = [ - helpers.createRootsBytes(input.roots), - helpers.toFixedHex(input.nullifierHash), - helpers.toFixedHex(input.refreshCommitment), - helpers.toFixedHex(input.recipient, 20), - helpers.toFixedHex(input.relayer, 20), - helpers.toFixedHex(input.fee), - helpers.toFixedHex(input.refund), - ]; - - proofEncoded = await helpers.generateWithdrawProofCallData(proof, publicSignals); - /* - * create 30 new deposits on chain so history wraps around and forgets second deposit - */ - for (var i = 0; i < 30; i++) { - // deposit on origin chain and define nonce based on events emmited - originDeposit = helpers.generateDeposit(destChainID, i); - ({ logs } = await OriginChainAnchorInstance.deposit(helpers.toFixedHex(originDeposit.commitment), { from: sender })); - latestLeafIndex = logs[0].args.leafIndex; - originUpdateNonce = latestLeafIndex; - originMerkleRoot = await OriginChainAnchorInstance.getLastRoot(); - // create correct update proposal data for the deposit on origin chain - originUpdateData = helpers.createUpdateProposalData(originChainID, latestLeafIndex, originMerkleRoot, DestChainAnchorInstance.address, destChainID); - originUpdateDataHash = Ethers.utils.keccak256(DestAnchorHandlerInstance.address + originUpdateData.substr(2)); - /* - * Relayers vote on dest chain - */ - // relayer1 creates the deposit proposal for the deposit that occured in the before each loop - await TruffleAssert.passes(DestBridgeInstance.voteProposal( - originChainID, - originUpdateNonce, - resourceID, - originUpdateDataHash, - { from: relayer1Address } - )); - // relayer1 will execute the deposit proposal - await TruffleAssert.passes(DestBridgeInstance.executeProposal( - originChainID, - originUpdateNonce, - originUpdateData, - resourceID, - { from: relayer1Address } - )); - } - - // withdraw should revert as historical root does not exist - await TruffleAssert.reverts(DestChainAnchorInstance.withdraw(`0x${proofEncoded}`, { - _roots: args[0], - _nullifierHash: args[1], - _refreshCommitment: args[2], - _recipient: args[3], - _relayer: args[4], - _fee: args[5], - _refund: args[6], - }, { from: input.relayer }), - 'Neighbor root not found'); - }).timeout(0); -}) diff --git a/test/integration/simpleWithdrawals.test.ts b/test/integration/simpleWithdrawals.test.ts deleted file mode 100644 index c15462ffe..000000000 --- a/test/integration/simpleWithdrawals.test.ts +++ /dev/null @@ -1,391 +0,0 @@ -import { artifacts, contract } from "hardhat"; -import { MerkleTree } from "@webb-tools/merkle-tree"; -const TruffleAssert = require('truffle-assertions'); -const Ethers = require('ethers'); -const helpers = require('../helpers'); -const { toBN } = require('web3-utils') -const assert = require('assert'); -const BridgeContract = artifacts.require('Bridge'); -const Anchor = artifacts.require('FixedDepositAnchor'); -const Hasher = artifacts.require('PoseidonT3'); -const Verifier = artifacts.require('Verifier'); -const Verifier2 = artifacts.require('Verifier2'); -const Verifier3 = artifacts.require('Verifier3'); -const Verifier4 = artifacts.require('Verifier4'); -const Verifier5 = artifacts.require('Verifier5'); -const Verifier6 = artifacts.require('Verifier6'); -const Token = artifacts.require('ERC20Mock'); -const AnchorHandlerContract = artifacts.require('AnchorHandler'); - -const fs = require('fs') -const path = require('path'); -const { NATIVE_AMOUNT } = process.env -let prefix = 'poseidon-test' -const snarkjs = require('snarkjs'); -const BN = require('bn.js'); -const F = require('circomlibjs').babyjub.F; -const Scalar = require('ffjavascript').Scalar; - -contract('E2E LinkableAnchors - Simple cross chain withdrawals', async accounts => { - const relayerThreshold = 1; - // Note: we have to use the same chainID for tests since Hardhat can't simulate 2 networks - const originChainID = 31337; - const destChainID = 31337; - const relayer1Address = accounts[3]; - const operator = accounts[6]; - const initialTokenMintAmount = BigInt(1e25); - const tokenDenomination = '1000000000000000000000'; - const maxRoots = 1; - const merkleTreeHeight = 30; - const sender = accounts[5]; - const fee = BigInt((new BN(`${NATIVE_AMOUNT}`).shrn(1)).toString()) || BigInt((new BN(`${1e17}`)).toString()); - const refund = BigInt((new BN('0')).toString()); - const recipient = helpers.getRandomRecipient(); - - let originMerkleRoot; - let destMerkleRoot; - let originUpdateNonce; - let destUpdateNonce; - let v2, v3, v4, v5, v6; - let hasher, verifier; - let originChainToken; - let destChainToken; - let originDeposit; - let destDeposit; - let tree; - let createWitness; - let OriginBridgeInstance; - let OriginChainAnchorInstance; - let OriginAnchorHandlerInstance; - let originUpdateData; - let originUpdateDataHash; - let resourceID; - let initialResourceIDs; - let originInitialContractAddresses; - let DestBridgeInstance; - let DestChainAnchorInstance - let DestAnchorHandlerInstance; - let destUpdateData; - let destUpdateDataHash; - let destInitialContractAddresses; - let proof, publicSignals; - const MAX_EDGES = 1; - - beforeEach(async () => { - await Promise.all([ - // instantiate bridges on both sides - BridgeContract.new(originChainID, [relayer1Address], relayerThreshold, 0, 100).then(instance => OriginBridgeInstance = instance), - BridgeContract.new(destChainID, [relayer1Address], relayerThreshold, 0, 100).then(instance => DestBridgeInstance = instance), - // create hasher, verifier, and tokens - Hasher.new().then(instance => hasher = instance), - Verifier2.new().then(instance => v2 = instance), - Verifier3.new().then(instance => v3 = instance), - Verifier4.new().then(instance => v4 = instance), - Verifier5.new().then(instance => v5 = instance), - Verifier6.new().then(instance => v6 = instance), - Token.new().then(instance => originChainToken = instance), - Token.new().then(instance => destChainToken = instance), - ]); - verifier = await Verifier.new( - v2.address, - v3.address, - v4.address, - v5.address, - v6.address - ); - - // initialize anchors on both chains - OriginChainAnchorInstance = await Anchor.new( - sender, - originChainToken.address, - verifier.address, - hasher.address, - tokenDenomination, - merkleTreeHeight, - MAX_EDGES, - { from: sender }); - DestChainAnchorInstance = await Anchor.new( - sender, - destChainToken.address, - verifier.address, - hasher.address, - tokenDenomination, - merkleTreeHeight, - MAX_EDGES, - { from: sender }); - // create resource ID using anchor address - resourceID = helpers.createResourceID(OriginChainAnchorInstance.address, 0); - initialResourceIDs = [resourceID]; - originInitialContractAddresses = [DestChainAnchorInstance.address]; - destInitialContractAddresses = [OriginChainAnchorInstance.address]; - // initialize anchorHanders - await Promise.all([ - AnchorHandlerContract.new(OriginBridgeInstance.address, initialResourceIDs, originInitialContractAddresses) - .then(instance => OriginAnchorHandlerInstance = instance), - AnchorHandlerContract.new(DestBridgeInstance.address, initialResourceIDs, destInitialContractAddresses) - .then(instance => DestAnchorHandlerInstance = instance), - ]); - // increase allowance and set resources for bridge - await Promise.all([ - OriginBridgeInstance.adminSetResource(OriginAnchorHandlerInstance.address, resourceID, OriginChainAnchorInstance.address), - DestBridgeInstance.adminSetResource(DestAnchorHandlerInstance.address, resourceID, DestChainAnchorInstance.address) - ]); - // set bridge and handler permissions for anchors - await Promise.all([ - OriginChainAnchorInstance.setHandler(OriginAnchorHandlerInstance.address, await OriginChainAnchorInstance.getProposalNonce() + 1, {from: sender}), - DestChainAnchorInstance.setHandler(DestAnchorHandlerInstance.address, await DestChainAnchorInstance.getProposalNonce() + 1, {from: sender}), - ]); - - createWitness = async (data) => { - const witnessCalculator = require("../../protocol-solidity-fixtures/fixtures/bridge/2/witness_calculator.js"); - const fileBuf = require('fs').readFileSync('./protocol-solidity-fixtures/fixtures/bridge/2/poseidon_bridge_2.wasm'); - const wtnsCalc = await witnessCalculator(fileBuf) - const wtns = await wtnsCalc.calculateWTNSBin(data,0); - return wtns; - } - - tree = new MerkleTree(merkleTreeHeight) - }); - - it('[sanity] bridges configured with threshold and relayers', async () => { - assert.equal(await OriginBridgeInstance._chainID(), originChainID); - assert.equal(await OriginBridgeInstance._relayerThreshold(), relayerThreshold) - assert.equal((await OriginBridgeInstance._totalRelayers()).toString(), '1') - assert.equal(await DestBridgeInstance._chainID(), destChainID) - assert.equal(await DestBridgeInstance._relayerThreshold(), relayerThreshold) - assert.equal((await DestBridgeInstance._totalRelayers()).toString(), '1') - }) - - it('withdrawals on both chains integration', async () => { - /* - * sender deposits on origin chain - */ - // minting Tokens - await originChainToken.mint(sender, initialTokenMintAmount); - // increasing allowance of anchors - await originChainToken.approve(OriginChainAnchorInstance.address, initialTokenMintAmount, { from: sender }); - // generate deposit commitment targeting withdrawal on destination chain - originDeposit = helpers.generateDeposit(destChainID); - // deposit on origin chain and define nonce - let { logs } = await OriginChainAnchorInstance.deposit(helpers.toFixedHex(originDeposit.commitment), { from: sender }); - let latestLeafIndex = logs[0].args.leafIndex; - originUpdateNonce = latestLeafIndex; - originMerkleRoot = await OriginChainAnchorInstance.getLastRoot(); - // create correct update proposal data for the deposit on origin chain - originUpdateData = helpers.createUpdateProposalData(originChainID, latestLeafIndex, originMerkleRoot, DestChainAnchorInstance.address, destChainID); - originUpdateDataHash = Ethers.utils.keccak256(DestAnchorHandlerInstance.address + originUpdateData.substr(2)); - /* - * Relayers vote on dest chain - */ - // deposit on origin chain leads to update proposal on dest chain - // relayer1 creates the deposit proposal for the deposit - await TruffleAssert.passes(DestBridgeInstance.voteProposal( - originChainID, - originUpdateNonce, - resourceID, - originUpdateDataHash, - { from: relayer1Address } - )); - // relayer1 will execute the deposit proposal - await TruffleAssert.passes(DestBridgeInstance.executeProposal( - originChainID, - originUpdateNonce, - originUpdateData, - resourceID, - { from: relayer1Address } - )); - - // check initial balances before withdrawal - let balanceOperatorBefore = await destChainToken.balanceOf(operator); - let balanceReceiverBefore = await destChainToken.balanceOf(helpers.toFixedHex(recipient, 20)); - /* - * sender generates proof - */ - const destNeighborRoots = await DestChainAnchorInstance.getLatestNeighborRoots(); - await tree.insert(originDeposit.commitment); - - let { pathElements, pathIndices } = await tree.path(0); - const destNativeRoot = await DestChainAnchorInstance.getLastRoot(); - let input = { - // public - nullifierHash: originDeposit.nullifierHash, - refreshCommitment: 0, - recipient, - relayer: operator, - fee, - refund, - chainID: originDeposit.chainID, - roots: [destNativeRoot, ...destNeighborRoots], - // private - nullifier: originDeposit.nullifier, - secret: originDeposit.secret, - pathElements, - pathIndices, - diffs: [destNativeRoot, ...destNeighborRoots].map(r => { - return F.sub( - Scalar.fromString(`${r}`), - Scalar.fromString(`${destNeighborRoots[0]}`), - ).toString(); - }), - }; - - let wtns = await createWitness(input); - - let res = await snarkjs.groth16.prove('protocol-solidity-fixtures/fixtures/bridge/2/circuit_final.zkey', wtns); - proof = res.proof; - publicSignals = res.publicSignals; - - let args = [ - helpers.createRootsBytes(input.roots), - helpers.toFixedHex(input.nullifierHash), - helpers.toFixedHex(input.refreshCommitment), - helpers.toFixedHex(input.recipient, 20), - helpers.toFixedHex(input.relayer, 20), - helpers.toFixedHex(input.fee), - helpers.toFixedHex(input.refund), - ]; - - let proofEncoded = await helpers.generateWithdrawProofCallData(proof, publicSignals); - /* - * sender withdraws on dest chain - */ - await destChainToken.mint(DestChainAnchorInstance.address, initialTokenMintAmount); - let balanceDestAnchorAfterDeposit = await destChainToken.balanceOf(DestChainAnchorInstance.address); - ({ logs } = await DestChainAnchorInstance.withdraw(`0x${proofEncoded}`, { - _roots: args[0], - _nullifierHash: args[1], - _refreshCommitment: args[2], - _recipient: args[3], - _relayer: args[4], - _fee: args[5], - _refund: args[6], - }, { from: input.relayer })); - - let balanceDestAnchorAfter = await destChainToken.balanceOf(DestChainAnchorInstance.address); - let balanceOperatorAfter = await destChainToken.balanceOf(input.relayer); - let balanceReceiverAfter = await destChainToken.balanceOf(helpers.toFixedHex(recipient, 20)); - const feeBN = toBN(fee.toString()) - assert.strictEqual(balanceDestAnchorAfter.toString(), balanceDestAnchorAfterDeposit.sub(toBN(tokenDenomination)).toString()); - assert.strictEqual(balanceOperatorAfter.toString(), balanceOperatorBefore.add(feeBN).toString()); - assert.strictEqual(balanceReceiverAfter.toString(), balanceReceiverBefore.add(toBN(tokenDenomination)).sub(feeBN).toString()); - - let isSpent = await DestChainAnchorInstance.isSpent(helpers.toFixedHex(input.nullifierHash)); - assert(isSpent); - /* - * sender deposit on dest chain - */ - // minting Tokens - await destChainToken.mint(sender, initialTokenMintAmount); - // approval - await destChainToken.approve(DestChainAnchorInstance.address, initialTokenMintAmount, { from: sender }), - // generate deposit commitment - destDeposit = helpers.generateDeposit(originChainID); - // deposit on dest chain and define nonce - ({ logs } = await DestChainAnchorInstance.deposit(helpers.toFixedHex(destDeposit.commitment), {from: sender})); - latestLeafIndex = logs[0].args.leafIndex; - destUpdateNonce = latestLeafIndex; - destMerkleRoot = await DestChainAnchorInstance.getLastRoot(); - // create correct update proposal data for the deposit on dest chain - destUpdateData = helpers.createUpdateProposalData(destChainID, latestLeafIndex, destMerkleRoot, OriginChainAnchorInstance.address, originChainID); - destUpdateDataHash = Ethers.utils.keccak256(OriginAnchorHandlerInstance.address + destUpdateData.substr(2)); - /* - * relayers vote on origin chain - */ - // deposit on dest chain leads to update proposal on origin chain - // relayer1 creates the deposit proposal - await TruffleAssert.passes(OriginBridgeInstance.voteProposal( - destChainID, - destUpdateNonce, - resourceID, - destUpdateDataHash, - { from: relayer1Address } - )); - // relayer1 will execute the update proposal - await TruffleAssert.passes(OriginBridgeInstance.executeProposal( - destChainID, - destUpdateNonce, - destUpdateData, - resourceID, - { from: relayer1Address } - )); - const originNeighborRoots = await OriginChainAnchorInstance.getLatestNeighborRoots(); - assert.strictEqual(originNeighborRoots.length, maxRoots); - assert.strictEqual(originNeighborRoots[0], destMerkleRoot); - // check initial balances - balanceOperatorBefore = await originChainToken.balanceOf(operator); - balanceReceiverBefore = await originChainToken.balanceOf(helpers.toFixedHex(recipient, 20)); - /* - * sender generates proof - */ - tree = new MerkleTree(merkleTreeHeight) - await tree.insert(destDeposit.commitment); - let merkleRoot; - ({ merkleRoot, pathElements, pathIndices } = await tree.path(0)); - const originNativeRoot = await OriginChainAnchorInstance.getLastRoot(); - input = { - // public - nullifierHash: destDeposit.nullifierHash, - refreshCommitment: 0, - recipient, - relayer: operator, - fee, - refund, - chainID: destDeposit.chainID, - roots: [originNativeRoot, ...originNeighborRoots], - // private - nullifier: destDeposit.nullifier, - secret: destDeposit.secret, - pathElements, - pathIndices, - diffs: [originNativeRoot, originNeighborRoots[0]].map(r => { - return F.sub( - Scalar.fromString(`${r}`), - Scalar.fromString(`${originNeighborRoots[0]}`), - ).toString(); - }), - }; - - wtns = await createWitness(input); - - res = await snarkjs.groth16.prove('protocol-solidity-fixtures/fixtures/bridge/2/circuit_final.zkey', wtns); - proof = res.proof; - publicSignals = res.publicSignals; - - args = [ - helpers.createRootsBytes(input.roots), - helpers.toFixedHex(input.nullifierHash), - helpers.toFixedHex(input.refreshCommitment), - helpers.toFixedHex(input.recipient, 20), - helpers.toFixedHex(input.relayer, 20), - helpers.toFixedHex(input.fee), - helpers.toFixedHex(input.refund), - ]; - - proofEncoded = await helpers.generateWithdrawProofCallData(proof, publicSignals); - /* - * sender withdraws on origin chain - */ - await originChainToken.mint(OriginChainAnchorInstance.address, initialTokenMintAmount); - let balanceOriginAnchorAfterDeposit = await originChainToken.balanceOf(OriginChainAnchorInstance.address); - ({ logs } = await OriginChainAnchorInstance.withdraw(`0x${proofEncoded}`, { - _roots: args[0], - _nullifierHash: args[1], - _refreshCommitment: args[2], - _recipient: args[3], - _relayer: args[4], - _fee: args[5], - _refund: args[6], - }, { from: input.relayer })); - - let balanceOriginAnchorAfter = await originChainToken.balanceOf(OriginChainAnchorInstance.address); - balanceOperatorAfter = await originChainToken.balanceOf(input.relayer); - balanceReceiverAfter = await originChainToken.balanceOf(helpers.toFixedHex(recipient, 20)); - - assert.strictEqual(balanceOriginAnchorAfter.toString(), balanceOriginAnchorAfterDeposit.sub(toBN(tokenDenomination)).toString()); - assert.strictEqual(balanceOperatorAfter.toString(), balanceOperatorBefore.add(feeBN).toString()); - assert.strictEqual(balanceReceiverAfter.toString(), balanceReceiverBefore.add(toBN(tokenDenomination)).sub(feeBN).toString()); - isSpent = await OriginChainAnchorInstance.isSpent(helpers.toFixedHex(input.nullifierHash)); - assert(isSpent); - }) -}) - diff --git a/test/vbridge/signatureVBridge.test.ts b/test/vbridge/signatureVBridge.test.ts index 85e287c4c..378168413 100644 --- a/test/vbridge/signatureVBridge.test.ts +++ b/test/vbridge/signatureVBridge.test.ts @@ -78,7 +78,7 @@ describe('multichain tests for signature vbridge', () => { 31337: signers[1], 1337: ganacheWallet2, }; - const vBridge = await VBridge.deployVariableAnchorBridge(bridge2WebbEthInput, deploymentConfig, false); + const vBridge = await VBridge.deployVariableAnchorBridge(bridge2WebbEthInput, deploymentConfig); // Should be able to retrieve individual anchors const chainId1 = 31337; const chainId2 = 1337; @@ -164,7 +164,7 @@ describe('multichain tests for signature vbridge', () => { } // deploy the bridge - vBridge = await VBridge.deployVariableAnchorBridge(vBridgeInput, deploymentConfig, false); + vBridge = await VBridge.deployVariableAnchorBridge(vBridgeInput, deploymentConfig); // make one deposit so the edge exists const depositUtxo1 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId2)}) @@ -382,7 +382,7 @@ describe('multichain tests for signature vbridge', () => { // deploy the bridge - vBridge = await VBridge.deployVariableAnchorBridge(vBridgeInput, deploymentConfig, false); + vBridge = await VBridge.deployVariableAnchorBridge(vBridgeInput, deploymentConfig); // make one deposit so the edge exists const depositUtxo1 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId2)}); diff --git a/test/vbridge/vbridge.test.ts b/test/vbridge/vbridge.test.ts deleted file mode 100644 index 7ae494ed1..000000000 --- a/test/vbridge/vbridge.test.ts +++ /dev/null @@ -1,516 +0,0 @@ -/** - * Copyright 2021 Webb Technologies - * SPDX-License-Identifier: GPL-3.0-or-later - */ -const TruffleAssert = require('truffle-assertions'); -const assert = require('assert'); -import { ethers } from 'hardhat'; - -// Convenience wrapper classes for contract classes -import { VBridge, VBridgeInput } from '@webb-tools/vbridge'; -import { VAnchor } from '@webb-tools/anchors'; -import { MintableToken, GovernedTokenWrapper } from '@webb-tools/tokens'; -import { BigNumber } from 'ethers'; -import { Utxo } from '@webb-tools/utils'; -import { startGanacheServer } from '../helpers/startGanacheServer'; - -export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); - -describe('multichain tests for vbridge', () => { - - // setup ganache networks - let ganacheServer2: any; - let ganacheServer3: any; - let ganacheServer4: any; - - before('setup networks', async () => { - ganacheServer2 = await startGanacheServer(1337, 1337, 'congress island collect purity dentist team gas unlock nuclear pig combine sight'); - ganacheServer3 = await startGanacheServer(9999, 9999, 'aspect biology suit thought bottom popular custom rebuild recall sauce endless local'); - ganacheServer4 = await startGanacheServer(4444, 4444, 'harvest useful giraffe swim rail ostrich public awful provide amazing tank weapon'); - await sleep(2000); - }); - - describe('BridgeConstruction', () => { - let bridge2WebbEthInput: VBridgeInput; - let bridge3WebbEthInput: VBridgeInput; - let tokenName: string = 'existingERC20'; - let tokenAbbreviation: string = 'EXIST'; - let tokenInstance1: MintableToken; - let tokenInstance2: MintableToken; - let tokenInstance3: MintableToken; - - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); - ganacheProvider2.pollingInterval = 1; - let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); - let ganacheProvider3 = new ethers.providers.JsonRpcProvider('http://localhost:9999'); - ganacheProvider3.pollingInterval = 1; - let ganacheWallet3 = new ethers.Wallet('745ee040ef2b087f075dc7d314fa06797ed2ffd4ab59a4cc35c0a33e8d2b7791', ganacheProvider3); - - before('construction-tests', async () => { - const signers = await ethers.getSigners(); - - // Create a token to test bridge construction support for existing tokens - tokenInstance1 = await MintableToken.createToken(tokenName, tokenAbbreviation, signers[7]); - tokenInstance2 = await MintableToken.createToken(tokenName, tokenAbbreviation, ganacheWallet2); - tokenInstance3 = await MintableToken.createToken(tokenName, tokenAbbreviation, ganacheWallet3); - - await tokenInstance1.mintTokens(signers[2].address, '100000000000000000000000000'); - }); - - it('create 2 side bridge for one token', async () => { - let webbTokens1 = new Map(); - webbTokens1.set(31337, null!); - webbTokens1.set(1337, null!); - bridge2WebbEthInput = { - vAnchorInputs: { - asset: { - 31337: [tokenInstance1.contract.address], - 1337: [tokenInstance2.contract.address], - } - }, - chainIDs: [31337, 1337], - webbTokens: webbTokens1 - }; - const signers = await ethers.getSigners(); - - const deploymentConfig = { - 31337: signers[1], - 1337: ganacheWallet2, - }; - const vBridge = await VBridge.deployVariableAnchorBridge(bridge2WebbEthInput, deploymentConfig, true); - // Should be able to retrieve individual anchors - const chainId1 = 31337; - const chainId2 = 1337; - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; - const vAnchor2: VAnchor = vBridge.getVAnchor(chainId2)! as VAnchor; - // Should be able to retrieve the token address (so we can mint tokens for test scenario) - const webbTokenAddress = vBridge.getWebbTokenAddress(chainId1); - const webbToken = await MintableToken.tokenFromAddress(webbTokenAddress!, signers[1]); - const tx = await webbToken.mintTokens(signers[2].address, '100000000000000000000000'); - // get the state of anchors before deposit - const sourceAnchorRootBefore = await vAnchor1.contract.getLastRoot(); - //console.log(sourceAnchorRootBefore); - //Define inputs/outputs for transact function - const depositUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}) - //Transact on the bridge - await vBridge.transact([], [depositUtxo], 0, '0', '0', signers[2]); - // Check the state of anchors after deposit - let edgeIndex = await vAnchor2.contract.edgeIndex(chainId1); - - const sourceAnchorRootAfter = await vAnchor1.contract.getLastRoot(); - const destAnchorEdgeAfter = await vAnchor2.contract.edgeList(edgeIndex); - - // make sure the roots / anchors state have changed - assert.notEqual(sourceAnchorRootAfter, sourceAnchorRootBefore); - assert.deepEqual(ethers.BigNumber.from(1), destAnchorEdgeAfter.latestLeafIndex); - - const transferUtxo = new Utxo({ - originChainId: BigNumber.from(chainId1), - amount: BigNumber.from(1e7), - keypair: depositUtxo.keypair - }); - - await vBridge.transact([depositUtxo], [transferUtxo], 0, '0', '0', signers[2]); - }); - }); - - describe('2 sided bridge existing token use', () => { - - // ERC20 compliant contracts that can easily create balances for test - let existingToken1: MintableToken; - let existingToken2: MintableToken; - - let vBridge: VBridge; - const chainId1 = 31337; - const chainId2 = 1337; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); - ganacheProvider2.pollingInterval = 1; - let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); - - before(async () => { - const signers = await ethers.getSigners(); - - existingToken1 = await MintableToken.createToken('existingERC20', 'EXIST', signers[1]); - // Use some other signer with provider on other chain - existingToken2 = await MintableToken.createToken('existingERC20', 'EXIST', ganacheWallet2); - - // mint some tokens to the user of the bridge - await existingToken1.mintTokens(signers[1].address, '100000000000000000000000000'); - await existingToken2.mintTokens(ganacheWallet2.address, '100000000000000000000000000'); - }) - - beforeEach(async () => { - const signers = await ethers.getSigners(); - let webbTokens1 = new Map(); - webbTokens1.set(31337, null!); - webbTokens1.set(1337, null!); - // create the config for the bridge - const vBridgeInput = { - vAnchorInputs: { - asset: { - 31337: [existingToken1.contract.address], - 1337: [existingToken2.contract.address], - } - }, - chainIDs: [31337, 1337], - webbTokens: webbTokens1 - } - - // setup the config for deployers of contracts (admins) - const deploymentConfig = { - [chainId1]: signers[1], - [chainId2]: ganacheWallet2, - } - - // deploy the bridge - vBridge = await VBridge.deployVariableAnchorBridge(vBridgeInput, deploymentConfig, true); - - // make one deposit so the edge exists - const depositUtxo1 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId2)}) - const depositUtxo2 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}) - - // Should be able to retrieve the token address (so we can mint tokens for test scenario) - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); - const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); - const tx1 = await webbToken1.mintTokens(signers[1].address, '100000000000000000000000'); - - const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainId2); - const webbToken2 = await MintableToken.tokenFromAddress(webbTokenAddress2!, ganacheWallet2); - const tx2 = await webbToken2.mintTokens(ganacheWallet2.address, '100000000000000000000000'); - - //Transact on the bridge - await vBridge.transact([], [depositUtxo1], 0, '0', '0', signers[1]); - await vBridge.transact([], [depositUtxo2], 0, '0', '0', ganacheWallet2); - //Now there is a bidirectional edge between chain1 and chain2 - }) - - describe('#bridging', () => { - it('basic ganache deposit should withdraw on hardhat', async () => { - // Fetch information about the anchor to be updated. - const signers = await ethers.getSigners(); - - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; - const vAnchor1Address = vAnchor1.contract.address; - let edgeIndex = await vAnchor1.contract.edgeIndex(chainId2); - const destAnchorEdge2Before = await vAnchor1.contract.edgeList(edgeIndex); - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); - const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); - const signers2BalanceBefore = await webbToken1.getBalance(await signers[2].getAddress()); - - //ganacheWallet2 makes a deposit with dest chain chainId1 - const ganacheDepositUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - - await vBridge.transact([], [ganacheDepositUtxo], 0, '0', '0', ganacheWallet2); - - //check latest leaf index is incremented - const destAnchorEdge2After = await vAnchor1.contract.edgeList(edgeIndex); - assert.deepStrictEqual(destAnchorEdge2Before.latestLeafIndex.add(2), destAnchorEdge2After.latestLeafIndex); - - //withdraw ganacheWallet2 deposit on chainId1 to signers[2] address - const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(5e6), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}) - await vBridge.transact([ganacheDepositUtxo], [hardhatWithdrawUtxo], 0, await signers[2].getAddress(), '0', signers[2]); - const signers2BalanceAfter = await webbToken1.getBalance(await signers[2].getAddress()); - assert.strictEqual(signers2BalanceBefore.add(5e6).toString(), signers2BalanceAfter.toString()); - }).timeout(40000) - - it('join and split ganache deposits and withdraw on hardhat', async () => { - const signers = await ethers.getSigners(); - - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; - let edgeIndex = await vAnchor1.contract.edgeIndex(chainId2); - const destAnchorEdge2Before = await vAnchor1.contract.edgeList(edgeIndex); - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); - const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); - const signers2BalanceBefore = await webbToken1.getBalance(await signers[2].getAddress()); - - //ganacheWallet2 makes a deposit with dest chain chainId1 - const ganacheDepositUtxo1 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - const ganacheDepositUtxo2 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1), keypair: ganacheDepositUtxo1.keypair}); - - await vBridge.transact([], [ganacheDepositUtxo1], 0, '0', '0', ganacheWallet2); - await vBridge.transact([], [ganacheDepositUtxo2], 0, '0', '0', ganacheWallet2); - - //check latest leaf index is incremented - const destAnchorEdge2After = await vAnchor1.contract.edgeList(edgeIndex); - assert.deepStrictEqual(destAnchorEdge2Before.latestLeafIndex.add(4), destAnchorEdge2After.latestLeafIndex); - - //withdraw ganacheWallet2 deposit on chainId1 to signers[2] address - const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(5e6), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}) - await vBridge.transact([ganacheDepositUtxo1, ganacheDepositUtxo2], [hardhatWithdrawUtxo], 0, await signers[2].getAddress(), '0', signers[2]); - - const signers2BalanceAfter = await webbToken1.getBalance(await signers[2].getAddress()); - assert.strictEqual(signers2BalanceBefore.add(1.5e7).toString(), signers2BalanceAfter.toString()); - }) - - it('should update multiple deposits and withdraw historic deposit from ganache', async () => { - // Fetch information about the anchor to be updated. - const signers = await ethers.getSigners(); - - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; - let edgeIndex = await vAnchor1.contract.edgeIndex(chainId2); - const destAnchorEdge2Before = await vAnchor1.contract.edgeList(edgeIndex); - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); - const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); - const startingBalanceDest = await webbToken1.getBalance(signers[1].address); - - //ganacheWallet2 makes a deposit with dest chain chainId1 - const ganacheDepositUtxo1 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - - const ganacheDepositUtxo2 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - - await vBridge.transact([], [ganacheDepositUtxo1], 0, '0', '0', ganacheWallet2); - await vBridge.transact([], [ganacheDepositUtxo2], 0, '0', '0', ganacheWallet2); - - // Check the leaf index is incremented by two - const destAnchorEdge2After = await vAnchor1.contract.edgeList(edgeIndex); - assert.deepStrictEqual(destAnchorEdge2Before.latestLeafIndex.add(4), destAnchorEdge2After.latestLeafIndex); - - //withdraw ganacheWallet2 deposit on chainId1 to signers[2] address - const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(5e6), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}) - await vBridge.transact([ganacheDepositUtxo1], [hardhatWithdrawUtxo], 0, await signers[1].getAddress(), '0', signers[2]); - - // // Check balances - const endingBalanceDest = await webbToken1.getBalance(signers[1].address); - assert.deepStrictEqual(endingBalanceDest, startingBalanceDest.add(5e6)); - }) - - it('prevent cross-chain double spending', async () => { - const signers = await ethers.getSigners(); - - //ganacheWallet2 makes a deposit with dest chain chainId1 - const ganacheDepositUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - - const hardhatUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}); - - await vBridge.transact([], [ganacheDepositUtxo], 0, '0', '0', ganacheWallet2); - await vBridge.transact([ganacheDepositUtxo], [hardhatUtxo], 0, '0', '0', signers[2]); - await TruffleAssert.reverts( - vBridge.transact([ganacheDepositUtxo], [hardhatUtxo], 0, '0', '0', signers[2]), - 'Input is already spent' - ); - }) - - it('mintable token task test', async () => { - // Fetch information about the anchor to be updated. - const signers = await ethers.getSigners(); - - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; - const vAnchor1Address = vAnchor1.contract.address; - let edgeIndex = await vAnchor1.contract.edgeIndex(chainId2); - const destAnchorEdge2Before = await vAnchor1.contract.edgeList(edgeIndex); - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); - const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); - const signers2BalanceBefore = await webbToken1.getBalance(await signers[2].getAddress()); - - //ganacheWallet2 makes a deposit with dest chain chainId1 - const ganacheDepositUtxo = new Utxo({amount: BigNumber.from(5e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - - await vBridge.transact([], [ganacheDepositUtxo], 0, '0', '0', ganacheWallet2); - - //Check that deposit went through - const vAnchor2: VAnchor = vBridge.getVAnchor(chainId2)! as VAnchor; - const vAnchor2Address = vAnchor2.contract.address; - const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainId2); - const webbToken2 = await MintableToken.tokenFromAddress(webbTokenAddress2!, ganacheWallet2); - assert.strictEqual((await webbToken2.getBalance(vAnchor2Address)).toString(), BigNumber.from(6e7).toString()); - - //Balance in VAnchor1 is 1e7 - assert.strictEqual((await webbToken1.getBalance(vAnchor1Address)).toString(), BigNumber.from(1e7).toString()); - - //check latest leaf index is incremented - const destAnchorEdge2After = await vAnchor1.contract.edgeList(edgeIndex); - assert.deepStrictEqual(destAnchorEdge2Before.latestLeafIndex.add(2), destAnchorEdge2After.latestLeafIndex); - - //withdrawing 3e7 from ganacheWallet2 deposit on chainId1 should work despite vanchor1 only having 1e7 webb tokens...this indicates that it minted 2e7 webb tokens to make up the balance - const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(2e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}) - await vBridge.transact([ganacheDepositUtxo], [hardhatWithdrawUtxo], 0, await signers[2].getAddress(), '0', signers[2]); - const signers2BalanceAfter = await webbToken1.getBalance(await signers[2].getAddress()); - assert.strictEqual(signers2BalanceBefore.add(3e7).toString(), signers2BalanceAfter.toString()); - assert.strictEqual((await webbToken1.getBalance(vAnchor1Address)).toString(), BigNumber.from(1e7).toString()); - }) - }) - }) - - describe('2 sided bridge existing token test wrapping functionality', () => { - // ERC20 compliant contracts that can easily create balances for test - let existingToken1: MintableToken; - let existingToken2: MintableToken; - - let vBridge: VBridge; - const chainId1 = 31337; - const chainId2 = 1337; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); - ganacheProvider2.pollingInterval = 1; - let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); - - before(async () => { - const signers = await ethers.getSigners(); - - existingToken1 = await MintableToken.createToken('existingERC20', 'EXIST', signers[1]); - // Use some other signer with provider on other chain - existingToken2 = await MintableToken.createToken('existingERC20', 'EXIST', ganacheWallet2); - - // mint some tokens to the user of the bridge - await existingToken1.mintTokens(signers[1].address, '100000000000000000000000000'); - await existingToken2.mintTokens(ganacheWallet2.address, '100000000000000000000000000'); - }) - - beforeEach(async () => { - const signers = await ethers.getSigners(); - let webbTokens1 = new Map(); - webbTokens1.set(31337, null!); - webbTokens1.set(1337, null!); - // create the config for the bridge - const vBridgeInput = { - vAnchorInputs: { - asset: { - 31337: [existingToken1.contract.address], - 1337: [existingToken2.contract.address], - } - }, - chainIDs: [31337, 1337], - webbTokens: webbTokens1 - } - - // setup the config for deployers of contracts (admins) - const deploymentConfig = { - [chainId1]: signers[1], - [chainId2]: ganacheWallet2, - } - - // deploy the bridge - - vBridge = await VBridge.deployVariableAnchorBridge(vBridgeInput, deploymentConfig, true); - - // make one deposit so the edge exists - const depositUtxo1 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId2)}); - const depositUtxo2 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - - //Transact on the bridge - await vBridge.transactWrap(existingToken1.contract.address, [], [depositUtxo1], 0, '0', '0', signers[1]); - await vBridge.transactWrap(existingToken2.contract.address, [], [depositUtxo2], 0, '0', '0', ganacheWallet2); - //Now there is a bidirectional edge between chain1 and chain2 - }) - - describe('#bridging wrapping/unwrapping', () => { - it('check there is a bidirectional bridge between the two chains', async () => { - //Fetch information about the anchor to be updated. - const signers = await ethers.getSigners(); - - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; - const vAnchor1Address = vAnchor1.contract.address; - const vAnchor2: VAnchor = vBridge.getVAnchor(chainId2)! as VAnchor; - const vAnchor2Address = vAnchor2.contract.address; - let edgeIndex12 = await vAnchor1.contract.edgeIndex(chainId2); - const destAnchorEdge2Before = await vAnchor1.contract.edgeList(edgeIndex12); - assert.strictEqual(destAnchorEdge2Before.root.toString(), (await vAnchor2.contract.getLastRoot()).toString()); - let edgeIndex21 = await vAnchor2.contract.edgeIndex(chainId1); - const destAnchorEdge1Before = await vAnchor2.contract.edgeList(edgeIndex21); - assert.strictEqual(destAnchorEdge1Before.root.toString(), (await vAnchor1.contract.getLastRoot()).toString()); - - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); - const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); - - const vAnchor1Balance = await webbToken1.getBalance(vAnchor1Address); - assert.strictEqual(vAnchor1Balance.toString(), BigNumber.from(1e7).toString()); - - const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainId2); - const webbToken2 = await MintableToken.tokenFromAddress(webbTokenAddress2!, ganacheWallet2); - - const vAnchor2Balance = await webbToken2.getBalance(vAnchor2Address); - assert.strictEqual(vAnchor2Balance.toString(), BigNumber.from(1e7).toString()); - }) - it('wrap and deposit, withdraw and unwrap works join split via transactWrap', async () => { - const signers = await ethers.getSigners(); - - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; - const vAnchor1Address = vAnchor1.contract.address; - const vAnchor2: VAnchor = vBridge.getVAnchor(chainId2)! as VAnchor; - const vAnchor2Address = vAnchor2.contract.address; - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); - const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); - - //Deposit UTXO - const ganacheDepositUtxo1 = new Utxo({amount: BigNumber.from(2.5e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - const ganacheDepositUtxo2 = new Utxo({amount: BigNumber.from(2.5e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - - await vBridge.transactWrap(existingToken2.contract.address, [], [ganacheDepositUtxo1, ganacheDepositUtxo2], 0, '0', '0', ganacheWallet2); - - const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainId2); - const webbToken2 = await MintableToken.tokenFromAddress(webbTokenAddress2!, ganacheWallet2); - assert.strictEqual((await webbToken2.getBalance(vAnchor2Address)).toString(), BigNumber.from(6e7).toString()); - - - //Withdraw UTXO - const vAnchor1TokenAddr = await vAnchor1.contract.token() - await existingToken1.mintTokens(vAnchor1TokenAddr, '100000000'); - const balWrapper1UnwrappedBefore = await existingToken1.contract.balanceOf(vAnchor1TokenAddr); - const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}) - await vBridge.transactWrap(existingToken1.contract.address, [ganacheDepositUtxo1, ganacheDepositUtxo2], [hardhatWithdrawUtxo], 0, await signers[2].getAddress(), '0', signers[1]); - - //Check relevant balances - //Unwrapped Balance of signers[2] should be 3e7 - const balSigners2Unwrapped = await existingToken1.contract.balanceOf(await signers[2].getAddress()); - assert.strictEqual(balSigners2Unwrapped.toString(), BigNumber.from(4e7).toString()); - //Unwrapped balance of vanchor1tokenaddr should be - const balWrapper1UnwrappedAfter = await existingToken1.contract.balanceOf(vAnchor1TokenAddr); - assert.strictEqual(balWrapper1UnwrappedBefore.sub(BigNumber.from(4e7)).toString(), balWrapper1UnwrappedAfter.toString()); - //wrapped balance of vanchor1 should be 1e7 - const balVAnchor1Wrapped = await webbToken1.getBalance(vAnchor1.contract.address); - assert.strictEqual(balVAnchor1Wrapped.toString(), BigNumber.from(1e7).toString()); - }); - - it('wrap and deposit, withdraw and unwrap works join split 16 input via transactWrap', async () => { - const signers = await ethers.getSigners(); - - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; - const vAnchor1Address = vAnchor1.contract.address; - const vAnchor2: VAnchor = vBridge.getVAnchor(chainId2)! as VAnchor; - const vAnchor2Address = vAnchor2.contract.address; - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); - const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); - - //Deposit UTXO - const ganacheDepositUtxo1 = new Utxo({amount: BigNumber.from(2e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - const ganacheDepositUtxo2 = new Utxo({amount: BigNumber.from(2e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - const ganacheDepositUtxo3 = new Utxo({amount: BigNumber.from(2e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - - await vBridge.transactWrap(existingToken2.contract.address, [], [ganacheDepositUtxo1], 0, '0', '0', ganacheWallet2); - - await vBridge.transactWrap(existingToken2.contract.address, [], [ganacheDepositUtxo2], 0, '0', '0', ganacheWallet2); - - await vBridge.transactWrap(existingToken2.contract.address, [], [ganacheDepositUtxo3], 0, '0', '0', ganacheWallet2); - - const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainId2); - const webbToken2 = await MintableToken.tokenFromAddress(webbTokenAddress2!, ganacheWallet2); - assert.strictEqual((await webbToken2.getBalance(vAnchor2Address)).toString(), BigNumber.from(7e7).toString()); - - const balSigners2UnwrappedBefore = await existingToken1.contract.balanceOf(await signers[2].getAddress()); - - //Withdraw UTXO - const vAnchor1TokenAddr = await vAnchor1.contract.token() - await existingToken1.mintTokens(vAnchor1TokenAddr, '100000000'); - const balWrapper1UnwrappedBefore = await existingToken1.contract.balanceOf(vAnchor1TokenAddr); - const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}) - await vBridge.transactWrap(existingToken1.contract.address, [ganacheDepositUtxo1, ganacheDepositUtxo2, ganacheDepositUtxo3], [hardhatWithdrawUtxo], 0, await signers[2].getAddress(), '0', signers[1]); - - //Check relevant balances - //Unwrapped Balance of signers[2] should be 3e7 - const balSigners2UnwrappedAfter = await existingToken1.contract.balanceOf(await signers[2].getAddress()); - assert.strictEqual(balSigners2UnwrappedAfter.sub(balSigners2UnwrappedBefore).toString(), BigNumber.from(5e7).toString()); - //Unwrapped balance of vanchor1tokenaddr should be - const balWrapper1UnwrappedAfter = await existingToken1.contract.balanceOf(vAnchor1TokenAddr); - assert.strictEqual(balWrapper1UnwrappedBefore.sub(BigNumber.from(5e7)).toString(), balWrapper1UnwrappedAfter.toString()); - //wrapped balance of vanchor1 should be 1e7 - const balVAnchor1Wrapped = await webbToken1.getBalance(vAnchor1.contract.address); - assert.strictEqual(balVAnchor1Wrapped.toString(), BigNumber.from(1e7).toString()); - }).timeout(40000); - }); - }); - - after('terminate networks', async () => { - await ganacheServer2.close(); - await ganacheServer3.close(); - await ganacheServer4.close(); - }); -}); \ No newline at end of file From acc8ec369f17c437cb8245669f3420784f21cd62 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 26 Jan 2022 15:32:57 -0500 Subject: [PATCH 02/15] Update chain ID to uint64 and add chain ID type fn --- contracts/anchors/LinkableTree.sol | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/contracts/anchors/LinkableTree.sol b/contracts/anchors/LinkableTree.sol index c6b5900fd..fd240af71 100644 --- a/contracts/anchors/LinkableTree.sol +++ b/contracts/anchors/LinkableTree.sol @@ -11,6 +11,7 @@ import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "hardhat/console.sol"; abstract contract LinkableTree is MerkleTreePoseidon, ReentrancyGuard { + bytes2 public constant EVM_CHAIN_ID_TYPE = 0x0100; address public handler; uint8 public immutable maxEdges; @@ -22,14 +23,14 @@ abstract contract LinkableTree is MerkleTreePoseidon, ReentrancyGuard { } // maps sourceChainID to the index in the edge list - mapping(uint256 => uint256) public edgeIndex; - mapping(uint256 => bool) public edgeExistsForChain; + mapping(uint64 => uint256) public edgeIndex; + mapping(uint64 => bool) public edgeExistsForChain; Edge[] public edgeList; // map to store chainID => (rootIndex => root) to track neighbor histories - mapping(uint256 => mapping(uint32 => bytes32)) public neighborRoots; + mapping(uint64 => mapping(uint32 => bytes32)) public neighborRoots; // map to store the current historical root index for a chainID - mapping(uint256 => uint32) public currentNeighborRootIndex; + mapping(uint64 => uint32) public currentNeighborRootIndex; // linking events event EdgeAddition(uint64 chainID, uint256 latestLeafIndex, bytes32 merkleRoot); @@ -52,7 +53,7 @@ abstract contract LinkableTree is MerkleTreePoseidon, ReentrancyGuard { } function updateEdge( - uint256 sourceChainID, + uint64 sourceChainID, bytes32 root, uint256 leafIndex ) onlyHandler external payable nonReentrant { @@ -121,7 +122,7 @@ abstract contract LinkableTree is MerkleTreePoseidon, ReentrancyGuard { } } - function isKnownNeighborRoot(uint256 neighborChainID, bytes32 _root) public view returns (bool) { + function isKnownNeighborRoot(uint64 neighborChainID, bytes32 _root) public view returns (bool) { if (_root == 0) { return false; } @@ -160,7 +161,20 @@ abstract contract LinkableTree is MerkleTreePoseidon, ReentrancyGuard { return chainId; } - function hasEdge(uint256 _chainID) external view returns (bool) { + function getChainIdType() public view returns (uint48) { + // The chain ID and type pair is 6 bytes in length + // The first 2 bytes are reserved for the chain type. + // The last 4 bytes are reserved for a u32 (uint32) chain ID. + bytes4 chainID = bytes4(uint32(getChainId())); + bytes2 chainType = EVM_CHAIN_ID_TYPE; + // We encode the chain ID and type pair into packed bytes which + // should be 6 bytes using the encode packed method. We will + // cast this as a bytes32 in order to encode as a uint256 for zkp verification. + bytes memory chainIdWithType = abi.encodePacked(chainType, chainID); + return uint48(bytes6(chainIdWithType)); + } + + function hasEdge(uint64 _chainID) external view returns (bool) { return edgeExistsForChain[_chainID]; } From 408c4f6a71c952e7785bbdf6a6dd2733460bf08b Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 26 Jan 2022 15:48:42 -0500 Subject: [PATCH 03/15] Update back to u64 => fixes ganache error --- contracts/anchors/LinkableTree.sol | 20 +++++----- docs/AnchorBase.md | 34 +++++++++++++++++ docs/FixedDepositAnchor.md | 34 +++++++++++++++++ docs/VAnchor.md | 34 +++++++++++++++++ docs/VAnchorBase.md | 34 +++++++++++++++++ packages/contracts/src/AnchorBase.d.ts | 38 +++++++++++++++++++ .../contracts/src/FixedDepositAnchor.d.ts | 38 +++++++++++++++++++ packages/contracts/src/VAnchor.d.ts | 38 +++++++++++++++++++ packages/contracts/src/VAnchorBase.d.ts | 38 +++++++++++++++++++ .../src/factories/AnchorBase__factory.ts | 26 +++++++++++++ .../factories/FixedDepositAnchor__factory.ts | 28 +++++++++++++- .../src/factories/VAnchorBase__factory.ts | 26 +++++++++++++ .../src/factories/VAnchor__factory.ts | 28 +++++++++++++- packages/utils/src/utils.ts | 11 ++++++ test/bridge/signatureBridge.test.ts | 2 +- 15 files changed, 416 insertions(+), 13 deletions(-) diff --git a/contracts/anchors/LinkableTree.sol b/contracts/anchors/LinkableTree.sol index fd240af71..fb553cda8 100644 --- a/contracts/anchors/LinkableTree.sol +++ b/contracts/anchors/LinkableTree.sol @@ -17,24 +17,24 @@ abstract contract LinkableTree is MerkleTreePoseidon, ReentrancyGuard { uint8 public immutable maxEdges; struct Edge { - uint64 chainID; + uint256 chainID; bytes32 root; uint256 latestLeafIndex; } // maps sourceChainID to the index in the edge list - mapping(uint64 => uint256) public edgeIndex; - mapping(uint64 => bool) public edgeExistsForChain; + mapping(uint256 => uint256) public edgeIndex; + mapping(uint256 => bool) public edgeExistsForChain; Edge[] public edgeList; // map to store chainID => (rootIndex => root) to track neighbor histories - mapping(uint64 => mapping(uint32 => bytes32)) public neighborRoots; + mapping(uint256 => mapping(uint32 => bytes32)) public neighborRoots; // map to store the current historical root index for a chainID - mapping(uint64 => uint32) public currentNeighborRootIndex; + mapping(uint256 => uint32) public currentNeighborRootIndex; // linking events - event EdgeAddition(uint64 chainID, uint256 latestLeafIndex, bytes32 merkleRoot); - event EdgeUpdate(uint64 chainID, uint256 latestLeafIndex, bytes32 merkleRoot); + event EdgeAddition(uint256 chainID, uint256 latestLeafIndex, bytes32 merkleRoot); + event EdgeUpdate(uint256 chainID, uint256 latestLeafIndex, bytes32 merkleRoot); /** @dev The constructor @@ -53,7 +53,7 @@ abstract contract LinkableTree is MerkleTreePoseidon, ReentrancyGuard { } function updateEdge( - uint64 sourceChainID, + uint256 sourceChainID, bytes32 root, uint256 leafIndex ) onlyHandler external payable nonReentrant { @@ -122,7 +122,7 @@ abstract contract LinkableTree is MerkleTreePoseidon, ReentrancyGuard { } } - function isKnownNeighborRoot(uint64 neighborChainID, bytes32 _root) public view returns (bool) { + function isKnownNeighborRoot(uint256 neighborChainID, bytes32 _root) public view returns (bool) { if (_root == 0) { return false; } @@ -174,7 +174,7 @@ abstract contract LinkableTree is MerkleTreePoseidon, ReentrancyGuard { return uint48(bytes6(chainIdWithType)); } - function hasEdge(uint64 _chainID) external view returns (bool) { + function hasEdge(uint256 _chainID) external view returns (bool) { return edgeExistsForChain[_chainID]; } diff --git a/docs/AnchorBase.md b/docs/AnchorBase.md index 9dd83ffcf..a4347203b 100644 --- a/docs/AnchorBase.md +++ b/docs/AnchorBase.md @@ -10,6 +10,23 @@ ## Methods +### EVM_CHAIN_ID_TYPE + +```solidity +function EVM_CHAIN_ID_TYPE() external view returns (bytes2) +``` + + + + + + +#### Returns + +| Name | Type | Description | +|---|---|---| +| _0 | bytes2 | undefined + ### FIELD_SIZE ```solidity @@ -229,6 +246,23 @@ function getChainId() external view returns (uint256) |---|---|---| | _0 | uint256 | undefined +### getChainIdType + +```solidity +function getChainIdType() external view returns (uint48) +``` + + + + + + +#### Returns + +| Name | Type | Description | +|---|---|---| +| _0 | uint48 | undefined + ### getLastRoot ```solidity diff --git a/docs/FixedDepositAnchor.md b/docs/FixedDepositAnchor.md index f728941c1..58d293fac 100644 --- a/docs/FixedDepositAnchor.md +++ b/docs/FixedDepositAnchor.md @@ -10,6 +10,23 @@ ## Methods +### EVM_CHAIN_ID_TYPE + +```solidity +function EVM_CHAIN_ID_TYPE() external view returns (bytes2) +``` + + + + + + +#### Returns + +| Name | Type | Description | +|---|---|---| +| _0 | bytes2 | undefined + ### FIELD_SIZE ```solidity @@ -262,6 +279,23 @@ function getChainId() external view returns (uint256) |---|---|---| | _0 | uint256 | undefined +### getChainIdType + +```solidity +function getChainIdType() external view returns (uint48) +``` + + + + + + +#### Returns + +| Name | Type | Description | +|---|---|---| +| _0 | uint48 | undefined + ### getDenomination ```solidity diff --git a/docs/VAnchor.md b/docs/VAnchor.md index 0fe6bdd48..6ce4fa8dd 100644 --- a/docs/VAnchor.md +++ b/docs/VAnchor.md @@ -10,6 +10,23 @@ ## Methods +### EVM_CHAIN_ID_TYPE + +```solidity +function EVM_CHAIN_ID_TYPE() external view returns (bytes2) +``` + + + + + + +#### Returns + +| Name | Type | Description | +|---|---|---| +| _0 | bytes2 | undefined + ### FIELD_SIZE ```solidity @@ -303,6 +320,23 @@ function getChainId() external view returns (uint256) |---|---|---| | _0 | uint256 | undefined +### getChainIdType + +```solidity +function getChainIdType() external view returns (uint48) +``` + + + + + + +#### Returns + +| Name | Type | Description | +|---|---|---| +| _0 | uint48 | undefined + ### getLastRoot ```solidity diff --git a/docs/VAnchorBase.md b/docs/VAnchorBase.md index 84b43a679..1ded0e222 100644 --- a/docs/VAnchorBase.md +++ b/docs/VAnchorBase.md @@ -10,6 +10,23 @@ ## Methods +### EVM_CHAIN_ID_TYPE + +```solidity +function EVM_CHAIN_ID_TYPE() external view returns (bytes2) +``` + + + + + + +#### Returns + +| Name | Type | Description | +|---|---|---| +| _0 | bytes2 | undefined + ### FIELD_SIZE ```solidity @@ -303,6 +320,23 @@ function getChainId() external view returns (uint256) |---|---|---| | _0 | uint256 | undefined +### getChainIdType + +```solidity +function getChainIdType() external view returns (uint48) +``` + + + + + + +#### Returns + +| Name | Type | Description | +|---|---|---| +| _0 | uint48 | undefined + ### getLastRoot ```solidity diff --git a/packages/contracts/src/AnchorBase.d.ts b/packages/contracts/src/AnchorBase.d.ts index c68c968aa..4eb8c3c7e 100644 --- a/packages/contracts/src/AnchorBase.d.ts +++ b/packages/contracts/src/AnchorBase.d.ts @@ -22,6 +22,7 @@ import type { TypedEventFilter, TypedEvent, TypedListener } from "./common"; interface AnchorBaseInterface extends ethers.utils.Interface { functions: { + "EVM_CHAIN_ID_TYPE()": FunctionFragment; "FIELD_SIZE()": FunctionFragment; "ROOT_HISTORY_SIZE()": FunctionFragment; "ZERO_VALUE()": FunctionFragment; @@ -33,6 +34,7 @@ interface AnchorBaseInterface extends ethers.utils.Interface { "edgeList(uint256)": FunctionFragment; "filledSubtrees(uint256)": FunctionFragment; "getChainId()": FunctionFragment; + "getChainIdType()": FunctionFragment; "getLastRoot()": FunctionFragment; "getLatestNeighborEdges()": FunctionFragment; "getLatestNeighborRoots()": FunctionFragment; @@ -59,6 +61,10 @@ interface AnchorBaseInterface extends ethers.utils.Interface { "zeros(uint256)": FunctionFragment; }; + encodeFunctionData( + functionFragment: "EVM_CHAIN_ID_TYPE", + values?: undefined + ): string; encodeFunctionData( functionFragment: "FIELD_SIZE", values?: undefined @@ -103,6 +109,10 @@ interface AnchorBaseInterface extends ethers.utils.Interface { functionFragment: "getChainId", values?: undefined ): string; + encodeFunctionData( + functionFragment: "getChainIdType", + values?: undefined + ): string; encodeFunctionData( functionFragment: "getLastRoot", values?: undefined @@ -184,6 +194,10 @@ interface AnchorBaseInterface extends ethers.utils.Interface { encodeFunctionData(functionFragment: "verifier", values?: undefined): string; encodeFunctionData(functionFragment: "zeros", values: [BigNumberish]): string; + decodeFunctionResult( + functionFragment: "EVM_CHAIN_ID_TYPE", + data: BytesLike + ): Result; decodeFunctionResult(functionFragment: "FIELD_SIZE", data: BytesLike): Result; decodeFunctionResult( functionFragment: "ROOT_HISTORY_SIZE", @@ -213,6 +227,10 @@ interface AnchorBaseInterface extends ethers.utils.Interface { data: BytesLike ): Result; decodeFunctionResult(functionFragment: "getChainId", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "getChainIdType", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "getLastRoot", data: BytesLike @@ -353,6 +371,8 @@ export class AnchorBase extends BaseContract { interface: AnchorBaseInterface; functions: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise<[string]>; + FIELD_SIZE(overrides?: CallOverrides): Promise<[BigNumber]>; ROOT_HISTORY_SIZE(overrides?: CallOverrides): Promise<[number]>; @@ -396,6 +416,8 @@ export class AnchorBase extends BaseContract { getChainId(overrides?: CallOverrides): Promise<[BigNumber]>; + getChainIdType(overrides?: CallOverrides): Promise<[number]>; + getLastRoot(overrides?: CallOverrides): Promise<[string]>; getLatestNeighborEdges( @@ -525,6 +547,8 @@ export class AnchorBase extends BaseContract { zeros(i: BigNumberish, overrides?: CallOverrides): Promise<[string]>; }; + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; ROOT_HISTORY_SIZE(overrides?: CallOverrides): Promise; @@ -565,6 +589,8 @@ export class AnchorBase extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getLastRoot(overrides?: CallOverrides): Promise; getLatestNeighborEdges( @@ -672,6 +698,8 @@ export class AnchorBase extends BaseContract { zeros(i: BigNumberish, overrides?: CallOverrides): Promise; callStatic: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; ROOT_HISTORY_SIZE(overrides?: CallOverrides): Promise; @@ -715,6 +743,8 @@ export class AnchorBase extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getLastRoot(overrides?: CallOverrides): Promise; getLatestNeighborEdges( @@ -888,6 +918,8 @@ export class AnchorBase extends BaseContract { }; estimateGas: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; ROOT_HISTORY_SIZE(overrides?: CallOverrides): Promise; @@ -922,6 +954,8 @@ export class AnchorBase extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getLastRoot(overrides?: CallOverrides): Promise; getLatestNeighborEdges(overrides?: CallOverrides): Promise; @@ -1028,6 +1062,8 @@ export class AnchorBase extends BaseContract { }; populateTransaction: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; ROOT_HISTORY_SIZE(overrides?: CallOverrides): Promise; @@ -1068,6 +1104,8 @@ export class AnchorBase extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getLastRoot(overrides?: CallOverrides): Promise; getLatestNeighborEdges( diff --git a/packages/contracts/src/FixedDepositAnchor.d.ts b/packages/contracts/src/FixedDepositAnchor.d.ts index 9f4e7f697..b85cf4887 100644 --- a/packages/contracts/src/FixedDepositAnchor.d.ts +++ b/packages/contracts/src/FixedDepositAnchor.d.ts @@ -22,6 +22,7 @@ import type { TypedEventFilter, TypedEvent, TypedListener } from "./common"; interface FixedDepositAnchorInterface extends ethers.utils.Interface { functions: { + "EVM_CHAIN_ID_TYPE()": FunctionFragment; "FIELD_SIZE()": FunctionFragment; "ROOT_HISTORY_SIZE()": FunctionFragment; "ZERO_VALUE()": FunctionFragment; @@ -35,6 +36,7 @@ interface FixedDepositAnchorInterface extends ethers.utils.Interface { "edgeList(uint256)": FunctionFragment; "filledSubtrees(uint256)": FunctionFragment; "getChainId()": FunctionFragment; + "getChainIdType()": FunctionFragment; "getDenomination()": FunctionFragment; "getLastRoot()": FunctionFragment; "getLatestNeighborEdges()": FunctionFragment; @@ -72,6 +74,10 @@ interface FixedDepositAnchorInterface extends ethers.utils.Interface { "zeros(uint256)": FunctionFragment; }; + encodeFunctionData( + functionFragment: "EVM_CHAIN_ID_TYPE", + values?: undefined + ): string; encodeFunctionData( functionFragment: "FIELD_SIZE", values?: undefined @@ -121,6 +127,10 @@ interface FixedDepositAnchorInterface extends ethers.utils.Interface { functionFragment: "getChainId", values?: undefined ): string; + encodeFunctionData( + functionFragment: "getChainIdType", + values?: undefined + ): string; encodeFunctionData( functionFragment: "getDenomination", values?: undefined @@ -263,6 +273,10 @@ interface FixedDepositAnchorInterface extends ethers.utils.Interface { ): string; encodeFunctionData(functionFragment: "zeros", values: [BigNumberish]): string; + decodeFunctionResult( + functionFragment: "EVM_CHAIN_ID_TYPE", + data: BytesLike + ): Result; decodeFunctionResult(functionFragment: "FIELD_SIZE", data: BytesLike): Result; decodeFunctionResult( functionFragment: "ROOT_HISTORY_SIZE", @@ -297,6 +311,10 @@ interface FixedDepositAnchorInterface extends ethers.utils.Interface { data: BytesLike ): Result; decodeFunctionResult(functionFragment: "getChainId", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "getChainIdType", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "getDenomination", data: BytesLike @@ -493,6 +511,8 @@ export class FixedDepositAnchor extends BaseContract { interface: FixedDepositAnchorInterface; functions: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise<[string]>; + FIELD_SIZE(overrides?: CallOverrides): Promise<[BigNumber]>; ROOT_HISTORY_SIZE(overrides?: CallOverrides): Promise<[number]>; @@ -543,6 +563,8 @@ export class FixedDepositAnchor extends BaseContract { getChainId(overrides?: CallOverrides): Promise<[BigNumber]>; + getChainIdType(overrides?: CallOverrides): Promise<[number]>; + getDenomination(overrides?: CallOverrides): Promise<[BigNumber]>; getLastRoot(overrides?: CallOverrides): Promise<[string]>; @@ -737,6 +759,8 @@ export class FixedDepositAnchor extends BaseContract { zeros(i: BigNumberish, overrides?: CallOverrides): Promise<[string]>; }; + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; ROOT_HISTORY_SIZE(overrides?: CallOverrides): Promise; @@ -784,6 +808,8 @@ export class FixedDepositAnchor extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getDenomination(overrides?: CallOverrides): Promise; getLastRoot(overrides?: CallOverrides): Promise; @@ -956,6 +982,8 @@ export class FixedDepositAnchor extends BaseContract { zeros(i: BigNumberish, overrides?: CallOverrides): Promise; callStatic: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; ROOT_HISTORY_SIZE(overrides?: CallOverrides): Promise; @@ -1003,6 +1031,8 @@ export class FixedDepositAnchor extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getDenomination(overrides?: CallOverrides): Promise; getLastRoot(overrides?: CallOverrides): Promise; @@ -1305,6 +1335,8 @@ export class FixedDepositAnchor extends BaseContract { }; estimateGas: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; ROOT_HISTORY_SIZE(overrides?: CallOverrides): Promise; @@ -1346,6 +1378,8 @@ export class FixedDepositAnchor extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getDenomination(overrides?: CallOverrides): Promise; getLastRoot(overrides?: CallOverrides): Promise; @@ -1517,6 +1551,8 @@ export class FixedDepositAnchor extends BaseContract { }; populateTransaction: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; ROOT_HISTORY_SIZE(overrides?: CallOverrides): Promise; @@ -1564,6 +1600,8 @@ export class FixedDepositAnchor extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getDenomination(overrides?: CallOverrides): Promise; getLastRoot(overrides?: CallOverrides): Promise; diff --git a/packages/contracts/src/VAnchor.d.ts b/packages/contracts/src/VAnchor.d.ts index d9e6752ae..f658ced48 100644 --- a/packages/contracts/src/VAnchor.d.ts +++ b/packages/contracts/src/VAnchor.d.ts @@ -22,6 +22,7 @@ import type { TypedEventFilter, TypedEvent, TypedListener } from "./common"; interface VAnchorInterface extends ethers.utils.Interface { functions: { + "EVM_CHAIN_ID_TYPE()": FunctionFragment; "FIELD_SIZE()": FunctionFragment; "MAX_EXT_AMOUNT()": FunctionFragment; "MAX_FEE()": FunctionFragment; @@ -37,6 +38,7 @@ interface VAnchorInterface extends ethers.utils.Interface { "edgeList(uint256)": FunctionFragment; "filledSubtrees(uint256)": FunctionFragment; "getChainId()": FunctionFragment; + "getChainIdType()": FunctionFragment; "getLastRoot()": FunctionFragment; "getLatestNeighborEdges()": FunctionFragment; "getLatestNeighborRoots()": FunctionFragment; @@ -80,6 +82,10 @@ interface VAnchorInterface extends ethers.utils.Interface { "zeros(uint256)": FunctionFragment; }; + encodeFunctionData( + functionFragment: "EVM_CHAIN_ID_TYPE", + values?: undefined + ): string; encodeFunctionData( functionFragment: "FIELD_SIZE", values?: undefined @@ -137,6 +143,10 @@ interface VAnchorInterface extends ethers.utils.Interface { functionFragment: "getChainId", values?: undefined ): string; + encodeFunctionData( + functionFragment: "getChainIdType", + values?: undefined + ): string; encodeFunctionData( functionFragment: "getLastRoot", values?: undefined @@ -355,6 +365,10 @@ interface VAnchorInterface extends ethers.utils.Interface { ): string; encodeFunctionData(functionFragment: "zeros", values: [BigNumberish]): string; + decodeFunctionResult( + functionFragment: "EVM_CHAIN_ID_TYPE", + data: BytesLike + ): Result; decodeFunctionResult(functionFragment: "FIELD_SIZE", data: BytesLike): Result; decodeFunctionResult( functionFragment: "MAX_EXT_AMOUNT", @@ -397,6 +411,10 @@ interface VAnchorInterface extends ethers.utils.Interface { data: BytesLike ): Result; decodeFunctionResult(functionFragment: "getChainId", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "getChainIdType", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "getLastRoot", data: BytesLike @@ -607,6 +625,8 @@ export class VAnchor extends BaseContract { interface: VAnchorInterface; functions: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise<[string]>; + FIELD_SIZE(overrides?: CallOverrides): Promise<[BigNumber]>; MAX_EXT_AMOUNT(overrides?: CallOverrides): Promise<[BigNumber]>; @@ -666,6 +686,8 @@ export class VAnchor extends BaseContract { getChainId(overrides?: CallOverrides): Promise<[BigNumber]>; + getChainIdType(overrides?: CallOverrides): Promise<[number]>; + getLastRoot(overrides?: CallOverrides): Promise<[string]>; getLatestNeighborEdges( @@ -935,6 +957,8 @@ export class VAnchor extends BaseContract { zeros(i: BigNumberish, overrides?: CallOverrides): Promise<[string]>; }; + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; MAX_EXT_AMOUNT(overrides?: CallOverrides): Promise; @@ -991,6 +1015,8 @@ export class VAnchor extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getLastRoot(overrides?: CallOverrides): Promise; getLatestNeighborEdges( @@ -1238,6 +1264,8 @@ export class VAnchor extends BaseContract { zeros(i: BigNumberish, overrides?: CallOverrides): Promise; callStatic: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; MAX_EXT_AMOUNT(overrides?: CallOverrides): Promise; @@ -1297,6 +1325,8 @@ export class VAnchor extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getLastRoot(overrides?: CallOverrides): Promise; getLatestNeighborEdges( @@ -1644,6 +1674,8 @@ export class VAnchor extends BaseContract { }; estimateGas: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; MAX_EXT_AMOUNT(overrides?: CallOverrides): Promise; @@ -1694,6 +1726,8 @@ export class VAnchor extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getLastRoot(overrides?: CallOverrides): Promise; getLatestNeighborEdges(overrides?: CallOverrides): Promise; @@ -1940,6 +1974,8 @@ export class VAnchor extends BaseContract { }; populateTransaction: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; MAX_EXT_AMOUNT(overrides?: CallOverrides): Promise; @@ -1996,6 +2032,8 @@ export class VAnchor extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getLastRoot(overrides?: CallOverrides): Promise; getLatestNeighborEdges( diff --git a/packages/contracts/src/VAnchorBase.d.ts b/packages/contracts/src/VAnchorBase.d.ts index 2f3956a48..494abe088 100644 --- a/packages/contracts/src/VAnchorBase.d.ts +++ b/packages/contracts/src/VAnchorBase.d.ts @@ -22,6 +22,7 @@ import type { TypedEventFilter, TypedEvent, TypedListener } from "./common"; interface VAnchorBaseInterface extends ethers.utils.Interface { functions: { + "EVM_CHAIN_ID_TYPE()": FunctionFragment; "FIELD_SIZE()": FunctionFragment; "MAX_EXT_AMOUNT()": FunctionFragment; "MAX_FEE()": FunctionFragment; @@ -37,6 +38,7 @@ interface VAnchorBaseInterface extends ethers.utils.Interface { "edgeList(uint256)": FunctionFragment; "filledSubtrees(uint256)": FunctionFragment; "getChainId()": FunctionFragment; + "getChainIdType()": FunctionFragment; "getLastRoot()": FunctionFragment; "getLatestNeighborEdges()": FunctionFragment; "getLatestNeighborRoots()": FunctionFragment; @@ -68,6 +70,10 @@ interface VAnchorBaseInterface extends ethers.utils.Interface { "zeros(uint256)": FunctionFragment; }; + encodeFunctionData( + functionFragment: "EVM_CHAIN_ID_TYPE", + values?: undefined + ): string; encodeFunctionData( functionFragment: "FIELD_SIZE", values?: undefined @@ -125,6 +131,10 @@ interface VAnchorBaseInterface extends ethers.utils.Interface { functionFragment: "getChainId", values?: undefined ): string; + encodeFunctionData( + functionFragment: "getChainIdType", + values?: undefined + ): string; encodeFunctionData( functionFragment: "getLastRoot", values?: undefined @@ -226,6 +236,10 @@ interface VAnchorBaseInterface extends ethers.utils.Interface { encodeFunctionData(functionFragment: "verifier", values?: undefined): string; encodeFunctionData(functionFragment: "zeros", values: [BigNumberish]): string; + decodeFunctionResult( + functionFragment: "EVM_CHAIN_ID_TYPE", + data: BytesLike + ): Result; decodeFunctionResult(functionFragment: "FIELD_SIZE", data: BytesLike): Result; decodeFunctionResult( functionFragment: "MAX_EXT_AMOUNT", @@ -268,6 +282,10 @@ interface VAnchorBaseInterface extends ethers.utils.Interface { data: BytesLike ): Result; decodeFunctionResult(functionFragment: "getChainId", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "getChainIdType", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "getLastRoot", data: BytesLike @@ -442,6 +460,8 @@ export class VAnchorBase extends BaseContract { interface: VAnchorBaseInterface; functions: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise<[string]>; + FIELD_SIZE(overrides?: CallOverrides): Promise<[BigNumber]>; MAX_EXT_AMOUNT(overrides?: CallOverrides): Promise<[BigNumber]>; @@ -501,6 +521,8 @@ export class VAnchorBase extends BaseContract { getChainId(overrides?: CallOverrides): Promise<[BigNumber]>; + getChainIdType(overrides?: CallOverrides): Promise<[number]>; + getLastRoot(overrides?: CallOverrides): Promise<[string]>; getLatestNeighborEdges( @@ -647,6 +669,8 @@ export class VAnchorBase extends BaseContract { zeros(i: BigNumberish, overrides?: CallOverrides): Promise<[string]>; }; + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; MAX_EXT_AMOUNT(overrides?: CallOverrides): Promise; @@ -703,6 +727,8 @@ export class VAnchorBase extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getLastRoot(overrides?: CallOverrides): Promise; getLatestNeighborEdges( @@ -827,6 +853,8 @@ export class VAnchorBase extends BaseContract { zeros(i: BigNumberish, overrides?: CallOverrides): Promise; callStatic: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; MAX_EXT_AMOUNT(overrides?: CallOverrides): Promise; @@ -886,6 +914,8 @@ export class VAnchorBase extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getLastRoot(overrides?: CallOverrides): Promise; getLatestNeighborEdges( @@ -1112,6 +1142,8 @@ export class VAnchorBase extends BaseContract { }; estimateGas: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; MAX_EXT_AMOUNT(overrides?: CallOverrides): Promise; @@ -1162,6 +1194,8 @@ export class VAnchorBase extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getLastRoot(overrides?: CallOverrides): Promise; getLatestNeighborEdges(overrides?: CallOverrides): Promise; @@ -1285,6 +1319,8 @@ export class VAnchorBase extends BaseContract { }; populateTransaction: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + FIELD_SIZE(overrides?: CallOverrides): Promise; MAX_EXT_AMOUNT(overrides?: CallOverrides): Promise; @@ -1341,6 +1377,8 @@ export class VAnchorBase extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + getLastRoot(overrides?: CallOverrides): Promise; getLatestNeighborEdges( diff --git a/packages/contracts/src/factories/AnchorBase__factory.ts b/packages/contracts/src/factories/AnchorBase__factory.ts index 914157663..79fef9360 100644 --- a/packages/contracts/src/factories/AnchorBase__factory.ts +++ b/packages/contracts/src/factories/AnchorBase__factory.ts @@ -82,6 +82,19 @@ const _abi = [ name: "Insertion", type: "event", }, + { + inputs: [], + name: "EVM_CHAIN_ID_TYPE", + outputs: [ + { + internalType: "bytes2", + name: "", + type: "bytes2", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [], name: "FIELD_SIZE", @@ -271,6 +284,19 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "getChainIdType", + outputs: [ + { + internalType: "uint48", + name: "", + type: "uint48", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [], name: "getLastRoot", diff --git a/packages/contracts/src/factories/FixedDepositAnchor__factory.ts b/packages/contracts/src/factories/FixedDepositAnchor__factory.ts index de049711e..a2659cf5b 100644 --- a/packages/contracts/src/factories/FixedDepositAnchor__factory.ts +++ b/packages/contracts/src/factories/FixedDepositAnchor__factory.ts @@ -214,6 +214,19 @@ const _abi = [ name: "Withdrawal", type: "event", }, + { + inputs: [], + name: "EVM_CHAIN_ID_TYPE", + outputs: [ + { + internalType: "bytes2", + name: "", + type: "bytes2", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [], name: "FIELD_SIZE", @@ -429,6 +442,19 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "getChainIdType", + outputs: [ + { + internalType: "uint48", + name: "", + type: "uint48", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [], name: "getDenomination", @@ -1129,7 +1155,7 @@ const _abi = [ ]; const _bytecode = - "0x610120604052600380546001600160401b0319169055600b805463ffffffff60a01b191690553480156200003257600080fd5b50604051620051e1380380620051e1833981016040819052620000559162000931565b8685858484848383838183818160008263ffffffff1611620000ca5760405162461bcd60e51b815260206004820152602360248201527f5f6c6576656c732073686f756c642062652067726561746572207468616e207a60448201526265726f60e81b60648201526084015b60405180910390fd5b60208263ffffffff1610620001225760405162461bcd60e51b815260206004820152601e60248201527f5f6c6576656c732073686f756c64206265206c657373207468616e20333200006044820152606401620000c1565b60e09190911b6001600160e01b03191660a05260601b6001600160601b03191660805260005b8263ffffffff168163ffffffff16101562000199576200016e63ffffffff8216620002cb565b63ffffffff821660009081526001602052604090205580620001908162000a05565b91505062000148565b50620001b7620001ab600184620009dd565b63ffffffff16620002cb565b6000805260026020527fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b5550506001600455600580546001600160a01b03199081166001600160a01b039687161790915560f89190911b7fff000000000000000000000000000000000000000000000000000000000000001660c052600b805490911697909316969096179091555050508515159250620002ac9150505760405162461bcd60e51b815260206004820152602560248201527f64656e6f6d696e6174696f6e2073686f756c6420626520677265617465722074604482015264068616e20360dc1b6064820152608401620000c1565b505061010052505060601b6001600160601b03191660e0525062000a5b565b600081620002fa57507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b81600114156200032b57507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156200035c57507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b81600314156200038d57507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b8160041415620003be57507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b8160051415620003ef57507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b81600614156200042057507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b81600714156200045157507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b81600814156200048257507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b8160091415620004b357507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a1415620004e457507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b14156200051557507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c14156200054657507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156200057757507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e1415620005a857507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f1415620005d957507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b81601014156200060a57507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b81601114156200063a57507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b81601214156200066b57507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b81601314156200069c57507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b8160141415620006cd57507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b8160151415620006fe57507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b81601614156200072f57507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b81601714156200076057507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b81601814156200079157507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b8160191415620007c257507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a1415620007f357507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b14156200082457507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c14156200085557507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d14156200088657507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e1415620008b757507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f1415620008e857507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b815260206004820152601360248201527f496e646578206f7574206f6620626f756e6473000000000000000000000000006044820152606401620000c1565b600080600080600080600060e0888a0312156200094d57600080fd5b87516200095a8162000a42565b60208901519097506200096d8162000a42565b6040890151909650620009808162000a42565b6060890151909550620009938162000a42565b608089015160a08a0151919550935063ffffffff81168114620009b557600080fd5b60c089015190925060ff81168114620009cd57600080fd5b8091505092959891949750929550565b600063ffffffff83811690831681811015620009fd57620009fd62000a2c565b039392505050565b600063ffffffff8083168181141562000a225762000a2262000a2c565b6001019392505050565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811462000a5857600080fd5b50565b60805160601c60a05160e01c60c05160f81c60e05160601c6101005161462b62000bb6600039600081816103610152818161062101528181611c8501528181611d9201528181611ee9015281816120a7015281816123a6015281816125ab01528181613281015281816132b0015261337a01526000818161039e015281816109b501528181611136015281816111bc015281816113f001528181611c5401528181611db801528181611e7701528181611f170152818161257b015281816131fb015281816132de015281816133180152818161334e015261342b01526000818161058b01528181610a9501528181610b0001528181610f850152818161126b01528181611660015281816116ed015281816130d70152818161365301526136c50152600081816104bc01528181610b89015281816117ac01528181612de00152612e830152600081816108f50152612f1c015261462b6000f3fe6080604052600436106102935760003560e01c806390eeb02b1161015a578063dbc916b8116100c1578063ed33639f1161007a578063ed33639f146108e3578063f178e47c14610917578063f5ab0dd614610944578063fa73168714610973578063fc0c546a146109a3578063fc7e9c6f146109d757600080fd5b8063dbc916b8146107e4578063df203aa71461081f578063e5285dcc14610832578063e70ea87c14610862578063e82955881461088f578063ec732959146108af57600080fd5b8063ba70f75711610113578063ba70f75714610732578063c2b40ae41461075c578063c80916d414610789578063cd3a9550146107a9578063cd87a3b4146107bc578063d0e8d34a146107d157600080fd5b806390eeb02b1461068557806392156311146106a25780639fa12d0b146106d25780639ff80063146104de578063a0d192f5146106ff578063b214faa51461071f57600080fd5b80634ecf518b116101fe57806371523c32116101b757806371523c321461057957806372c1ad03146105bf578063839df945146105df5780638bca6d161461060f5780638c0d34d8146106435780638ea3099e1461066557600080fd5b80634ecf518b146104aa5780634f401241146104de5780635d2d766c146104fe578063616e0957146105315780636ad481f3146105515780636d9833e31461055957600080fd5b80632b7ac3f3116102505780632b7ac3f3146103d65780633408e470146103f6578063414a37ba1461040957806343e7119f1461043d57806344347ba914610475578063460b53e31461048a57600080fd5b80630b27fb9a1461029857806311e4dcb9146102d057806317cc915c146103005780631e627617146103305780631fc601c91461035257806321df0da71461038f575b600080fd5b3480156102a457600080fd5b50600b54600160a01b900463ffffffff165b60405163ffffffff90911681526020015b60405180910390f35b3480156102dc57600080fd5b506102f06102eb366004613e3a565b6109fc565b60405190151581526020016102c7565b34801561030c57600080fd5b506102f061031b366004613cee565b600c6020526000908152604090205460ff1681565b34801561033c57600080fd5b50610345610a91565b6040516102c79190613ff8565b34801561035e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020016102c7565b34801561039b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020016102c7565b3480156103e257600080fd5b50600b546103be906001600160a01b031681565b34801561040257600080fd5b5046610381565b34801561041557600080fd5b506103817f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b34801561044957600080fd5b50610381610458366004613e88565b600960209081526000928352604080842090915290825290205481565b610488610483366004613e5c565b610be8565b005b34801561049657600080fd5b506104886104a5366004613a7d565b61111f565b3480156104b657600080fd5b506102b67f000000000000000000000000000000000000000000000000000000000000000081565b3480156104ea57600080fd5b506104886104f9366004613a7d565b6111a5565b34801561050a57600080fd5b506102b6610519366004613cee565b600a6020526000908152604090205463ffffffff1681565b34801561053d57600080fd5b506102f061054c366004613b53565b6111f5565b6104886113d9565b34801561056557600080fd5b506102f0610574366004613cee565b611460565b34801561058557600080fd5b506105ad7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016102c7565b3480156105cb57600080fd5b506104886105da366004613aa9565b6114db565b3480156105eb57600080fd5b506102f06105fa366004613cee565b600d6020526000908152604090205460ff1681565b34801561061b57600080fd5b506103817f000000000000000000000000000000000000000000000000000000000000000081565b34801561064f57600080fd5b5061065861165c565b6040516102c79190614030565b34801561067157600080fd5b50610381610680366004613dec565b611810565b34801561069157600080fd5b506003546102b69063ffffffff1681565b3480156106ae57600080fd5b506102f06106bd366004613cee565b60009081526007602052604090205460ff1690565b3480156106de57600080fd5b506106f26106ed366004613ade565b611997565b6040516102c79190613fb2565b34801561070b57600080fd5b5061048861071a366004613aa9565b611a5d565b61048861072d366004613cee565b611bc8565b34801561073e57600080fd5b5060035463ffffffff16600090815260026020526040902054610381565b34801561076857600080fd5b50610381610777366004613cee565b60026020526000908152604090205481565b34801561079557600080fd5b506005546103be906001600160a01b031681565b6104886107b7366004613a7d565b611d46565b3480156107c857600080fd5b506102b6601e81565b6104886107df366004613d07565b61207d565b3480156107f057600080fd5b506108046107ff366004613cee565b612349565b604080519384526020840192909252908201526060016102c7565b61048861082d366004613d70565b61237c565b34801561083e57600080fd5b506102f061084d366004613cee565b6000908152600c602052604090205460ff1690565b34801561086e57600080fd5b5061038161087d366004613cee565b60066020526000908152604090205481565b34801561089b57600080fd5b506103816108aa366004613cee565b612655565b3480156108bb57600080fd5b506103817f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c81565b3480156108ef57600080fd5b506103be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561092357600080fd5b50610381610932366004613cee565b60016020526000908152604090205481565b34801561095057600080fd5b5061096461095f366004613c00565b612c95565b6040516102c793929190614097565b34801561097f57600080fd5b506102f061098e366004613cee565b60076020526000908152604090205460ff1681565b3480156109af57600080fd5b506103be7f000000000000000000000000000000000000000000000000000000000000000081565b3480156109e357600080fd5b506003546102b690640100000000900463ffffffff1681565b600081610a0b57506000610a8b565b6000838152600a602052604090205463ffffffff16805b600085815260096020908152604080832063ffffffff85168452909152902054841415610a5457600192505050610a8b565b63ffffffff8116610a635750601e5b80610a6d81614503565b9150508163ffffffff168163ffffffff161415610a22576000925050505b92915050565b60607f000000000000000000000000000000000000000000000000000000000000000060ff1667ffffffffffffffff811115610acf57610acf6145c7565b604051908082528060200260200182016040528015610af8578160200160208202803683370190505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610be457610b348160016142da565b60085410610b845760088181548110610b4f57610b4f6145b1565b906000526020600020906003020160010154828281518110610b7357610b736145b1565b602002602001018181525050610bd2565b610bb37f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612655565b828281518110610bc557610bc56145b1565b6020026020010181815250505b80610bdc81614523565b915050610afe565b5090565b6005546001600160a01b03163314610c1b5760405162461bcd60e51b8152600401610c12906141d7565b60405180910390fd5b60026004541415610c3e5760405162461bcd60e51b8152600401610c12906141a0565b60026004908155604051639215631160e01b8152908101849052309063921563119060240160206040518083038186803b158015610c7b57600080fd5b505afa158015610c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb39190613ccc565b15610f7e5760008381526007602052604090205460ff16610d3c5760405162461bcd60e51b815260206004820152603760248201527f436861696e206d75737420626520696e74656772617465642066726f6d20746860448201527f6520627269646765206265666f726520757064617465730000000000000000006064820152608401610c12565b600083815260066020526040902054600880548392908110610d6057610d606145b1565b90600052602060002090600302016002015410610dbf5760405162461bcd60e51b815260206004820152601e60248201527f4e6577206c65616620696e646578206d757374206265206772656174657200006044820152606401610c12565b600083815260066020526040902054600880549091908110610de357610de36145b1565b90600052602060002090600302016002015462010000610e0391906142da565b8110610e615760405162461bcd60e51b815260206004820152602760248201527f4e6577206c65616620696e646578206d7573742077697468696e20325e3136206044820152667570646174657360c81b6064820152608401610c12565b6000838152600660209081526040918290205482516060810184528681529182018590529181018390526008805483908110610e9f57610e9f6145b1565b60009182526020808320845160039093020191825583810151600180840191909155604094850151600290930192909255878352600a9052918120549091601e91610ef29163ffffffff909116906142f2565b610efc9190614562565b6000868152600a60209081526040808320805463ffffffff191663ffffffff86169081179091556009835281842090845282529182902087905581518881529081018690529081018690529091507f675e61f04bcf314a9c310a93f2346f417a03d704c1caf9c6af8a65ad8addfa3f9060600160405180910390a15050611115565b60085460ff7f00000000000000000000000000000000000000000000000000000000000000001611610ff25760405162461bcd60e51b815260206004820152601a60248201527f5468697320416e63686f722069732061742063617061636974790000000000006044820152606401610c12565b6000838152600760209081526040808320805460ff19166001908117909155600880548351606080820186528a82528187018a81528287018a815295840185559388528151600384027ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee381019190915593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee485015593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee590930192909255888652600685528386208190556009855283862086805285528386208890558351898152948501879052928401879052919391927fcf4749969bace1552af6a97fe7e4affedf68875511f9746c6332eb40647b3054910160405180910390a15050505b5050600160045550565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca693889061116f90339086908690600401613f8e565b600060405180830381600087803b15801561118957600080fd5b505af115801561119d573d6000803e3d6000fd5b505050505050565b60405163130e405b60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063261c80b69061116f90339086908690600401613f8e565b600061121a8260008151811061120d5761120d6145b1565b6020026020010151611460565b6112665760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f742066696e6420796f7572206d65726b6c6520726f6f74000000006044820152606401610c12565b6112917f0000000000000000000000000000000000000000000000000000000000000000600161431a565b60ff168251146112e35760405162461bcd60e51b815260206004820152601b60248201527f496e636f727265637420726f6f74206172726179206c656e67746800000000006044820152606401610c12565b60005b6008548110156113d057600060088281548110611305576113056145b1565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905061137181600001518584600161135491906142da565b81518110611364576113646145b1565b60200260200101516109fc565b6113bd5760405162461bcd60e51b815260206004820152601760248201527f4e65696768626f7220726f6f74206e6f7420666f756e640000000000000000006044820152606401610c12565b50806113c881614523565b9150506112e6565b50600192915050565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca6938890349061142c9033906000908190600401613f8e565b6000604051808303818588803b15801561144557600080fd5b505af1158015611459573d6000803e3d6000fd5b5050505050565b60008161146f57506000919050565b60035463ffffffff16805b63ffffffff81166000908152600260205260409020548414156114a1575060019392505050565b63ffffffff81166114b05750601e5b806114ba81614503565b9150508163ffffffff168163ffffffff16141561147a575060009392505050565b6005546001600160a01b031633146115055760405162461bcd60e51b8152600401610c12906141d7565b6001600160a01b0382166115515760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610c12565b600b5463ffffffff808316600160a01b90920416106115a25760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610c12565b600b546115bd90600160a01b900463ffffffff1660016142f2565b63ffffffff168163ffffffff1611156116145760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610c12565b600580546001600160a01b039093166001600160a01b031990931692909217909155600b805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b60607f000000000000000000000000000000000000000000000000000000000000000060ff1667ffffffffffffffff81111561169a5761169a6145c7565b6040519080825280602002602001820160405280156116e557816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816116b85790505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610be4576117218160016142da565b60085410611795576008818154811061173c5761173c6145b1565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050828281518110611785576117856145b1565b60200260200101819052506117fe565b6040518060600160405280600081526020016117d67f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612655565b815260200160008152508282815181106117f2576117f26145b1565b60200260200101819052505b8061180881614523565b9150506116eb565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000183106118815760405162461bcd60e51b815260206004820181905260248201527f5f6c6566742073686f756c6420626520696e7369646520746865206669656c646044820152606401610c12565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182106118fa5760405162461bcd60e51b815260206004820152602160248201527f5f72696768742073686f756c6420626520696e7369646520746865206669656c6044820152601960fa1b6064820152608401610c12565b6040805180820182528481526020810184905290516314d2f97b60e11b8152849184916001600160a01b038816916329a5f2f69161193b9190600401614089565b60206040518083038186803b15801561195357600080fd5b505afa158015611967573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198b9190613e21565b925050505b9392505050565b60608167ffffffffffffffff8111156119b2576119b26145c7565b6040519080825280602002602001820160405280156119db578160200160208202803683370190505b50905060005b82811015611a5657611a1a8484838181106119fe576119fe6145b1565b905060200201356000908152600c602052604090205460ff1690565b15611a44576001828281518110611a3357611a336145b1565b911515602092830291909101909101525b80611a4e81614523565b9150506119e1565b5092915050565b6005546001600160a01b03163314611a875760405162461bcd60e51b8152600401610c12906141d7565b6001600160a01b038216611ad35760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610c12565b600b5463ffffffff808316600160a01b9092041610611b245760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610c12565b600b54611b3f90600160a01b900463ffffffff1660016142f2565b63ffffffff168163ffffffff161115611b965760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610c12565b600b805463ffffffff909216600160a01b026001600160c01b03199092166001600160a01b0390931692909217179055565b3415611c2f5760405162461bcd60e51b815260206004820152603060248201527f4554482076616c756520697320737570706f73656420746f206265203020666f60448201526f7220455243323020696e7374616e636560801b6064820152608401610c12565b6000611c3a82612d1e565b6040516323b872dd60e01b81529091506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906323b872dd90611cad90339030907f000000000000000000000000000000000000000000000000000000000000000090600401613f8e565b602060405180830381600087803b158015611cc757600080fd5b505af1158015611cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cff9190613ccc565b5060408051338152426020820152839163ffffffff8416917fb50b68adb3452534cd51b362b06e4194335b46951229ec1945a94a158c2b48b2910160405180910390a35050565b6000818152600d602052604090205460ff1615611d755760405162461bcd60e51b8152600401610c129061415f565b6001600160a01b038216611eda57604051634b66a6ff60e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906396cd4dfe9060240160206040518083038186803b158015611e0257600080fd5b505afa158015611e16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e3a9190613e21565b3414611e4557600080fd5b604051633d97186b60e11b81523360048201526001600160a01b038381166024830152600060448301523060648301527f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d69034906084016000604051808303818588803b158015611ebc57600080fd5b505af1158015611ed0573d6000803e3d6000fd5b505050505061200b565b604051634b66a6ff60e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d6903390859084906396cd4dfe9060240160206040518083038186803b158015611f6557600080fd5b505afa158015611f79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9d9190613e21565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152306064820152608401600060405180830381600087803b158015611ff257600080fd5b505af1158015612006573d6000803e3d6000fd5b505050505b600061201682612dc7565b6000838152600d6020908152604091829020805460ff1916600117905581513381524291810191909152919250839163ffffffff8416917fb50b68adb3452534cd51b362b06e4194335b46951229ec1945a94a158c2b48b2910160405180910390a3505050565b600260045414156120a05760405162461bcd60e51b8152600401610c12906141a0565b60026004557f000000000000000000000000000000000000000000000000000000000000000060a082013511156121195760405162461bcd60e51b815260206004820152601a60248201527f4665652065786365656473207472616e736665722076616c75650000000000006044820152606401610c12565b61213681602001356000908152600c602052604090205460ff1690565b156121835760405162461bcd60e51b815260206004820152601f60248201527f546865206e6f746520686173206265656e20616c7265616479207370656e74006044820152606401610c12565b60008061218f83612ff1565b9150915061219c816111f5565b6121d85760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610c12565b61221985858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525086925061307a915050565b6122355760405162461bcd60e51b8152600401610c129061412f565b6020808401356000908152600c909152604090819020805460ff191660011790558301356122945761228f6122706080850160608601613a60565b61228060a0860160808701613a60565b8560a001358660c0013561317b565b61233d565b6040808401356000908152600d602052205460ff16156122c65760405162461bcd60e51b8152600401610c129061415f565b60006122d58460400135612dc7565b6040858101356000818152600d602090815290839020805460ff19166001179055825181890135815263ffffffff851691810191909152929350917f138604f043594af1377bf30140984eef19cad0fb0c801cbb9b879005eddc06f0910160405180910390a2505b50506001600455505050565b6008818154811061235957600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b6002600454141561239f5760405162461bcd60e51b8152600401610c12906141a0565b60026004557f000000000000000000000000000000000000000000000000000000000000000060a083013511156124185760405162461bcd60e51b815260206004820152601a60248201527f4665652065786365656473207472616e736665722076616c75650000000000006044820152606401610c12565b6020808301356000908152600c909152604090205460ff161561247d5760405162461bcd60e51b815260206004820152601f60248201527f546865206e6f746520686173206265656e20616c7265616479207370656e74006044820152606401610c12565b60008061248984612ff1565b91509150612496816111f5565b6124d25760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610c12565b61251386868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525086925061307a915050565b61252f5760405162461bcd60e51b8152600401610c129061412f565b6020808501356000908152600c90915260409020805460ff191660011790556125713061256260a0870160808801613a60565b8660a001358760c0013561317b565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016634808285e846125cf60a08801357f00000000000000000000000000000000000000000000000000000000000000006144a2565b6125df6080890160608a01613a60565b60405160e085901b6001600160e01b03191681526001600160a01b03938416600482015260248101929092529091166044820152606401600060405180830381600087803b15801561263057600080fd5b505af1158015612644573d6000803e3d6000fd5b505060016004555050505050505050565b60008161268357507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b81600114156126b357507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156126e357507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b816003141561271357507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b816004141561274357507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b816005141561277357507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b81600614156127a357507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b81600714156127d357507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b816008141561280357507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b816009141561283357507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a141561286357507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b141561289357507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c14156128c357507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156128f357507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e141561292357507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f141561295357507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b816010141561298357507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b81601114156129b257507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b81601214156129e257507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b8160131415612a1257507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b8160141415612a4257507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b8160151415612a7257507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b8160161415612aa257507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b8160171415612ad257507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b8160181415612b0257507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b8160191415612b3257507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a1415612b6257507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b1415612b9257507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c1415612bc257507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d1415612bf257507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e1415612c2257507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f1415612c5257507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b6044820152606401610c12565b919050565b612c9d6139a0565b612ca56139be565b612cad6139a0565b50506040805180820182528351815260208085015181830152825160808082018552868501518286019081526060808901519084015282528451808601865290870151815260a08701518184015281830152835180850190945260c0860151845260e0909501519083015293909150565b6000818152600d602052604081205460ff1615612d4d5760405162461bcd60e51b8152600401610c129061415f565b6000612d5883612dc7565b6000848152600d602052604090819020805460ff191660011790555190915083907fe77f587aa74084fff834b53ccbab07695ee4594b9c9d5bfd8a7dd80c556124b590612db9908490429063ffffffff929092168252602082015260400190565b60405180910390a292915050565b600354600090640100000000900463ffffffff16612e067f000000000000000000000000000000000000000000000000000000000000000060026143a7565b63ffffffff168163ffffffff161415612e7a5760405162461bcd60e51b815260206004820152603060248201527f4d65726b6c6520747265652069732066756c6c2e204e6f206d6f7265206c656160448201526f1d995cc818d85b88189948185919195960821b6064820152608401610c12565b8083600080805b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff161015612f6357612ec0600286614562565b63ffffffff16612efb57839250612edc8163ffffffff16612655565b63ffffffff821660009081526001602052604090208590559150612f17565b63ffffffff811660009081526001602052604090205492508391505b612f427f00000000000000000000000000000000000000000000000000000000000000008484611810565b9350612f4f60028661433f565b945080612f5b8161453e565b915050612e81565b50600354600090601e90612f7e9063ffffffff1660016142f2565b612f889190614562565b6003805463ffffffff191663ffffffff831690811790915560009081526002602052604090208590559050612fbe8660016142f2565b6003805463ffffffff929092166401000000000267ffffffff000000001990921691909117905550939695505050505050565b606080613071613001848061420e565b6040805160c0810182526020808901358252888301359082015290810161302e6080890160608a01613a60565b6001600160a01b0316815260200161304c60a0890160808a01613a60565b6001600160a01b031681526020018760a0013581526020018760c0013581525061356e565b91509150915091565b600080838060200190518101906130919190613c6b565b905060008060006130a184612c95565b600b54604051638041ca5360e01b815293965091945092506001600160a01b031690638041ca5390613102908690869086908c907f0000000000000000000000000000000000000000000000000000000000000000906001906004016140c0565b60206040518083038186803b15801561311a57600080fd5b505afa15801561312e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131529190613ccc565b9450846131715760405162461bcd60e51b8152600401610c129061412f565b5050505092915050565b8034146131e35760405162461bcd60e51b815260206004820152603060248201527f496e636f727265637420726566756e6420616d6f756e7420726563656976656460448201526f08189e481d1a194818dbdb9d1c9858dd60821b6064820152608401610c12565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561324557600080fd5b505afa158015613259573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061327d9190613e21565b90507f0000000000000000000000000000000000000000000000000000000000000000811061334457613305856132d4857f00000000000000000000000000000000000000000000000000000000000000006144a2565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691906135f5565b821561333f5761333f6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001685856135f5565b613488565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166340c10f198661339e867f00000000000000000000000000000000000000000000000000000000000000006144a2565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156133e457600080fd5b505af11580156133f8573d6000803e3d6000fd5b505050506000831115613488576040516340c10f1960e01b81526001600160a01b038581166004830152602482018590527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b15801561346f57600080fd5b505af1158015613483573d6000803e3d6000fd5b505050505b604080516001600160a01b038781168252602082018690528616917f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b6398910160405180910390a28115611459576000856001600160a01b03168360405160006040518083038185875af1925050503d8060008114613521576040519150601f19603f3d011682016040523d82523d6000602084013e613526565b606091505b505090508061119d576040516001600160a01b0386169084156108fc029085906000818181858888f19350505050158015613565573d6000803e3d6000fd5b50505050505050565b6060806000836000015160001c84604001516001600160a01b031685606001516001600160a01b031686608001518760a00151886020015160001c6135b04690565b8c8c6040516020016135ca99989796959493929190613f4a565b604051602081830303815290604052905060006135e7878761364c565b919791965090945050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052613647908490613756565b505050565b60606136797f0000000000000000000000000000000000000000000000000000000000000000600161431a565b60ff1667ffffffffffffffff811115613694576136946145c7565b6040519080825280602002602001820160405280156136bd578160200160208202803683370190505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff168111611a565783836136fa836020614483565b906137068460016142da565b613711906020614483565b9261371e939291906142b0565b613727916144b9565b828281518110613739576137396145b1565b60209081029190910101528061374e81614523565b9150506136c3565b60006137ab826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166138289092919063ffffffff16565b80519091501561364757808060200190518101906137c99190613ccc565b6136475760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610c12565b6060613837848460008561383f565b949350505050565b6060824710156138a05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610c12565b843b6138ee5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c12565b600080866001600160a01b0316858760405161390a9190613f2e565b60006040518083038185875af1925050503d8060008114613947576040519150601f19603f3d011682016040523d82523d6000602084013e61394c565b606091505b509150915061395c828286613967565b979650505050505050565b60608315613976575081611990565b8251156139865782518084602001fd5b8160405162461bcd60e51b8152600401610c12919061411c565b60405180604001604052806002906020820280368337509192915050565b60405180604001604052806002905b6139d56139a0565b8152602001906001900390816139cd5790505090565b60008083601f8401126139fd57600080fd5b50813567ffffffffffffffff811115613a1557600080fd5b602083019150836020828501011115613a2d57600080fd5b9250929050565b600060e08284031215613a4657600080fd5b50919050565b803563ffffffff81168114612c9057600080fd5b600060208284031215613a7257600080fd5b8135611990816145dd565b60008060408385031215613a9057600080fd5b8235613a9b816145dd565b946020939093013593505050565b60008060408385031215613abc57600080fd5b8235613ac7816145dd565b9150613ad560208401613a4c565b90509250929050565b60008060208385031215613af157600080fd5b823567ffffffffffffffff80821115613b0957600080fd5b818501915085601f830112613b1d57600080fd5b813581811115613b2c57600080fd5b8660208260051b8501011115613b4157600080fd5b60209290920196919550909350505050565b60006020808385031215613b6657600080fd5b823567ffffffffffffffff80821115613b7e57600080fd5b818501915085601f830112613b9257600080fd5b813581811115613ba457613ba46145c7565b8060051b9150613bb584830161427f565b8181528481019084860184860187018a1015613bd057600080fd5b600095505b83861015613bf3578035835260019590950194918601918601613bd5565b5098975050505050505050565b6000610100808385031215613c1457600080fd5b83601f840112613c2357600080fd5b613c2b614255565b8084868487011115613c3c57600080fd5b600093505b6008841015613c6157803583526001939093019260209283019201613c41565b5095945050505050565b6000610100808385031215613c7f57600080fd5b83601f840112613c8e57600080fd5b613c96614255565b8084868487011115613ca757600080fd5b600093505b6008841015613c6157805183526001939093019260209283019201613cac565b600060208284031215613cde57600080fd5b8151801515811461199057600080fd5b600060208284031215613d0057600080fd5b5035919050565b600080600060408486031215613d1c57600080fd5b833567ffffffffffffffff80821115613d3457600080fd5b613d40878388016139eb565b90955093506020860135915080821115613d5957600080fd5b50613d6686828701613a34565b9150509250925092565b60008060008060608587031215613d8657600080fd5b843567ffffffffffffffff80821115613d9e57600080fd5b613daa888389016139eb565b90965094506020870135915080821115613dc357600080fd5b50613dd087828801613a34565b9250506040850135613de1816145dd565b939692955090935050565b600080600060608486031215613e0157600080fd5b8335613e0c816145dd565b95602085013595506040909401359392505050565b600060208284031215613e3357600080fd5b5051919050565b60008060408385031215613e4d57600080fd5b50508035926020909101359150565b600080600060608486031215613e7157600080fd5b505081359360208301359350604090920135919050565b60008060408385031215613e9b57600080fd5b82359150613ad560208401613a4c565b8060005b6002811015613ed957613ec3848351613edf565b6040939093019260209190910190600101613eaf565b50505050565b8060005b6002811015613ed9578151845260209384019390910190600101613ee3565b60008151808452613f1a8160208601602086016144d7565b601f01601f19169290920160200192915050565b60008251613f408184602087016144d7565b9190910192915050565b8981528860208201528760408201528660608201528560808201528460a08201528360c0820152818360e08301376000910160e00190815298975050505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6020808252825182820181905260009190848201906040850190845b81811015613fec578351151583529284019291840191600101613fce565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613fec57835183529284019291840191600101614014565b602080825282518282018190526000919060409081850190868401855b8281101561407c578151805185528681015187860152850151858501526060909301929085019060010161404d565b5091979650505050505050565b60408101610a8b8284613edf565b61010081016140a68286613edf565b6140b36040830185613eab565b61383760c0830184613edf565b60006101606140cf838a613edf565b6140dc6040840189613eab565b6140e960c0840188613edf565b806101008401526140fc81840187613f02565b60ff95909516610120840152505090151561014090910152949350505050565b6020815260006119906020830184613f02565b60208082526016908201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b604082015260600190565b60208082526021908201527f54686520636f6d6d69746d656e7420686173206265656e207375626d697474656040820152601960fa1b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526019908201527f73656e646572206973206e6f74207468652068616e646c657200000000000000604082015260600190565b6000808335601e1984360301811261422557600080fd5b83018035915067ffffffffffffffff82111561424057600080fd5b602001915036819003821315613a2d57600080fd5b604051610100810167ffffffffffffffff81118282101715614279576142796145c7565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156142a8576142a86145c7565b604052919050565b600080858511156142c057600080fd5b838611156142cd57600080fd5b5050820193919092039150565b600082198211156142ed576142ed614585565b500190565b600063ffffffff80831681851680830382111561431157614311614585565b01949350505050565b600060ff821660ff84168060ff0382111561433757614337614585565b019392505050565b600063ffffffff808416806143565761435661459b565b92169190910492915050565b600181815b8085111561439f578163ffffffff0482111561438557614385614585565b8085161561439257918102915b93841c9390800290614367565b509250929050565b600063ffffffff6138378185168285166000826143c657506001610a8b565b816143d357506000610a8b565b81600181146143e957600281146143f357614424565b6001915050610a8b565b60ff84111561440457614404614585565b6001841b915063ffffffff82111561441e5761441e614585565b50610a8b565b5060208310610133831016604e8410600b841016171561445b575081810a63ffffffff81111561445657614456614585565b610a8b565b6144658383614362565b8063ffffffff0482111561447b5761447b614585565b029392505050565b600081600019048311821515161561449d5761449d614585565b500290565b6000828210156144b4576144b4614585565b500390565b80356020831015610a8b57600019602084900360031b1b1692915050565b60005b838110156144f25781810151838201526020016144da565b83811115613ed95750506000910152565b600063ffffffff82168061451957614519614585565b6000190192915050565b600060001982141561453757614537614585565b5060010190565b600063ffffffff8083168181141561455857614558614585565b6001019392505050565b600063ffffffff808416806145795761457961459b565b92169190910692915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146145f257600080fd5b5056fea26469706673582212203a29f1e9bc1be76afc80d596c8bef09bddde155f908bd53fea24e659fb94e0b964736f6c63430008050033"; + "0x610120604052600380546001600160401b0319169055600b805463ffffffff60a01b191690553480156200003257600080fd5b50604051620052f9380380620052f9833981016040819052620000559162000931565b8685858484848383838183818160008263ffffffff1611620000ca5760405162461bcd60e51b815260206004820152602360248201527f5f6c6576656c732073686f756c642062652067726561746572207468616e207a60448201526265726f60e81b60648201526084015b60405180910390fd5b60208263ffffffff1610620001225760405162461bcd60e51b815260206004820152601e60248201527f5f6c6576656c732073686f756c64206265206c657373207468616e20333200006044820152606401620000c1565b60e09190911b6001600160e01b03191660a05260601b6001600160601b03191660805260005b8263ffffffff168163ffffffff16101562000199576200016e63ffffffff8216620002cb565b63ffffffff821660009081526001602052604090205580620001908162000a05565b91505062000148565b50620001b7620001ab600184620009dd565b63ffffffff16620002cb565b6000805260026020527fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b5550506001600455600580546001600160a01b03199081166001600160a01b039687161790915560f89190911b7fff000000000000000000000000000000000000000000000000000000000000001660c052600b805490911697909316969096179091555050508515159250620002ac9150505760405162461bcd60e51b815260206004820152602560248201527f64656e6f6d696e6174696f6e2073686f756c6420626520677265617465722074604482015264068616e20360dc1b6064820152608401620000c1565b505061010052505060601b6001600160601b03191660e0525062000a5b565b600081620002fa57507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b81600114156200032b57507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156200035c57507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b81600314156200038d57507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b8160041415620003be57507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b8160051415620003ef57507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b81600614156200042057507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b81600714156200045157507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b81600814156200048257507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b8160091415620004b357507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a1415620004e457507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b14156200051557507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c14156200054657507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156200057757507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e1415620005a857507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f1415620005d957507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b81601014156200060a57507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b81601114156200063a57507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b81601214156200066b57507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b81601314156200069c57507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b8160141415620006cd57507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b8160151415620006fe57507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b81601614156200072f57507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b81601714156200076057507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b81601814156200079157507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b8160191415620007c257507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a1415620007f357507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b14156200082457507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c14156200085557507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d14156200088657507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e1415620008b757507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f1415620008e857507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b815260206004820152601360248201527f496e646578206f7574206f6620626f756e6473000000000000000000000000006044820152606401620000c1565b600080600080600080600060e0888a0312156200094d57600080fd5b87516200095a8162000a42565b60208901519097506200096d8162000a42565b6040890151909650620009808162000a42565b6060890151909550620009938162000a42565b608089015160a08a0151919550935063ffffffff81168114620009b557600080fd5b60c089015190925060ff81168114620009cd57600080fd5b8091505092959891949750929550565b600063ffffffff83811690831681811015620009fd57620009fd62000a2c565b039392505050565b600063ffffffff8083168181141562000a225762000a2262000a2c565b6001019392505050565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811462000a5857600080fd5b50565b60805160601c60a05160e01c60c05160f81c60e05160601c6101005161474362000bb660003960008181610397015281816106b401528181611d6601528181611e7301528181611fca01528181612188015281816124870152818161268c0152818161336201528181613391015261345b0152600081816103d401528181610a48015281816111c90152818161129d015281816114d101528181611d3501528181611e9901528181611f5801528181611ff80152818161265c015281816132dc015281816133bf015281816133f90152818161342f015261350c0152600081816105ed01528181610b2801528181610b93015281816110180152818161134c01528181611741015281816117ce015281816131b80152818161373401526137a601526000818161051e01528181610c1c0152818161188d01528181612ec10152612f640152600081816109880152612ffd01526147436000f3fe6080604052600436106102c95760003560e01c80638ea3099e11610175578063d0e8d34a116100dc578063ec73295911610095578063f5ab0dd61161006f578063f5ab0dd6146109d7578063fa73168714610a06578063fc0c546a14610a36578063fc7e9c6f14610a6a57600080fd5b8063ec73295914610942578063ed33639f14610976578063f178e47c146109aa57600080fd5b8063d0e8d34a14610864578063dbc916b814610877578063df203aa7146108b2578063e5285dcc146108c5578063e70ea87c146108f5578063e82955881461092257600080fd5b8063b214faa51161012e578063b214faa5146107b2578063ba70f757146107c5578063c2b40ae4146107ef578063c80916d41461081c578063cd3a95501461083c578063cd87a3b41461084f57600080fd5b80638ea3099e146106f857806390eeb02b1461071857806392156311146107355780639fa12d0b146107655780639ff8006314610540578063a0d192f51461079257600080fd5b80634c830cbd116102345780636d9833e3116101ed578063839df945116101c7578063839df945146106415780638b7e8782146106715780638bca6d16146106a25780638c0d34d8146106d657600080fd5b80636d9833e3146105bb57806371523c32146105db57806372c1ad031461062157600080fd5b80634c830cbd146104e05780634ecf518b1461050c5780634f401241146105405780635d2d766c14610560578063616e0957146105935780636ad481f3146105b357600080fd5b80632b7ac3f3116102865780632b7ac3f31461040c5780633408e4701461042c578063414a37ba1461043f57806343e7119f1461047357806344347ba9146104ab578063460b53e3146104c057600080fd5b80630b27fb9a146102ce57806311e4dcb91461030657806317cc915c146103365780631e627617146103665780631fc601c91461038857806321df0da7146103c5575b600080fd5b3480156102da57600080fd5b50600b54600160a01b900463ffffffff165b60405163ffffffff90911681526020015b60405180910390f35b34801561031257600080fd5b50610326610321366004613f1b565b610a8f565b60405190151581526020016102fd565b34801561034257600080fd5b50610326610351366004613dcf565b600c6020526000908152604090205460ff1681565b34801561037257600080fd5b5061037b610b24565b6040516102fd91906140d9565b34801561039457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020016102fd565b3480156103d157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020016102fd565b34801561041857600080fd5b50600b546103f4906001600160a01b031681565b34801561043857600080fd5b50466103b7565b34801561044b57600080fd5b506103b77f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b34801561047f57600080fd5b506103b761048e366004613f69565b600960209081526000928352604080842090915290825290205481565b6104be6104b9366004613f3d565b610c7b565b005b3480156104cc57600080fd5b506104be6104db366004613b5e565b6111b2565b3480156104ec57600080fd5b506104f5611238565b60405165ffffffffffff90911681526020016102fd565b34801561051857600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000000081565b34801561054c57600080fd5b506104be61055b366004613b5e565b611286565b34801561056c57600080fd5b506102ec61057b366004613dcf565b600a6020526000908152604090205463ffffffff1681565b34801561059f57600080fd5b506103266105ae366004613c34565b6112d6565b6104be6114ba565b3480156105c757600080fd5b506103266105d6366004613dcf565b611541565b3480156105e757600080fd5b5061060f7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016102fd565b34801561062d57600080fd5b506104be61063c366004613b8a565b6115bc565b34801561064d57600080fd5b5061032661065c366004613dcf565b600d6020526000908152604090205460ff1681565b34801561067d57600080fd5b50610689600160f81b81565b6040516001600160f01b031990911681526020016102fd565b3480156106ae57600080fd5b506103b77f000000000000000000000000000000000000000000000000000000000000000081565b3480156106e257600080fd5b506106eb61173d565b6040516102fd9190614111565b34801561070457600080fd5b506103b7610713366004613ecd565b6118f1565b34801561072457600080fd5b506003546102ec9063ffffffff1681565b34801561074157600080fd5b50610326610750366004613dcf565b60009081526007602052604090205460ff1690565b34801561077157600080fd5b50610785610780366004613bbf565b611a78565b6040516102fd9190614093565b34801561079e57600080fd5b506104be6107ad366004613b8a565b611b3e565b6104be6107c0366004613dcf565b611ca9565b3480156107d157600080fd5b5060035463ffffffff166000908152600260205260409020546103b7565b3480156107fb57600080fd5b506103b761080a366004613dcf565b60026020526000908152604090205481565b34801561082857600080fd5b506005546103f4906001600160a01b031681565b6104be61084a366004613b5e565b611e27565b34801561085b57600080fd5b506102ec601e81565b6104be610872366004613de8565b61215e565b34801561088357600080fd5b50610897610892366004613dcf565b61242a565b604080519384526020840192909252908201526060016102fd565b6104be6108c0366004613e51565b61245d565b3480156108d157600080fd5b506103266108e0366004613dcf565b6000908152600c602052604090205460ff1690565b34801561090157600080fd5b506103b7610910366004613dcf565b60066020526000908152604090205481565b34801561092e57600080fd5b506103b761093d366004613dcf565b612736565b34801561094e57600080fd5b506103b77f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c81565b34801561098257600080fd5b506103f47f000000000000000000000000000000000000000000000000000000000000000081565b3480156109b657600080fd5b506103b76109c5366004613dcf565b60016020526000908152604090205481565b3480156109e357600080fd5b506109f76109f2366004613ce1565b612d76565b6040516102fd93929190614178565b348015610a1257600080fd5b50610326610a21366004613dcf565b60076020526000908152604090205460ff1681565b348015610a4257600080fd5b506103f47f000000000000000000000000000000000000000000000000000000000000000081565b348015610a7657600080fd5b506003546102ec90640100000000900463ffffffff1681565b600081610a9e57506000610b1e565b6000838152600a602052604090205463ffffffff16805b600085815260096020908152604080832063ffffffff85168452909152902054841415610ae757600192505050610b1e565b63ffffffff8116610af65750601e5b80610b008161461b565b9150508163ffffffff168163ffffffff161415610ab5576000925050505b92915050565b60607f000000000000000000000000000000000000000000000000000000000000000060ff1667ffffffffffffffff811115610b6257610b626146df565b604051908082528060200260200182016040528015610b8b578160200160208202803683370190505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610c7757610bc78160016143bb565b60085410610c175760088181548110610be257610be26146c9565b906000526020600020906003020160010154828281518110610c0657610c066146c9565b602002602001018181525050610c65565b610c467f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612736565b828281518110610c5857610c586146c9565b6020026020010181815250505b80610c6f8161463b565b915050610b91565b5090565b6005546001600160a01b03163314610cae5760405162461bcd60e51b8152600401610ca5906142b8565b60405180910390fd5b60026004541415610cd15760405162461bcd60e51b8152600401610ca590614281565b60026004908155604051639215631160e01b8152908101849052309063921563119060240160206040518083038186803b158015610d0e57600080fd5b505afa158015610d22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d469190613dad565b156110115760008381526007602052604090205460ff16610dcf5760405162461bcd60e51b815260206004820152603760248201527f436861696e206d75737420626520696e74656772617465642066726f6d20746860448201527f6520627269646765206265666f726520757064617465730000000000000000006064820152608401610ca5565b600083815260066020526040902054600880548392908110610df357610df36146c9565b90600052602060002090600302016002015410610e525760405162461bcd60e51b815260206004820152601e60248201527f4e6577206c65616620696e646578206d757374206265206772656174657200006044820152606401610ca5565b600083815260066020526040902054600880549091908110610e7657610e766146c9565b90600052602060002090600302016002015462010000610e9691906143bb565b8110610ef45760405162461bcd60e51b815260206004820152602760248201527f4e6577206c65616620696e646578206d7573742077697468696e20325e3136206044820152667570646174657360c81b6064820152608401610ca5565b6000838152600660209081526040918290205482516060810184528681529182018590529181018390526008805483908110610f3257610f326146c9565b60009182526020808320845160039093020191825583810151600180840191909155604094850151600290930192909255878352600a9052918120549091601e91610f859163ffffffff909116906143d3565b610f8f919061467a565b6000868152600a60209081526040808320805463ffffffff191663ffffffff86169081179091556009835281842090845282529182902087905581518881529081018690529081018690529091507f675e61f04bcf314a9c310a93f2346f417a03d704c1caf9c6af8a65ad8addfa3f9060600160405180910390a150506111a8565b60085460ff7f000000000000000000000000000000000000000000000000000000000000000016116110855760405162461bcd60e51b815260206004820152601a60248201527f5468697320416e63686f722069732061742063617061636974790000000000006044820152606401610ca5565b6000838152600760209081526040808320805460ff19166001908117909155600880548351606080820186528a82528187018a81528287018a815295840185559388528151600384027ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee381019190915593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee485015593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee590930192909255888652600685528386208190556009855283862086805285528386208890558351898152948501879052928401879052919391927fcf4749969bace1552af6a97fe7e4affedf68875511f9746c6332eb40647b3054910160405180910390a15050505b5050600160045550565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca69388906112029033908690869060040161406f565b600060405180830381600087803b15801561121c57600080fd5b505af1158015611230573d6000803e3d6000fd5b505050505050565b60408051600160f81b602082018190524660e01b6001600160e01b0319811660228401528351808403600601815260269093019093526000929161127b816145b8565b60d01c935050505090565b60405163130e405b60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063261c80b6906112029033908690869060040161406f565b60006112fb826000815181106112ee576112ee6146c9565b6020026020010151611541565b6113475760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f742066696e6420796f7572206d65726b6c6520726f6f74000000006044820152606401610ca5565b6113727f000000000000000000000000000000000000000000000000000000000000000060016143fb565b60ff168251146113c45760405162461bcd60e51b815260206004820152601b60248201527f496e636f727265637420726f6f74206172726179206c656e67746800000000006044820152606401610ca5565b60005b6008548110156114b1576000600882815481106113e6576113e66146c9565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905061145281600001518584600161143591906143bb565b81518110611445576114456146c9565b6020026020010151610a8f565b61149e5760405162461bcd60e51b815260206004820152601760248201527f4e65696768626f7220726f6f74206e6f7420666f756e640000000000000000006044820152606401610ca5565b50806114a98161463b565b9150506113c7565b50600192915050565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca6938890349061150d903390600090819060040161406f565b6000604051808303818588803b15801561152657600080fd5b505af115801561153a573d6000803e3d6000fd5b5050505050565b60008161155057506000919050565b60035463ffffffff16805b63ffffffff8116600090815260026020526040902054841415611582575060019392505050565b63ffffffff81166115915750601e5b8061159b8161461b565b9150508163ffffffff168163ffffffff16141561155b575060009392505050565b6005546001600160a01b031633146115e65760405162461bcd60e51b8152600401610ca5906142b8565b6001600160a01b0382166116325760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610ca5565b600b5463ffffffff808316600160a01b90920416106116835760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610ca5565b600b5461169e90600160a01b900463ffffffff1660016143d3565b63ffffffff168163ffffffff1611156116f55760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610ca5565b600580546001600160a01b039093166001600160a01b031990931692909217909155600b805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b60607f000000000000000000000000000000000000000000000000000000000000000060ff1667ffffffffffffffff81111561177b5761177b6146df565b6040519080825280602002602001820160405280156117c657816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816117995790505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610c77576118028160016143bb565b60085410611876576008818154811061181d5761181d6146c9565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050828281518110611866576118666146c9565b60200260200101819052506118df565b6040518060600160405280600081526020016118b77f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612736565b815260200160008152508282815181106118d3576118d36146c9565b60200260200101819052505b806118e98161463b565b9150506117cc565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000183106119625760405162461bcd60e51b815260206004820181905260248201527f5f6c6566742073686f756c6420626520696e7369646520746865206669656c646044820152606401610ca5565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182106119db5760405162461bcd60e51b815260206004820152602160248201527f5f72696768742073686f756c6420626520696e7369646520746865206669656c6044820152601960fa1b6064820152608401610ca5565b6040805180820182528481526020810184905290516314d2f97b60e11b8152849184916001600160a01b038816916329a5f2f691611a1c919060040161416a565b60206040518083038186803b158015611a3457600080fd5b505afa158015611a48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6c9190613f02565b925050505b9392505050565b60608167ffffffffffffffff811115611a9357611a936146df565b604051908082528060200260200182016040528015611abc578160200160208202803683370190505b50905060005b82811015611b3757611afb848483818110611adf57611adf6146c9565b905060200201356000908152600c602052604090205460ff1690565b15611b25576001828281518110611b1457611b146146c9565b911515602092830291909101909101525b80611b2f8161463b565b915050611ac2565b5092915050565b6005546001600160a01b03163314611b685760405162461bcd60e51b8152600401610ca5906142b8565b6001600160a01b038216611bb45760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610ca5565b600b5463ffffffff808316600160a01b9092041610611c055760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610ca5565b600b54611c2090600160a01b900463ffffffff1660016143d3565b63ffffffff168163ffffffff161115611c775760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610ca5565b600b805463ffffffff909216600160a01b026001600160c01b03199092166001600160a01b0390931692909217179055565b3415611d105760405162461bcd60e51b815260206004820152603060248201527f4554482076616c756520697320737570706f73656420746f206265203020666f60448201526f7220455243323020696e7374616e636560801b6064820152608401610ca5565b6000611d1b82612dff565b6040516323b872dd60e01b81529091506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906323b872dd90611d8e90339030907f00000000000000000000000000000000000000000000000000000000000000009060040161406f565b602060405180830381600087803b158015611da857600080fd5b505af1158015611dbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de09190613dad565b5060408051338152426020820152839163ffffffff8416917fb50b68adb3452534cd51b362b06e4194335b46951229ec1945a94a158c2b48b2910160405180910390a35050565b6000818152600d602052604090205460ff1615611e565760405162461bcd60e51b8152600401610ca590614240565b6001600160a01b038216611fbb57604051634b66a6ff60e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906396cd4dfe9060240160206040518083038186803b158015611ee357600080fd5b505afa158015611ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f1b9190613f02565b3414611f2657600080fd5b604051633d97186b60e11b81523360048201526001600160a01b038381166024830152600060448301523060648301527f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d69034906084016000604051808303818588803b158015611f9d57600080fd5b505af1158015611fb1573d6000803e3d6000fd5b50505050506120ec565b604051634b66a6ff60e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d6903390859084906396cd4dfe9060240160206040518083038186803b15801561204657600080fd5b505afa15801561205a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207e9190613f02565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152306064820152608401600060405180830381600087803b1580156120d357600080fd5b505af11580156120e7573d6000803e3d6000fd5b505050505b60006120f782612ea8565b6000838152600d6020908152604091829020805460ff1916600117905581513381524291810191909152919250839163ffffffff8416917fb50b68adb3452534cd51b362b06e4194335b46951229ec1945a94a158c2b48b2910160405180910390a3505050565b600260045414156121815760405162461bcd60e51b8152600401610ca590614281565b60026004557f000000000000000000000000000000000000000000000000000000000000000060a082013511156121fa5760405162461bcd60e51b815260206004820152601a60248201527f4665652065786365656473207472616e736665722076616c75650000000000006044820152606401610ca5565b61221781602001356000908152600c602052604090205460ff1690565b156122645760405162461bcd60e51b815260206004820152601f60248201527f546865206e6f746520686173206265656e20616c7265616479207370656e74006044820152606401610ca5565b600080612270836130d2565b9150915061227d816112d6565b6122b95760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610ca5565b6122fa85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525086925061315b915050565b6123165760405162461bcd60e51b8152600401610ca590614210565b6020808401356000908152600c909152604090819020805460ff19166001179055830135612375576123706123516080850160608601613b41565b61236160a0860160808701613b41565b8560a001358660c0013561325c565b61241e565b6040808401356000908152600d602052205460ff16156123a75760405162461bcd60e51b8152600401610ca590614240565b60006123b68460400135612ea8565b6040858101356000818152600d602090815290839020805460ff19166001179055825181890135815263ffffffff851691810191909152929350917f138604f043594af1377bf30140984eef19cad0fb0c801cbb9b879005eddc06f0910160405180910390a2505b50506001600455505050565b6008818154811061243a57600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b600260045414156124805760405162461bcd60e51b8152600401610ca590614281565b60026004557f000000000000000000000000000000000000000000000000000000000000000060a083013511156124f95760405162461bcd60e51b815260206004820152601a60248201527f4665652065786365656473207472616e736665722076616c75650000000000006044820152606401610ca5565b6020808301356000908152600c909152604090205460ff161561255e5760405162461bcd60e51b815260206004820152601f60248201527f546865206e6f746520686173206265656e20616c7265616479207370656e74006044820152606401610ca5565b60008061256a846130d2565b91509150612577816112d6565b6125b35760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610ca5565b6125f486868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525086925061315b915050565b6126105760405162461bcd60e51b8152600401610ca590614210565b6020808501356000908152600c90915260409020805460ff191660011790556126523061264360a0870160808801613b41565b8660a001358760c0013561325c565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016634808285e846126b060a08801357f0000000000000000000000000000000000000000000000000000000000000000614583565b6126c06080890160608a01613b41565b60405160e085901b6001600160e01b03191681526001600160a01b03938416600482015260248101929092529091166044820152606401600060405180830381600087803b15801561271157600080fd5b505af1158015612725573d6000803e3d6000fd5b505060016004555050505050505050565b60008161276457507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b816001141561279457507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156127c457507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b81600314156127f457507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b816004141561282457507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b816005141561285457507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b816006141561288457507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b81600714156128b457507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b81600814156128e457507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b816009141561291457507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a141561294457507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b141561297457507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c14156129a457507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156129d457507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e1415612a0457507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f1415612a3457507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b8160101415612a6457507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b8160111415612a9357507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b8160121415612ac357507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b8160131415612af357507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b8160141415612b2357507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b8160151415612b5357507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b8160161415612b8357507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b8160171415612bb357507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b8160181415612be357507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b8160191415612c1357507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a1415612c4357507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b1415612c7357507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c1415612ca357507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d1415612cd357507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e1415612d0357507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f1415612d3357507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b6044820152606401610ca5565b919050565b612d7e613a81565b612d86613a9f565b612d8e613a81565b50506040805180820182528351815260208085015181830152825160808082018552868501518286019081526060808901519084015282528451808601865290870151815260a08701518184015281830152835180850190945260c0860151845260e0909501519083015293909150565b6000818152600d602052604081205460ff1615612e2e5760405162461bcd60e51b8152600401610ca590614240565b6000612e3983612ea8565b6000848152600d602052604090819020805460ff191660011790555190915083907fe77f587aa74084fff834b53ccbab07695ee4594b9c9d5bfd8a7dd80c556124b590612e9a908490429063ffffffff929092168252602082015260400190565b60405180910390a292915050565b600354600090640100000000900463ffffffff16612ee77f00000000000000000000000000000000000000000000000000000000000000006002614488565b63ffffffff168163ffffffff161415612f5b5760405162461bcd60e51b815260206004820152603060248201527f4d65726b6c6520747265652069732066756c6c2e204e6f206d6f7265206c656160448201526f1d995cc818d85b88189948185919195960821b6064820152608401610ca5565b8083600080805b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff16101561304457612fa160028661467a565b63ffffffff16612fdc57839250612fbd8163ffffffff16612736565b63ffffffff821660009081526001602052604090208590559150612ff8565b63ffffffff811660009081526001602052604090205492508391505b6130237f000000000000000000000000000000000000000000000000000000000000000084846118f1565b9350613030600286614420565b94508061303c81614656565b915050612f62565b50600354600090601e9061305f9063ffffffff1660016143d3565b613069919061467a565b6003805463ffffffff191663ffffffff83169081179091556000908152600260205260409020859055905061309f8660016143d3565b6003805463ffffffff929092166401000000000267ffffffff000000001990921691909117905550939695505050505050565b6060806131526130e284806142ef565b6040805160c0810182526020808901358252888301359082015290810161310f6080890160608a01613b41565b6001600160a01b0316815260200161312d60a0890160808a01613b41565b6001600160a01b031681526020018760a0013581526020018760c0013581525061364f565b91509150915091565b600080838060200190518101906131729190613d4c565b9050600080600061318284612d76565b600b54604051638041ca5360e01b815293965091945092506001600160a01b031690638041ca53906131e3908690869086908c907f0000000000000000000000000000000000000000000000000000000000000000906001906004016141a1565b60206040518083038186803b1580156131fb57600080fd5b505afa15801561320f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132339190613dad565b9450846132525760405162461bcd60e51b8152600401610ca590614210565b5050505092915050565b8034146132c45760405162461bcd60e51b815260206004820152603060248201527f496e636f727265637420726566756e6420616d6f756e7420726563656976656460448201526f08189e481d1a194818dbdb9d1c9858dd60821b6064820152608401610ca5565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561332657600080fd5b505afa15801561333a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061335e9190613f02565b90507f00000000000000000000000000000000000000000000000000000000000000008110613425576133e6856133b5857f0000000000000000000000000000000000000000000000000000000000000000614583565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691906136d6565b8215613420576134206001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001685856136d6565b613569565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166340c10f198661347f867f0000000000000000000000000000000000000000000000000000000000000000614583565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156134c557600080fd5b505af11580156134d9573d6000803e3d6000fd5b505050506000831115613569576040516340c10f1960e01b81526001600160a01b038581166004830152602482018590527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b15801561355057600080fd5b505af1158015613564573d6000803e3d6000fd5b505050505b604080516001600160a01b038781168252602082018690528616917f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b6398910160405180910390a2811561153a576000856001600160a01b03168360405160006040518083038185875af1925050503d8060008114613602576040519150601f19603f3d011682016040523d82523d6000602084013e613607565b606091505b5050905080611230576040516001600160a01b0386169084156108fc029085906000818181858888f19350505050158015613646573d6000803e3d6000fd5b50505050505050565b6060806000836000015160001c84604001516001600160a01b031685606001516001600160a01b031686608001518760a00151886020015160001c6136914690565b8c8c6040516020016136ab9998979695949392919061402b565b604051602081830303815290604052905060006136c8878761372d565b919791965090945050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052613728908490613837565b505050565b606061375a7f000000000000000000000000000000000000000000000000000000000000000060016143fb565b60ff1667ffffffffffffffff811115613775576137756146df565b60405190808252806020026020018201604052801561379e578160200160208202803683370190505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff168111611b375783836137db836020614564565b906137e78460016143bb565b6137f2906020614564565b926137ff93929190614391565b6138089161459a565b82828151811061381a5761381a6146c9565b60209081029190910101528061382f8161463b565b9150506137a4565b600061388c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166139099092919063ffffffff16565b80519091501561372857808060200190518101906138aa9190613dad565b6137285760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610ca5565b60606139188484600085613920565b949350505050565b6060824710156139815760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610ca5565b843b6139cf5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca5565b600080866001600160a01b031685876040516139eb919061400f565b60006040518083038185875af1925050503d8060008114613a28576040519150601f19603f3d011682016040523d82523d6000602084013e613a2d565b606091505b5091509150613a3d828286613a48565b979650505050505050565b60608315613a57575081611a71565b825115613a675782518084602001fd5b8160405162461bcd60e51b8152600401610ca591906141fd565b60405180604001604052806002906020820280368337509192915050565b60405180604001604052806002905b613ab6613a81565b815260200190600190039081613aae5790505090565b60008083601f840112613ade57600080fd5b50813567ffffffffffffffff811115613af657600080fd5b602083019150836020828501011115613b0e57600080fd5b9250929050565b600060e08284031215613b2757600080fd5b50919050565b803563ffffffff81168114612d7157600080fd5b600060208284031215613b5357600080fd5b8135611a71816146f5565b60008060408385031215613b7157600080fd5b8235613b7c816146f5565b946020939093013593505050565b60008060408385031215613b9d57600080fd5b8235613ba8816146f5565b9150613bb660208401613b2d565b90509250929050565b60008060208385031215613bd257600080fd5b823567ffffffffffffffff80821115613bea57600080fd5b818501915085601f830112613bfe57600080fd5b813581811115613c0d57600080fd5b8660208260051b8501011115613c2257600080fd5b60209290920196919550909350505050565b60006020808385031215613c4757600080fd5b823567ffffffffffffffff80821115613c5f57600080fd5b818501915085601f830112613c7357600080fd5b813581811115613c8557613c856146df565b8060051b9150613c96848301614360565b8181528481019084860184860187018a1015613cb157600080fd5b600095505b83861015613cd4578035835260019590950194918601918601613cb6565b5098975050505050505050565b6000610100808385031215613cf557600080fd5b83601f840112613d0457600080fd5b613d0c614336565b8084868487011115613d1d57600080fd5b600093505b6008841015613d4257803583526001939093019260209283019201613d22565b5095945050505050565b6000610100808385031215613d6057600080fd5b83601f840112613d6f57600080fd5b613d77614336565b8084868487011115613d8857600080fd5b600093505b6008841015613d4257805183526001939093019260209283019201613d8d565b600060208284031215613dbf57600080fd5b81518015158114611a7157600080fd5b600060208284031215613de157600080fd5b5035919050565b600080600060408486031215613dfd57600080fd5b833567ffffffffffffffff80821115613e1557600080fd5b613e2187838801613acc565b90955093506020860135915080821115613e3a57600080fd5b50613e4786828701613b15565b9150509250925092565b60008060008060608587031215613e6757600080fd5b843567ffffffffffffffff80821115613e7f57600080fd5b613e8b88838901613acc565b90965094506020870135915080821115613ea457600080fd5b50613eb187828801613b15565b9250506040850135613ec2816146f5565b939692955090935050565b600080600060608486031215613ee257600080fd5b8335613eed816146f5565b95602085013595506040909401359392505050565b600060208284031215613f1457600080fd5b5051919050565b60008060408385031215613f2e57600080fd5b50508035926020909101359150565b600080600060608486031215613f5257600080fd5b505081359360208301359350604090920135919050565b60008060408385031215613f7c57600080fd5b82359150613bb660208401613b2d565b8060005b6002811015613fba57613fa4848351613fc0565b6040939093019260209190910190600101613f90565b50505050565b8060005b6002811015613fba578151845260209384019390910190600101613fc4565b60008151808452613ffb8160208601602086016145ef565b601f01601f19169290920160200192915050565b600082516140218184602087016145ef565b9190910192915050565b8981528860208201528760408201528660608201528560808201528460a08201528360c0820152818360e08301376000910160e00190815298975050505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6020808252825182820181905260009190848201906040850190845b818110156140cd5783511515835292840192918401916001016140af565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156140cd578351835292840192918401916001016140f5565b602080825282518282018190526000919060409081850190868401855b8281101561415d578151805185528681015187860152850151858501526060909301929085019060010161412e565b5091979650505050505050565b60408101610b1e8284613fc0565b61010081016141878286613fc0565b6141946040830185613f8c565b61391860c0830184613fc0565b60006101606141b0838a613fc0565b6141bd6040840189613f8c565b6141ca60c0840188613fc0565b806101008401526141dd81840187613fe3565b60ff95909516610120840152505090151561014090910152949350505050565b602081526000611a716020830184613fe3565b60208082526016908201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b604082015260600190565b60208082526021908201527f54686520636f6d6d69746d656e7420686173206265656e207375626d697474656040820152601960fa1b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526019908201527f73656e646572206973206e6f74207468652068616e646c657200000000000000604082015260600190565b6000808335601e1984360301811261430657600080fd5b83018035915067ffffffffffffffff82111561432157600080fd5b602001915036819003821315613b0e57600080fd5b604051610100810167ffffffffffffffff8111828210171561435a5761435a6146df565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614389576143896146df565b604052919050565b600080858511156143a157600080fd5b838611156143ae57600080fd5b5050820193919092039150565b600082198211156143ce576143ce61469d565b500190565b600063ffffffff8083168185168083038211156143f2576143f261469d565b01949350505050565b600060ff821660ff84168060ff038211156144185761441861469d565b019392505050565b600063ffffffff80841680614437576144376146b3565b92169190910492915050565b600181815b80851115614480578163ffffffff048211156144665761446661469d565b8085161561447357918102915b93841c9390800290614448565b509250929050565b600063ffffffff6139188185168285166000826144a757506001610b1e565b816144b457506000610b1e565b81600181146144ca57600281146144d457614505565b6001915050610b1e565b60ff8411156144e5576144e561469d565b6001841b915063ffffffff8211156144ff576144ff61469d565b50610b1e565b5060208310610133831016604e8410600b841016171561453c575081810a63ffffffff8111156145375761453761469d565b610b1e565b6145468383614443565b8063ffffffff0482111561455c5761455c61469d565b029392505050565b600081600019048311821515161561457e5761457e61469d565b500290565b6000828210156145955761459561469d565b500390565b80356020831015610b1e57600019602084900360031b1b1692915050565b805160208201516001600160d01b031980821692919060068310156145e75780818460060360031b1b83161693505b505050919050565b60005b8381101561460a5781810151838201526020016145f2565b83811115613fba5750506000910152565b600063ffffffff8216806146315761463161469d565b6000190192915050565b600060001982141561464f5761464f61469d565b5060010190565b600063ffffffff808316818114156146705761467061469d565b6001019392505050565b600063ffffffff80841680614691576146916146b3565b92169190910692915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461470a57600080fd5b5056fea2646970667358221220c0ccd0ad910d236cd2bf38a65e3a1f5824a69fb7dbf27a93d770b5509c6434a264736f6c63430008050033"; export class FixedDepositAnchor__factory extends ContractFactory { constructor( diff --git a/packages/contracts/src/factories/VAnchorBase__factory.ts b/packages/contracts/src/factories/VAnchorBase__factory.ts index 5da282b8d..93799ffa3 100644 --- a/packages/contracts/src/factories/VAnchorBase__factory.ts +++ b/packages/contracts/src/factories/VAnchorBase__factory.ts @@ -139,6 +139,19 @@ const _abi = [ name: "PublicKey", type: "event", }, + { + inputs: [], + name: "EVM_CHAIN_ID_TYPE", + outputs: [ + { + internalType: "bytes2", + name: "", + type: "bytes2", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [], name: "FIELD_SIZE", @@ -396,6 +409,19 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "getChainIdType", + outputs: [ + { + internalType: "uint48", + name: "", + type: "uint48", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [], name: "getLastRoot", diff --git a/packages/contracts/src/factories/VAnchor__factory.ts b/packages/contracts/src/factories/VAnchor__factory.ts index 35afce02e..33fda4582 100644 --- a/packages/contracts/src/factories/VAnchor__factory.ts +++ b/packages/contracts/src/factories/VAnchor__factory.ts @@ -182,6 +182,19 @@ const _abi = [ name: "PublicKey", type: "event", }, + { + inputs: [], + name: "EVM_CHAIN_ID_TYPE", + outputs: [ + { + internalType: "bytes2", + name: "", + type: "bytes2", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [], name: "FIELD_SIZE", @@ -439,6 +452,19 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "getChainIdType", + outputs: [ + { + internalType: "uint48", + name: "", + type: "uint48", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [], name: "getLastRoot", @@ -1475,7 +1501,7 @@ const _abi = [ ]; const _bytecode = - "0x610100604052600380546001600160401b0319169055600b805463ffffffff60a01b191690553480156200003257600080fd5b506040516200595a3803806200595a8339810160408190526200005591620008da565b85858585848185848684848383838183818160008263ffffffff1611620000cf5760405162461bcd60e51b815260206004820152602360248201527f5f6c6576656c732073686f756c642062652067726561746572207468616e207a60448201526265726f60e81b60648201526084015b60405180910390fd5b60208263ffffffff1610620001275760405162461bcd60e51b815260206004820152601e60248201527f5f6c6576656c732073686f756c64206265206c657373207468616e20333200006044820152606401620000c6565b60e09190911b6001600160e01b03191660a05260601b6001600160601b03191660805260005b8263ffffffff168163ffffffff1610156200019e576200017363ffffffff821662000274565b63ffffffff8216600090815260016020526040902055806200019581620009a3565b9150506200014d565b50620001bc620001b06001846200097b565b63ffffffff1662000274565b6000805260026020527fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b5550506001600455600580546001600160a01b03199081166001600160a01b039687161790915560f89190911b7fff000000000000000000000000000000000000000000000000000000000000001660c052600b80549091169790931696909617909155505050505060609790971b6001600160601b03191660e05250620009f99950505050505050505050565b600081620002a357507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b8160011415620002d457507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156200030557507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b81600314156200033657507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b81600414156200036757507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b81600514156200039857507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b8160061415620003c957507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b8160071415620003fa57507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b81600814156200042b57507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b81600914156200045c57507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a14156200048d57507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b1415620004be57507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c1415620004ef57507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156200052057507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e14156200055157507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f14156200058257507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b8160101415620005b357507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b8160111415620005e357507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b81601214156200061457507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b81601314156200064557507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b81601414156200067657507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b8160151415620006a757507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b8160161415620006d857507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b81601714156200070957507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b81601814156200073a57507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b81601914156200076b57507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a14156200079c57507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b1415620007cd57507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c1415620007fe57507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d14156200082f57507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e14156200086057507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f14156200089157507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b815260206004820152601360248201527f496e646578206f7574206f6620626f756e6473000000000000000000000000006044820152606401620000c6565b60008060008060008060c08789031215620008f457600080fd5b86516200090181620009e0565b602088015190965063ffffffff811681146200091c57600080fd5b60408801519095506200092f81620009e0565b60608801519094506200094281620009e0565b60808801519093506200095581620009e0565b60a088015190925060ff811681146200096d57600080fd5b809150509295509295509295565b600063ffffffff838116908316818110156200099b576200099b620009ca565b039392505050565b600063ffffffff80831681811415620009c057620009c0620009ca565b6001019392505050565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0381168114620009f657600080fd5b50565b60805160601c60a05160e01c60c05160f81c60e05160601c614e5762000b0360003960008181610b1001528181610d8e01528181610e220152818161160b0152818161165b0152818161188f01528181611e7101528181611f3201528181612d5901528181612df701528181612e4401528181612ff9015261309101526000818161065901528181610bf001528181610c5a0152818161145a0152818161170a01528181611aff01528181611b8b01528181613132015281816132910152818161359b01526136c501526000818161058a01528181610ce301528181611c4a015281816137db01526138bb015260008181610a500152818161388b01526139540152614e576000f3fe60806040526004361061036b5760003560e01c80638f1c56bd116101c6578063c9be7250116100f7578063ec73295911610095578063f5ab0dd61161006f578063f5ab0dd614610a9f578063fa73168714610ace578063fc0c546a14610afe578063fc7e9c6f14610b3257600080fd5b8063ec73295914610a0a578063ed33639f14610a3e578063f178e47c14610a7257600080fd5b8063e4a30116116100d1578063e4a301161461096d578063e5285dcc1461098d578063e70ea87c146109bd578063e8295588146109ea57600080fd5b8063c9be7250146108fd578063cd87a3b41461091d578063dbc916b81461093257600080fd5b8063a0d192f511610164578063ba70f7571161013e578063ba70f75714610886578063bc063e1a146106c3578063c2b40ae4146108b0578063c80916d4146108dd57600080fd5b8063a0d192f514610826578063b2bc6e0f14610846578063b7566a671461086657600080fd5b806395c87d1a116101a057806395c87d1a146107c65780639bbca3a9146107d95780639fa12d0b146107f95780639ff80063146105ac57600080fd5b80638f1c56bd1461076357806390eeb02b14610779578063921563111461079657600080fd5b80634ecf518b116102a057806372c1ad031161023e578063839df94511610218578063839df945146106db578063840b27911461070b5780638c0d34d8146107215780638ea3099e1461074357600080fd5b806372c1ad031461068d57806378abb49b146106ad5780637fe24ffe146106c357600080fd5b8063616e09571161027a578063616e0957146105ff5780636ad481f31461061f5780636d9833e31461062757806371523c321461064757600080fd5b80634ecf518b146105785780634f401241146105ac5780635d2d766c146105cc57600080fd5b80633408e4701161030d57806342d90711116102e757806342d90711146104ed57806343e7119f1461050d57806344347ba914610545578063460b53e31461055857600080fd5b80633408e470146104a5578063414a37ba146104b85780634167bb1e146104da57600080fd5b80631e627617116103495780631e627617146104085780632063e3d31461042a5780632570b7b41461043f5780632b7ac3f31461046d57600080fd5b80630b27fb9a1461037057806311e4dcb9146103a857806317cc915c146103d8575b600080fd5b34801561037c57600080fd5b50600b54600160a01b900463ffffffff165b60405163ffffffff90911681526020015b60405180910390f35b3480156103b457600080fd5b506103c86103c3366004614238565b610b57565b604051901515815260200161039f565b3480156103e457600080fd5b506103c86103f33660046140ec565b600c6020526000908152604090205460ff1681565b34801561041457600080fd5b5061041d610bec565b60405161039f91906145f4565b61043d610438366004613ef5565b610d42565b005b34801561044b57600080fd5b5061045f61045a366004614238565b610e83565b60405190815260200161039f565b34801561047957600080fd5b50600b5461048d906001600160a01b031681565b6040516001600160a01b03909116815260200161039f565b3480156104b157600080fd5b504661045f565b3480156104c457600080fd5b5061045f600080516020614e0283398151915281565b61043d6104e8366004614412565b610f71565b3480156104f957600080fd5b5061043d610508366004614238565b611091565b34801561051957600080fd5b5061045f6105283660046144ce565b600960209081526000928352604080842090915290825290205481565b61043d6105533660046144a2565b6110c6565b34801561056457600080fd5b5061043d610573366004613ef5565b6115f4565b34801561058457600080fd5b5061038e7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105b857600080fd5b5061043d6105c7366004613ef5565b611644565b3480156105d857600080fd5b5061038e6105e73660046140ec565b600a6020526000908152604090205463ffffffff1681565b34801561060b57600080fd5b506103c861061a366004613fca565b611694565b61043d611878565b34801561063357600080fd5b506103c86106423660046140ec565b6118ff565b34801561065357600080fd5b5061067b7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161039f565b34801561069957600080fd5b5061043d6106a8366004613f21565b61197a565b3480156106b957600080fd5b5061045f60105481565b3480156106cf57600080fd5b5061045f600160f81b81565b3480156106e757600080fd5b506103c86106f63660046140ec565b600d6020526000908152604090205460ff1681565b34801561071757600080fd5b5061045f600f5481565b34801561072d57600080fd5b50610736611afb565b60405161039f919061462c565b34801561074f57600080fd5b5061045f61075e366004614203565b611cae565b34801561076f57600080fd5b5061045f600e5481565b34801561078557600080fd5b5060035461038e9063ffffffff1681565b3480156107a257600080fd5b506103c86107b13660046140ec565b60009081526007602052604090205460ff1690565b61043d6107d4366004613eb4565b611e11565b3480156107e557600080fd5b5061043d6107f43660046143af565b611ed7565b34801561080557600080fd5b50610819610814366004613f56565b6120c0565b60405161039f91906145ae565b34801561083257600080fd5b5061043d610841366004613f21565b612185565b34801561085257600080fd5b5061043d61086136600461425a565b6122f0565b34801561087257600080fd5b5061043d610881366004614315565b612355565b34801561089257600080fd5b5060035463ffffffff1660009081526002602052604090205461045f565b3480156108bc57600080fd5b5061045f6108cb3660046140ec565b60026020526000908152604090205481565b3480156108e957600080fd5b5060055461048d906001600160a01b031681565b34801561090957600080fd5b5061043d61091836600461428e565b61236f565b34801561092957600080fd5b5061038e601e81565b34801561093e57600080fd5b5061095261094d3660046140ec565b612382565b6040805193845260208401929092529082015260600161039f565b34801561097957600080fd5b5061043d610988366004614238565b6123b5565b34801561099957600080fd5b506103c86109a83660046140ec565b6000908152600c602052604090205460ff1690565b3480156109c957600080fd5b5061045f6109d83660046140ec565b60066020526000908152604090205481565b3480156109f657600080fd5b5061045f610a053660046140ec565b612473565b348015610a1657600080fd5b5061045f7f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c81565b348015610a4a57600080fd5b5061048d7f000000000000000000000000000000000000000000000000000000000000000081565b348015610a7e57600080fd5b5061045f610a8d3660046140ec565b60016020526000908152604090205481565b348015610aab57600080fd5b50610abf610aba366004613ffe565b612ab3565b60405161039f93929190614693565b348015610ada57600080fd5b506103c8610ae93660046140ec565b60076020526000908152604090205460ff1681565b348015610b0a57600080fd5b5061048d7f000000000000000000000000000000000000000000000000000000000000000081565b348015610b3e57600080fd5b5060035461038e90640100000000900463ffffffff1681565b600081610b6657506000610be6565b6000838152600a602052604090205463ffffffff16805b600085815260096020908152604080832063ffffffff85168452909152902054841415610baf57600192505050610be6565b63ffffffff8116610bbe5750601e5b80610bc881614ce1565b9150508163ffffffff168163ffffffff161415610b7d576000925050505b92915050565b60607f000000000000000000000000000000000000000000000000000000000000000060ff166001600160401b03811115610c2957610c29614dd6565b604051908082528060200260200182016040528015610c52578160200160208202803683370190505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610d3e57610c8e816001614a91565b60085410610cde5760088181548110610ca957610ca9614dc0565b906000526020600020906003020160010154828281518110610ccd57610ccd614dc0565b602002602001018181525050610d2c565b610d0d7f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612473565b828281518110610d1f57610d1f614dc0565b6020026020010181815250505b80610d3681614d01565b915050610c58565b5090565b6001600160a01b038216610df057803414610d5c57600080fd5b604051633d97186b60e11b81523360048201526001600160a01b038381166024830152600060448301523060648301527f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d69034906084016000604051808303818588803b158015610dd357600080fd5b505af1158015610de7573d6000803e3d6000fd5b50505050505050565b604051633d97186b60e11b81523360048201526001600160a01b038381166024830152604482018390523060648301527f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d6906084015b600060405180830381600087803b158015610e6757600080fd5b505af1158015610e7b573d6000803e3d6000fd5b505050505050565b6000600160f81b8210610ecb5760405162461bcd60e51b815260206004820152600b60248201526a496e76616c69642066656560a81b60448201526064015b60405180910390fd5b610ed8600160f81b614d77565b83138015610ee95750600160f81b83125b610f2a5760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a5908195e1d08185b5bdd5b9d60721b6044820152606401610ec2565b6000610f368385614c3a565b90506000811215610f6757610f4a81614d77565b610f6290600080516020614e02833981519152614c79565b610f69565b805b949350505050565b610f7b8383612b3c565b600082602001511315610fbc5760105482602001511115610fae5760405162461bcd60e51b8152600401610ec29061481c565b610fbc818360200151610d42565b6000826020015112156110665781516001600160a01b03166110205760405162461bcd60e51b815260206004820152601e60248201527f43616e277420776974686472617720746f207a65726f206164647265737300006044820152606401610ec2565b600f54826020015161103190614d77565b101561104f5760405162461bcd60e51b8152600401610ec290614759565b61106681836000015184602001516107d490614d77565b6060820151156110825761108282604001518360600151612d41565b61108c8383612e88565b505050565b6005546001600160a01b031633146110bb5760405162461bcd60e51b8152600401610ec290614866565b600f91909155601055565b6005546001600160a01b031633146110f05760405162461bcd60e51b8152600401610ec290614866565b600260045414156111135760405162461bcd60e51b8152600401610ec2906147e5565b60026004908155604051639215631160e01b8152908101849052309063921563119060240160206040518083038186803b15801561115057600080fd5b505afa158015611164573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118891906140ca565b156114535760008381526007602052604090205460ff166112115760405162461bcd60e51b815260206004820152603760248201527f436861696e206d75737420626520696e74656772617465642066726f6d20746860448201527f6520627269646765206265666f726520757064617465730000000000000000006064820152608401610ec2565b60008381526006602052604090205460088054839290811061123557611235614dc0565b906000526020600020906003020160020154106112945760405162461bcd60e51b815260206004820152601e60248201527f4e6577206c65616620696e646578206d757374206265206772656174657200006044820152606401610ec2565b6000838152600660205260409020546008805490919081106112b8576112b8614dc0565b906000526020600020906003020160020154620100006112d89190614a91565b81106113365760405162461bcd60e51b815260206004820152602760248201527f4e6577206c65616620696e646578206d7573742077697468696e20325e3136206044820152667570646174657360c81b6064820152608401610ec2565b600083815260066020908152604091829020548251606081018452868152918201859052918101839052600880548390811061137457611374614dc0565b60009182526020808320845160039093020191825583810151600180840191909155604094850151600290930192909255878352600a9052918120549091601e916113c79163ffffffff90911690614aa9565b6113d19190614d54565b6000868152600a60209081526040808320805463ffffffff191663ffffffff86169081179091556009835281842090845282529182902087905581518881529081018690529081018690529091507f675e61f04bcf314a9c310a93f2346f417a03d704c1caf9c6af8a65ad8addfa3f9060600160405180910390a150506115ea565b60085460ff7f000000000000000000000000000000000000000000000000000000000000000016116114c75760405162461bcd60e51b815260206004820152601a60248201527f5468697320416e63686f722069732061742063617061636974790000000000006044820152606401610ec2565b6000838152600760209081526040808320805460ff19166001908117909155600880548351606080820186528a82528187018a81528287018a815295840185559388528151600384027ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee381019190915593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee485015593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee590930192909255888652600685528386208190556009855283862086805285528386208890558351898152948501879052928401879052919391927fcf4749969bace1552af6a97fe7e4affedf68875511f9746c6332eb40647b3054910160405180910390a15050505b5050600160045550565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca6938890610e4d9033908690869060040161458a565b60405163130e405b60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063261c80b690610e4d9033908690869060040161458a565b60006116b9826000815181106116ac576116ac614dc0565b60200260200101516118ff565b6117055760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f742066696e6420796f7572206d65726b6c6520726f6f74000000006044820152606401610ec2565b6117307f00000000000000000000000000000000000000000000000000000000000000006001614ad1565b60ff168251146117825760405162461bcd60e51b815260206004820152601b60248201527f496e636f727265637420726f6f74206172726179206c656e67746800000000006044820152606401610ec2565b60005b60085481101561186f576000600882815481106117a4576117a4614dc0565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505090506118108160000151858460016117f39190614a91565b8151811061180357611803614dc0565b6020026020010151610b57565b61185c5760405162461bcd60e51b815260206004820152601760248201527f4e65696768626f7220726f6f74206e6f7420666f756e640000000000000000006044820152606401610ec2565b508061186781614d01565b915050611785565b50600192915050565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca693889034906118cb903390600090819060040161458a565b6000604051808303818588803b1580156118e457600080fd5b505af11580156118f8573d6000803e3d6000fd5b5050505050565b60008161190e57506000919050565b60035463ffffffff16805b63ffffffff8116600090815260026020526040902054841415611940575060019392505050565b63ffffffff811661194f5750601e5b8061195981614ce1565b9150508163ffffffff168163ffffffff161415611919575060009392505050565b6005546001600160a01b031633146119a45760405162461bcd60e51b8152600401610ec290614866565b6001600160a01b0382166119f05760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610ec2565b600b5463ffffffff808316600160a01b9092041610611a415760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610ec2565b600b54611a5c90600160a01b900463ffffffff166001614aa9565b63ffffffff168163ffffffff161115611ab35760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610ec2565b600580546001600160a01b039093166001600160a01b031990931692909217909155600b805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b60607f000000000000000000000000000000000000000000000000000000000000000060ff166001600160401b03811115611b3857611b38614dd6565b604051908082528060200260200182016040528015611b8357816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181611b565790505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610d3e57611bbf816001614a91565b60085410611c335760088181548110611bda57611bda614dc0565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050828281518110611c2357611c23614dc0565b6020026020010181905250611c9c565b604051806060016040528060008152602001611c747f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612473565b81526020016000815250828281518110611c9057611c90614dc0565b60200260200101819052505b80611ca681614d01565b915050611b89565b6000600080516020614e028339815191528310611d0d5760405162461bcd60e51b815260206004820181905260248201527f5f6c6566742073686f756c6420626520696e7369646520746865206669656c646044820152606401610ec2565b600080516020614e028339815191528210611d745760405162461bcd60e51b815260206004820152602160248201527f5f72696768742073686f756c6420626520696e7369646520746865206669656c6044820152601960fa1b6064820152608401610ec2565b6040805180820182528481526020810184905290516314d2f97b60e11b8152849184916001600160a01b038816916329a5f2f691611db59190600401614685565b60206040518083038186803b158015611dcd57600080fd5b505afa158015611de1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e059190614489565b925050505b9392505050565b60026004541415611e345760405162461bcd60e51b8152600401610ec2906147e5565b6002600455611e433082612fe1565b604051632404142f60e11b81526001600160a01b0384811660048301526024820183905283811660448301527f00000000000000000000000000000000000000000000000000000000000000001690634808285e90606401600060405180830381600087803b158015611eb557600080fd5b505af1158015611ec9573d6000803e3d6000fd5b505060016004555050505050565b60026004541415611efa5760405162461bcd60e51b8152600401610ec2906147e5565b6002600455611f098282612b3c565b600081602001511315611fe35760208101516040516323b872dd60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916323b872dd91611f6a91339130919060040161458a565b602060405180830381600087803b158015611f8457600080fd5b505af1158015611f98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fbc91906140ca565b5060105481602001511115611fe35760405162461bcd60e51b8152600401610ec29061481c565b6000816020015112156120915780516001600160a01b03166120475760405162461bcd60e51b815260206004820152601e60248201527f43616e277420776974686472617720746f207a65726f206164647265737300006044820152606401610ec2565b600f54816020015161205890614d77565b10156120765760405162461bcd60e51b8152600401610ec290614759565b6120918160000151826020015161208c90614d77565b612fe1565b6060810151156120ad576120ad81604001518260600151612d41565b6120b78282612e88565b50506001600455565b6060816001600160401b038111156120da576120da614dd6565b604051908082528060200260200182016040528015612103578160200160208202803683370190505b50905060005b8281101561217e5761214284848381811061212657612126614dc0565b905060200201356000908152600c602052604090205460ff1690565b1561216c57600182828151811061215b5761215b614dc0565b911515602092830291909101909101525b8061217681614d01565b915050612109565b5092915050565b6005546001600160a01b031633146121af5760405162461bcd60e51b8152600401610ec290614866565b6001600160a01b0382166121fb5760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610ec2565b600b5463ffffffff808316600160a01b909204161061224c5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610ec2565b600b5461226790600160a01b900463ffffffff166001614aa9565b63ffffffff168163ffffffff1611156122be5760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610ec2565b600b805463ffffffff909216600160a01b026001600160c01b03199092166001600160a01b0390931692909217179055565b80516001600160a01b031633146123495760405162461bcd60e51b815260206004820152601c60248201527f6f6e6c79206f776e65722063616e2062652072656769737465726564000000006044820152606401610ec2565b612352816130b8565b50565b61235e846122f0565b612369838383610f71565b50505050565b612378836122f0565b61108c8282611ed7565b6008818154811061239257600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b600054610100900460ff16806123ce575060005460ff16155b6124315760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610ec2565b600054610100900460ff16158015612453576000805461ffff19166101011790555b600f8390556010829055801561108c576000805461ff0019169055505050565b6000816124a157507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b81600114156124d157507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b816002141561250157507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b816003141561253157507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b816004141561256157507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b816005141561259157507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b81600614156125c157507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b81600714156125f157507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b816008141561262157507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b816009141561265157507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a141561268157507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b14156126b157507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c14156126e157507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d141561271157507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e141561274157507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f141561277157507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b81601014156127a157507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b81601114156127d057507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b816012141561280057507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b816013141561283057507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b816014141561286057507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b816015141561289057507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b81601614156128c057507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b81601714156128f057507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b816018141561292057507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b816019141561295057507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a141561298057507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b14156129b057507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c14156129e057507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d1415612a1057507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e1415612a4057507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f1415612a7057507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b6044820152606401610ec2565b919050565b612abb613b3a565b612ac3613b58565b612acb613b3a565b50506040805180820182528351815260208085015181830152825160808082018552868501518286019081526060808901519084015282528451808601865290870151815260a08701518184015281830152835180850190945260c0860151845260e0909501519083015293909150565b60005b826040015151811015612bda57612b8283604001518281518110612b6557612b65614dc0565b60200260200101516000908152600c602052604090205460ff1690565b15612bc85760405162461bcd60e51b8152602060048201526016602482015275125b9c1d5d081a5cc8185b1c9958591e481cdc195b9d60521b6044820152606401610ec2565b80612bd281614d01565b915050612b3f565b50600080516020614e0283398151915281604051602001612bfb919061489d565b6040516020818303038152906040528051906020012060001c612c1e9190614d40565b60a083015114612c705760405162461bcd60e51b815260206004820152601c60248201527f496e636f72726563742065787465726e616c20646174612068617368000000006044820152606401610ec2565b612c8281602001518260600151610e83565b826080015114612ccc5760405162461bcd60e51b8152602060048201526015602482015274125b9d985b1a59081c1d589b1a58c8185b5bdd5b9d605a1b6044820152606401610ec2565b612cd582613104565b60005b82604001515181101561108c576001600c600085604001518481518110612d0157612d01614dc0565b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080612d3990614d01565b915050612cd8565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015612da357600080fd5b505afa158015612db7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ddb9190614489565b9050811561108c57818110612e1e5761108c6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001684846133be565b6040516340c10f1960e01b81526001600160a01b038481166004830152602482018490527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b158015610dd357600080fd5b60608201518051602090910151612e9f9190613410565b506060820151516003547ff3843eddcfcac65d12d9f26261dab50671fdbf5dc44441816c8bbdace2411afd9190612ee690600290640100000000900463ffffffff16614c90565b8360800151604051612efa93929190614718565b60405180910390a160608201517ff3843eddcfcac65d12d9f26261dab50671fdbf5dc44441816c8bbdace2411afd9060016020020151600354612f4d90600190640100000000900463ffffffff16614c90565b8360a00151604051612f6193929190614718565b60405180910390a160005b82604001515181101561108c577f5e58f77bbf94b46d8d896e29753e4458c6e59b48581e20ed58c9558e96f297ce83604001518281518110612fb057612fb0614dc0565b6020026020010151604051612fc791815260200190565b60405180910390a180612fd981614d01565b915050612f6c565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561304357600080fd5b505afa158015613057573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061307b9190614489565b9050818110612e1e5761108c6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001684846133be565b80600001516001600160a01b03167f2c1ca5c14df2aba59d26842c5ff53f6817052ef34f6f7537f8b4c9e3805a5e5082602001516040516130f99190614746565b60405180910390a250565b806040015151600214156132635760008073__$c855d983235a063579a323068f4c8734f9$__63416e8491847f00000000000000000000000000000000000000000000000000000000000000006040518363ffffffff1660e01b815260040161316e92919061490a565b60006040518083038186803b15801561318657600080fd5b505af415801561319a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526131c29190810190614105565b915091506131cf81611694565b61320b5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610ec2565b8251613217908361353e565b61108c5760405162461bcd60e51b815260206004820152601960248201527f496e76616c6964207472616e73616374696f6e2070726f6f66000000000000006044820152606401610ec2565b806040015151601014156133765760008073__$c855d983235a063579a323068f4c8734f9$__637dc45e3f847f00000000000000000000000000000000000000000000000000000000000000006040518363ffffffff1660e01b81526004016132cd92919061490a565b60006040518083038186803b1580156132e557600080fd5b505af41580156132f9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526133219190810190614105565b9150915061332e81611694565b61336a5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610ec2565b82516132179083613668565b60405162461bcd60e51b815260206004820152601760248201527f756e737570706f7274656420696e70757420636f756e740000000000000000006044820152606401610ec2565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261108c9084906136f0565b6000828152600d602052604081205460ff161561343f5760405162461bcd60e51b8152600401610ec2906147a4565b6000828152600d602052604090205460ff161561346e5760405162461bcd60e51b8152600401610ec2906147a4565b600061347a84846137c2565b6000858152600d602090815260408083208054600160ff19918216811790925588855293829020805490941617909255815163ffffffff84168152429181019190915291925085917fe77f587aa74084fff834b53ccbab07695ee4594b9c9d5bfd8a7dd80c556124b5910160405180910390a2827fe77f587aa74084fff834b53ccbab07695ee4594b9c9d5bfd8a7dd80c556124b561351a836001614aa9565b6040805163ffffffff90921682524260208301520160405180910390a29392505050565b600080838060200190518101906135559190614069565b9050600080600061356584612ab3565b600b54604051638041ca5360e01b815293965091945092506001600160a01b031690638041ca53906135c6908690869086908c907f0000000000000000000000000000000000000000000000000000000000000000906001906004016146bc565b60206040518083038186803b1580156135de57600080fd5b505afa1580156135f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061361691906140ca565b94508461365e5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b6044820152606401610ec2565b5050505092915050565b6000808380602001905181019061367f9190614069565b9050600080600061368f84612ab3565b600b54604051638041ca5360e01b815293965091945092506001600160a01b031690638041ca53906135c6908690869086908c907f0000000000000000000000000000000000000000000000000000000000000000906000906004016146bc565b6000613745826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613a2f9092919063ffffffff16565b80519091501561108c578080602001905181019061376391906140ca565b61108c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610ec2565b600354600090640100000000900463ffffffff166138017f00000000000000000000000000000000000000000000000000000000000000006002614b5e565b63ffffffff168163ffffffff1614156138755760405162461bcd60e51b815260206004820152603060248201527f4d65726b6c6520747265652069732066756c6c2e204e6f206d6f7265206c656160448201526f1d995cc818d85b88189948185919195960821b6064820152608401610ec2565b6000613882600283614af6565b905060006138b17f00000000000000000000000000000000000000000000000000000000000000008787611cae565b905060008060015b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff16101561399b576138f8600286614d54565b63ffffffff16613933578392506139148163ffffffff16612473565b63ffffffff82166000908152600160205260409020859055915061394f565b63ffffffff811660009081526001602052604090205492508391505b61397a7f00000000000000000000000000000000000000000000000000000000000000008484611cae565b9350613987600286614af6565b94508061399381614d1c565b9150506138b9565b50600354600090601e906139b69063ffffffff166001614aa9565b6139c09190614d54565b6003805463ffffffff191663ffffffff831690811790915560009081526002602081905260409091208690559091506139fa908790614aa9565b6003805463ffffffff929092166401000000000267ffffffff0000000019909216919091179055509394505050505092915050565b6060610f69848460008585843b613a885760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ec2565b600080866001600160a01b03168587604051613aa4919061456e565b60006040518083038185875af1925050503d8060008114613ae1576040519150601f19603f3d011682016040523d82523d6000602084013e613ae6565b606091505b5091509150613af6828286613b01565b979650505050505050565b60608315613b10575081611e0a565b825115613b205782518084602001fd5b8160405162461bcd60e51b8152600401610ec29190614746565b60405180604001604052806002906020820280368337509192915050565b60405180604001604052806002905b613b6f613b3a565b815260200190600190039081613b675790505090565b8035612aae81614dec565b600082601f830112613ba157600080fd5b604051604081018181106001600160401b0382111715613bc357613bc3614dd6565b8060405250808385604086011115613bda57600080fd5b60005b6002811015613bfc578135835260209283019290910190600101613bdd565b509195945050505050565b600082601f830112613c1857600080fd5b81356020613c2d613c2883614a47565b614a17565b80838252828201915082860187848660051b8901011115613c4d57600080fd5b60005b85811015613c6c57813584529284019290840190600101613c50565b5090979650505050505050565b600082601f830112613c8a57600080fd5b8135613c98613c2882614a6a565b818152846020838601011115613cad57600080fd5b816020850160208301376000918101602001919091529392505050565b600060408284031215613cdc57600080fd5b604051604081016001600160401b038282108183111715613cff57613cff614dd6565b8160405282935084359150613d1382614dec565b90825260208401359080821115613d2957600080fd5b50613d3685828601613c79565b6020830152505092915050565b600060c08284031215613d5557600080fd5b613d5d6149cc565b9050613d6882613b85565b815260208201356020820152613d8060408301613b85565b60408201526060820135606082015260808201356001600160401b0380821115613da957600080fd5b613db585838601613c79565b608084015260a0840135915080821115613dce57600080fd5b50613ddb84828501613c79565b60a08301525092915050565b600060e08284031215613df957600080fd5b613e016149cc565b905081356001600160401b0380821115613e1a57600080fd5b613e2685838601613c79565b83526020840135915080821115613e3c57600080fd5b613e4885838601613c79565b60208401526040840135915080821115613e6157600080fd5b50613e6e84828501613c07565b604083015250613e818360608401613b90565b606082015260a0820135608082015260c082013560a082015292915050565b803563ffffffff81168114612aae57600080fd5b600080600060608486031215613ec957600080fd5b8335613ed481614dec565b92506020840135613ee481614dec565b929592945050506040919091013590565b60008060408385031215613f0857600080fd5b8235613f1381614dec565b946020939093013593505050565b60008060408385031215613f3457600080fd5b8235613f3f81614dec565b9150613f4d60208401613ea0565b90509250929050565b60008060208385031215613f6957600080fd5b82356001600160401b0380821115613f8057600080fd5b818501915085601f830112613f9457600080fd5b813581811115613fa357600080fd5b8660208260051b8501011115613fb857600080fd5b60209290920196919550909350505050565b600060208284031215613fdc57600080fd5b81356001600160401b03811115613ff257600080fd5b610f6984828501613c07565b600061010080838503121561401257600080fd5b83601f84011261402157600080fd5b6140296149f4565b808486848701111561403a57600080fd5b600093505b600884101561405f5780358352600193909301926020928301920161403f565b5095945050505050565b600061010080838503121561407d57600080fd5b83601f84011261408c57600080fd5b6140946149f4565b80848684870111156140a557600080fd5b600093505b600884101561405f578051835260019390930192602092830192016140aa565b6000602082840312156140dc57600080fd5b81518015158114610f6757600080fd5b6000602082840312156140fe57600080fd5b5035919050565b6000806040838503121561411857600080fd5b82516001600160401b038082111561412f57600080fd5b818501915085601f83011261414357600080fd5b81516020614153613c2883614a6a565b828152888284870101111561416757600080fd5b61417683838301848801614cb5565b8782015190965093508284111561418c57600080fd5b838701935087601f8501126141a057600080fd5b835192506141b0613c2884614a47565b8381528181019250848201600585901b860183018a10156141d057600080fd5b600095505b848610156141f35780518452600195909501949282019282016141d5565b5080955050505050509250929050565b60008060006060848603121561421857600080fd5b833561422381614dec565b95602085013595506040909401359392505050565b6000806040838503121561424b57600080fd5b50508035926020909101359150565b60006020828403121561426c57600080fd5b81356001600160401b0381111561428257600080fd5b610f6984828501613cca565b6000806000606084860312156142a357600080fd5b83356001600160401b03808211156142ba57600080fd5b6142c687838801613cca565b945060208601359150808211156142dc57600080fd5b6142e887838801613de7565b935060408601359150808211156142fe57600080fd5b5061430b86828701613d43565b9150509250925092565b6000806000806080858703121561432b57600080fd5b84356001600160401b038082111561434257600080fd5b61434e88838901613cca565b9550602087013591508082111561436457600080fd5b61437088838901613de7565b9450604087013591508082111561438657600080fd5b5061439387828801613d43565b92505060608501356143a481614dec565b939692955090935050565b600080604083850312156143c257600080fd5b82356001600160401b03808211156143d957600080fd5b6143e586838701613de7565b935060208501359150808211156143fb57600080fd5b5061440885828601613d43565b9150509250929050565b60008060006060848603121561442757600080fd5b83356001600160401b038082111561443e57600080fd5b61444a87838801613de7565b9450602086013591508082111561446057600080fd5b5061446d86828701613d43565b925050604084013561447e81614dec565b809150509250925092565b60006020828403121561449b57600080fd5b5051919050565b6000806000606084860312156144b757600080fd5b505081359360208301359350604090920135919050565b600080604083850312156144e157600080fd5b82359150613f4d60208401613ea0565b8060005b60028110156123695761450984835161451f565b60409390930192602091909101906001016144f5565b8060005b6002811015612369578151845260209384019390910190600101614523565b6000815180845261455a816020860160208601614cb5565b601f01601f19169290920160200192915050565b60008251614580818460208701614cb5565b9190910192915050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6020808252825182820181905260009190848201906040850190845b818110156145e85783511515835292840192918401916001016145ca565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156145e857835183529284019291840191600101614610565b602080825282518282018190526000919060409081850190868401855b828110156146785781518051855286810151878601528501518585015260609093019290850190600101614649565b5091979650505050505050565b60408101610be6828461451f565b61010081016146a2828661451f565b6146af60408301856144f1565b610f6960c083018461451f565b60006101606146cb838a61451f565b6146d860408401896144f1565b6146e560c084018861451f565b806101008401526146f881840187614542565b60ff95909516610120840152505090151561014090910152949350505050565b83815263ffffffff8316602082015260606040820152600061473d6060830184614542565b95945050505050565b602081526000611e0a6020830184614542565b6020808252602b908201527f616d6f756e74206973206c657373207468616e206d696e696d616c576974686460408201526a1c985dd85b105b5bdd5b9d60aa1b606082015260800190565b60208082526021908201527f54686520636f6d6d69746d656e7420686173206265656e207375626d697474656040820152601960fa1b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252602a908201527f616d6f756e74206973206c6172676572207468616e206d6178696d756d4465706040820152691bdcda5d105b5bdd5b9d60b21b606082015260800190565b60208082526019908201527f73656e646572206973206e6f74207468652068616e646c657200000000000000604082015260600190565b60208152600060018060a01b03808451166020840152602084015160408401528060408501511660608401525060608301516080830152608083015160c060a08401526148ed60e0840182614542565b905060a0840151601f198483030160c085015261473d8282614542565b604081526000835160e06040840152614927610120840182614542565b9050602080860151603f19808685030160608701526149468483614542565b6040890151878203909201608088015281518082529184019450600092508301905b808310156149885784518252938301936001929092019190830190614968565b506060880151935061499d60a087018561451f565b608088015160e087015260a088015161010087015260ff87168387015293506149c39050565b50509392505050565b60405160c081016001600160401b03811182821017156149ee576149ee614dd6565b60405290565b60405161010081016001600160401b03811182821017156149ee576149ee614dd6565b604051601f8201601f191681016001600160401b0381118282101715614a3f57614a3f614dd6565b604052919050565b60006001600160401b03821115614a6057614a60614dd6565b5060051b60200190565b60006001600160401b03821115614a8357614a83614dd6565b50601f01601f191660200190565b60008219821115614aa457614aa4614d94565b500190565b600063ffffffff808316818516808303821115614ac857614ac8614d94565b01949350505050565b600060ff821660ff84168060ff03821115614aee57614aee614d94565b019392505050565b600063ffffffff80841680614b0d57614b0d614daa565b92169190910492915050565b600181815b80851115614b56578163ffffffff04821115614b3c57614b3c614d94565b80851615614b4957918102915b93841c9390800290614b1e565b509250929050565b600063ffffffff610f69818516828516600082614b7d57506001610be6565b81614b8a57506000610be6565b8160018114614ba05760028114614baa57614bdb565b6001915050610be6565b60ff841115614bbb57614bbb614d94565b6001841b915063ffffffff821115614bd557614bd5614d94565b50610be6565b5060208310610133831016604e8410600b8410161715614c12575081810a63ffffffff811115614c0d57614c0d614d94565b610be6565b614c1c8383614b19565b8063ffffffff04821115614c3257614c32614d94565b029392505050565b60008083128015600160ff1b850184121615614c5857614c58614d94565b6001600160ff1b0384018313811615614c7357614c73614d94565b50500390565b600082821015614c8b57614c8b614d94565b500390565b600063ffffffff83811690831681811015614cad57614cad614d94565b039392505050565b60005b83811015614cd0578181015183820152602001614cb8565b838111156123695750506000910152565b600063ffffffff821680614cf757614cf7614d94565b6000190192915050565b6000600019821415614d1557614d15614d94565b5060010190565b600063ffffffff80831681811415614d3657614d36614d94565b6001019392505050565b600082614d4f57614d4f614daa565b500690565b600063ffffffff80841680614d6b57614d6b614daa565b92169190910692915050565b6000600160ff1b821415614d8d57614d8d614d94565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461235257600080fdfe30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220f4d3c91ce7307a467d4c8894af94afdd6fbedd710b5d9673e33d6fdf0eb5280664736f6c63430008050033"; + "0x610100604052600380546001600160401b0319169055600b805463ffffffff60a01b191690553480156200003257600080fd5b5060405162005a5238038062005a528339810160408190526200005591620008da565b85858585848185848684848383838183818160008263ffffffff1611620000cf5760405162461bcd60e51b815260206004820152602360248201527f5f6c6576656c732073686f756c642062652067726561746572207468616e207a60448201526265726f60e81b60648201526084015b60405180910390fd5b60208263ffffffff1610620001275760405162461bcd60e51b815260206004820152601e60248201527f5f6c6576656c732073686f756c64206265206c657373207468616e20333200006044820152606401620000c6565b60e09190911b6001600160e01b03191660a05260601b6001600160601b03191660805260005b8263ffffffff168163ffffffff1610156200019e576200017363ffffffff821662000274565b63ffffffff8216600090815260016020526040902055806200019581620009a3565b9150506200014d565b50620001bc620001b06001846200097b565b63ffffffff1662000274565b6000805260026020527fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b5550506001600455600580546001600160a01b03199081166001600160a01b039687161790915560f89190911b7fff000000000000000000000000000000000000000000000000000000000000001660c052600b80549091169790931696909617909155505050505060609790971b6001600160601b03191660e05250620009f99950505050505050505050565b600081620002a357507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b8160011415620002d457507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156200030557507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b81600314156200033657507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b81600414156200036757507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b81600514156200039857507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b8160061415620003c957507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b8160071415620003fa57507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b81600814156200042b57507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b81600914156200045c57507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a14156200048d57507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b1415620004be57507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c1415620004ef57507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156200052057507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e14156200055157507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f14156200058257507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b8160101415620005b357507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b8160111415620005e357507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b81601214156200061457507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b81601314156200064557507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b81601414156200067657507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b8160151415620006a757507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b8160161415620006d857507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b81601714156200070957507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b81601814156200073a57507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b81601914156200076b57507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a14156200079c57507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b1415620007cd57507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c1415620007fe57507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d14156200082f57507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e14156200086057507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f14156200089157507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b815260206004820152601360248201527f496e646578206f7574206f6620626f756e6473000000000000000000000000006044820152606401620000c6565b60008060008060008060c08789031215620008f457600080fd5b86516200090181620009e0565b602088015190965063ffffffff811681146200091c57600080fd5b60408801519095506200092f81620009e0565b60608801519094506200094281620009e0565b60808801519093506200095581620009e0565b60a088015190925060ff811681146200096d57600080fd5b809150509295509295509295565b600063ffffffff838116908316818110156200099b576200099b620009ca565b039392505050565b600063ffffffff80831681811415620009c057620009c0620009ca565b6001019392505050565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0381168114620009f657600080fd5b50565b60805160601c60a05160e01c60c05160f81c60e05160601c614f4f62000b0360003960008181610b8301528181610e0101528181610e950152818161167e0152818161171c0152818161195001528181611f3201528181611ff301528181612e1a01528181612eb801528181612f05015281816130ba015261315201526000818161069b01528181610c6301528181610ccd015281816114cd015281816117cb01528181611bc001528181611c4c015281816131f3015281816133520152818161365c01526137860152600081816105cc01528181610d5601528181611d0b0152818161389c015261397c015260008181610ac30152818161394c0152613a150152614f4f6000f3fe6080604052600436106103815760003560e01c80638ea3099e116101d1578063c80916d411610102578063e8295588116100a0578063f5ab0dd61161006f578063f5ab0dd614610b12578063fa73168714610b41578063fc0c546a14610b71578063fc7e9c6f14610ba557600080fd5b8063e829558814610a5d578063ec73295914610a7d578063ed33639f14610ab1578063f178e47c14610ae557600080fd5b8063dbc916b8116100dc578063dbc916b8146109a5578063e4a30116146109e0578063e5285dcc14610a00578063e70ea87c14610a3057600080fd5b8063c80916d414610950578063c9be725014610970578063cd87a3b41461099057600080fd5b80639ff800631161016f578063b7566a6711610149578063b7566a67146108d9578063ba70f757146108f9578063bc063e1a14610705578063c2b40ae41461092357600080fd5b80639ff80063146105ee578063a0d192f514610899578063b2bc6e0f146108b957600080fd5b806392156311116101ab578063921563111461080957806395c87d1a146108395780639bbca3a91461084c5780639fa12d0b1461086c57600080fd5b80638ea3099e146107b65780638f1c56bd146107d657806390eeb02b146107ec57600080fd5b80634c830cbd116102b657806371523c3211610254578063839df94511610223578063839df9451461071d578063840b27911461074d5780638b7e8782146107635780638c0d34d81461079457600080fd5b806371523c321461068957806372c1ad03146106cf57806378abb49b146106ef5780637fe24ffe1461070557600080fd5b80635d2d766c116102905780635d2d766c1461060e578063616e0957146106415780636ad481f3146106615780636d9833e31461066957600080fd5b80634c830cbd1461058e5780634ecf518b146105ba5780634f401241146105ee57600080fd5b80633408e4701161032357806342d90711116102fd57806342d907111461050357806343e7119f1461052357806344347ba91461055b578063460b53e31461056e57600080fd5b80633408e470146104bb578063414a37ba146104ce5780634167bb1e146104f057600080fd5b80631e6276171161035f5780631e6276171461041e5780632063e3d3146104405780632570b7b4146104555780632b7ac3f31461048357600080fd5b80630b27fb9a1461038657806311e4dcb9146103be57806317cc915c146103ee575b600080fd5b34801561039257600080fd5b50600b54600160a01b900463ffffffff165b60405163ffffffff90911681526020015b60405180910390f35b3480156103ca57600080fd5b506103de6103d93660046142f9565b610bca565b60405190151581526020016103b5565b3480156103fa57600080fd5b506103de6104093660046141ad565b600c6020526000908152604090205460ff1681565b34801561042a57600080fd5b50610433610c5f565b6040516103b591906146b5565b61045361044e366004613fb6565b610db5565b005b34801561046157600080fd5b506104756104703660046142f9565b610ef6565b6040519081526020016103b5565b34801561048f57600080fd5b50600b546104a3906001600160a01b031681565b6040516001600160a01b0390911681526020016103b5565b3480156104c757600080fd5b5046610475565b3480156104da57600080fd5b50610475600080516020614efa83398151915281565b6104536104fe3660046144d3565b610fe4565b34801561050f57600080fd5b5061045361051e3660046142f9565b611104565b34801561052f57600080fd5b5061047561053e36600461458f565b600960209081526000928352604080842090915290825290205481565b610453610569366004614563565b611139565b34801561057a57600080fd5b50610453610589366004613fb6565b611667565b34801561059a57600080fd5b506105a36116b7565b60405165ffffffffffff90911681526020016103b5565b3480156105c657600080fd5b506103a47f000000000000000000000000000000000000000000000000000000000000000081565b3480156105fa57600080fd5b50610453610609366004613fb6565b611705565b34801561061a57600080fd5b506103a46106293660046141ad565b600a6020526000908152604090205463ffffffff1681565b34801561064d57600080fd5b506103de61065c36600461408b565b611755565b610453611939565b34801561067557600080fd5b506103de6106843660046141ad565b6119c0565b34801561069557600080fd5b506106bd7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016103b5565b3480156106db57600080fd5b506104536106ea366004613fe2565b611a3b565b3480156106fb57600080fd5b5061047560105481565b34801561071157600080fd5b50610475600160f81b81565b34801561072957600080fd5b506103de6107383660046141ad565b600d6020526000908152604090205460ff1681565b34801561075957600080fd5b50610475600f5481565b34801561076f57600080fd5b5061077b600160f81b81565b6040516001600160f01b031990911681526020016103b5565b3480156107a057600080fd5b506107a9611bbc565b6040516103b591906146ed565b3480156107c257600080fd5b506104756107d13660046142c4565b611d6f565b3480156107e257600080fd5b50610475600e5481565b3480156107f857600080fd5b506003546103a49063ffffffff1681565b34801561081557600080fd5b506103de6108243660046141ad565b60009081526007602052604090205460ff1690565b610453610847366004613f75565b611ed2565b34801561085857600080fd5b50610453610867366004614470565b611f98565b34801561087857600080fd5b5061088c610887366004614017565b612181565b6040516103b5919061466f565b3480156108a557600080fd5b506104536108b4366004613fe2565b612246565b3480156108c557600080fd5b506104536108d436600461431b565b6123b1565b3480156108e557600080fd5b506104536108f43660046143d6565b612416565b34801561090557600080fd5b5060035463ffffffff16600090815260026020526040902054610475565b34801561092f57600080fd5b5061047561093e3660046141ad565b60026020526000908152604090205481565b34801561095c57600080fd5b506005546104a3906001600160a01b031681565b34801561097c57600080fd5b5061045361098b36600461434f565b612430565b34801561099c57600080fd5b506103a4601e81565b3480156109b157600080fd5b506109c56109c03660046141ad565b612443565b604080519384526020840192909252908201526060016103b5565b3480156109ec57600080fd5b506104536109fb3660046142f9565b612476565b348015610a0c57600080fd5b506103de610a1b3660046141ad565b6000908152600c602052604090205460ff1690565b348015610a3c57600080fd5b50610475610a4b3660046141ad565b60066020526000908152604090205481565b348015610a6957600080fd5b50610475610a783660046141ad565b612534565b348015610a8957600080fd5b506104757f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c81565b348015610abd57600080fd5b506104a37f000000000000000000000000000000000000000000000000000000000000000081565b348015610af157600080fd5b50610475610b003660046141ad565b60016020526000908152604090205481565b348015610b1e57600080fd5b50610b32610b2d3660046140bf565b612b74565b6040516103b593929190614754565b348015610b4d57600080fd5b506103de610b5c3660046141ad565b60076020526000908152604090205460ff1681565b348015610b7d57600080fd5b506104a37f000000000000000000000000000000000000000000000000000000000000000081565b348015610bb157600080fd5b506003546103a490640100000000900463ffffffff1681565b600081610bd957506000610c59565b6000838152600a602052604090205463ffffffff16805b600085815260096020908152604080832063ffffffff85168452909152902054841415610c2257600192505050610c59565b63ffffffff8116610c315750601e5b80610c3b81614dd9565b9150508163ffffffff168163ffffffff161415610bf0576000925050505b92915050565b60607f000000000000000000000000000000000000000000000000000000000000000060ff166001600160401b03811115610c9c57610c9c614ece565b604051908082528060200260200182016040528015610cc5578160200160208202803683370190505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610db157610d01816001614b52565b60085410610d515760088181548110610d1c57610d1c614eb8565b906000526020600020906003020160010154828281518110610d4057610d40614eb8565b602002602001018181525050610d9f565b610d807f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612534565b828281518110610d9257610d92614eb8565b6020026020010181815250505b80610da981614df9565b915050610ccb565b5090565b6001600160a01b038216610e6357803414610dcf57600080fd5b604051633d97186b60e11b81523360048201526001600160a01b038381166024830152600060448301523060648301527f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d69034906084016000604051808303818588803b158015610e4657600080fd5b505af1158015610e5a573d6000803e3d6000fd5b50505050505050565b604051633d97186b60e11b81523360048201526001600160a01b038381166024830152604482018390523060648301527f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d6906084015b600060405180830381600087803b158015610eda57600080fd5b505af1158015610eee573d6000803e3d6000fd5b505050505050565b6000600160f81b8210610f3e5760405162461bcd60e51b815260206004820152600b60248201526a496e76616c69642066656560a81b60448201526064015b60405180910390fd5b610f4b600160f81b614e6f565b83138015610f5c5750600160f81b83125b610f9d5760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a5908195e1d08185b5bdd5b9d60721b6044820152606401610f35565b6000610fa98385614cfb565b90506000811215610fda57610fbd81614e6f565b610fd590600080516020614efa833981519152614d3a565b610fdc565b805b949350505050565b610fee8383612bfd565b60008260200151131561102f57601054826020015111156110215760405162461bcd60e51b8152600401610f35906148dd565b61102f818360200151610db5565b6000826020015112156110d95781516001600160a01b03166110935760405162461bcd60e51b815260206004820152601e60248201527f43616e277420776974686472617720746f207a65726f206164647265737300006044820152606401610f35565b600f5482602001516110a490614e6f565b10156110c25760405162461bcd60e51b8152600401610f359061481a565b6110d9818360000151846020015161084790614e6f565b6060820151156110f5576110f582604001518360600151612e02565b6110ff8383612f49565b505050565b6005546001600160a01b0316331461112e5760405162461bcd60e51b8152600401610f3590614927565b600f91909155601055565b6005546001600160a01b031633146111635760405162461bcd60e51b8152600401610f3590614927565b600260045414156111865760405162461bcd60e51b8152600401610f35906148a6565b60026004908155604051639215631160e01b8152908101849052309063921563119060240160206040518083038186803b1580156111c357600080fd5b505afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb919061418b565b156114c65760008381526007602052604090205460ff166112845760405162461bcd60e51b815260206004820152603760248201527f436861696e206d75737420626520696e74656772617465642066726f6d20746860448201527f6520627269646765206265666f726520757064617465730000000000000000006064820152608401610f35565b6000838152600660205260409020546008805483929081106112a8576112a8614eb8565b906000526020600020906003020160020154106113075760405162461bcd60e51b815260206004820152601e60248201527f4e6577206c65616620696e646578206d757374206265206772656174657200006044820152606401610f35565b60008381526006602052604090205460088054909190811061132b5761132b614eb8565b9060005260206000209060030201600201546201000061134b9190614b52565b81106113a95760405162461bcd60e51b815260206004820152602760248201527f4e6577206c65616620696e646578206d7573742077697468696e20325e3136206044820152667570646174657360c81b6064820152608401610f35565b60008381526006602090815260409182902054825160608101845286815291820185905291810183905260088054839081106113e7576113e7614eb8565b60009182526020808320845160039093020191825583810151600180840191909155604094850151600290930192909255878352600a9052918120549091601e9161143a9163ffffffff90911690614b6a565b6114449190614e4c565b6000868152600a60209081526040808320805463ffffffff191663ffffffff86169081179091556009835281842090845282529182902087905581518881529081018690529081018690529091507f675e61f04bcf314a9c310a93f2346f417a03d704c1caf9c6af8a65ad8addfa3f9060600160405180910390a1505061165d565b60085460ff7f0000000000000000000000000000000000000000000000000000000000000000161161153a5760405162461bcd60e51b815260206004820152601a60248201527f5468697320416e63686f722069732061742063617061636974790000000000006044820152606401610f35565b6000838152600760209081526040808320805460ff19166001908117909155600880548351606080820186528a82528187018a81528287018a815295840185559388528151600384027ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee381019190915593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee485015593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee590930192909255888652600685528386208190556009855283862086805285528386208890558351898152948501879052928401879052919391927fcf4749969bace1552af6a97fe7e4affedf68875511f9746c6332eb40647b3054910160405180910390a15050505b5050600160045550565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca6938890610ec09033908690869060040161464b565b60408051600160f81b602082018190524660e01b6001600160e01b031981166022840152835180840360060181526026909301909352600092916116fa81614d76565b60d01c935050505090565b60405163130e405b60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063261c80b690610ec09033908690869060040161464b565b600061177a8260008151811061176d5761176d614eb8565b60200260200101516119c0565b6117c65760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f742066696e6420796f7572206d65726b6c6520726f6f74000000006044820152606401610f35565b6117f17f00000000000000000000000000000000000000000000000000000000000000006001614b92565b60ff168251146118435760405162461bcd60e51b815260206004820152601b60248201527f496e636f727265637420726f6f74206172726179206c656e67746800000000006044820152606401610f35565b60005b6008548110156119305760006008828154811061186557611865614eb8565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505090506118d18160000151858460016118b49190614b52565b815181106118c4576118c4614eb8565b6020026020010151610bca565b61191d5760405162461bcd60e51b815260206004820152601760248201527f4e65696768626f7220726f6f74206e6f7420666f756e640000000000000000006044820152606401610f35565b508061192881614df9565b915050611846565b50600192915050565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca6938890349061198c903390600090819060040161464b565b6000604051808303818588803b1580156119a557600080fd5b505af11580156119b9573d6000803e3d6000fd5b5050505050565b6000816119cf57506000919050565b60035463ffffffff16805b63ffffffff8116600090815260026020526040902054841415611a01575060019392505050565b63ffffffff8116611a105750601e5b80611a1a81614dd9565b9150508163ffffffff168163ffffffff1614156119da575060009392505050565b6005546001600160a01b03163314611a655760405162461bcd60e51b8152600401610f3590614927565b6001600160a01b038216611ab15760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610f35565b600b5463ffffffff808316600160a01b9092041610611b025760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610f35565b600b54611b1d90600160a01b900463ffffffff166001614b6a565b63ffffffff168163ffffffff161115611b745760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610f35565b600580546001600160a01b039093166001600160a01b031990931692909217909155600b805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b60607f000000000000000000000000000000000000000000000000000000000000000060ff166001600160401b03811115611bf957611bf9614ece565b604051908082528060200260200182016040528015611c4457816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181611c175790505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610db157611c80816001614b52565b60085410611cf45760088181548110611c9b57611c9b614eb8565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050828281518110611ce457611ce4614eb8565b6020026020010181905250611d5d565b604051806060016040528060008152602001611d357f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612534565b81526020016000815250828281518110611d5157611d51614eb8565b60200260200101819052505b80611d6781614df9565b915050611c4a565b6000600080516020614efa8339815191528310611dce5760405162461bcd60e51b815260206004820181905260248201527f5f6c6566742073686f756c6420626520696e7369646520746865206669656c646044820152606401610f35565b600080516020614efa8339815191528210611e355760405162461bcd60e51b815260206004820152602160248201527f5f72696768742073686f756c6420626520696e7369646520746865206669656c6044820152601960fa1b6064820152608401610f35565b6040805180820182528481526020810184905290516314d2f97b60e11b8152849184916001600160a01b038816916329a5f2f691611e769190600401614746565b60206040518083038186803b158015611e8e57600080fd5b505afa158015611ea2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec6919061454a565b925050505b9392505050565b60026004541415611ef55760405162461bcd60e51b8152600401610f35906148a6565b6002600455611f0430826130a2565b604051632404142f60e11b81526001600160a01b0384811660048301526024820183905283811660448301527f00000000000000000000000000000000000000000000000000000000000000001690634808285e90606401600060405180830381600087803b158015611f7657600080fd5b505af1158015611f8a573d6000803e3d6000fd5b505060016004555050505050565b60026004541415611fbb5760405162461bcd60e51b8152600401610f35906148a6565b6002600455611fca8282612bfd565b6000816020015113156120a45760208101516040516323b872dd60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916323b872dd9161202b91339130919060040161464b565b602060405180830381600087803b15801561204557600080fd5b505af1158015612059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207d919061418b565b50601054816020015111156120a45760405162461bcd60e51b8152600401610f35906148dd565b6000816020015112156121525780516001600160a01b03166121085760405162461bcd60e51b815260206004820152601e60248201527f43616e277420776974686472617720746f207a65726f206164647265737300006044820152606401610f35565b600f54816020015161211990614e6f565b10156121375760405162461bcd60e51b8152600401610f359061481a565b6121528160000151826020015161214d90614e6f565b6130a2565b60608101511561216e5761216e81604001518260600151612e02565b6121788282612f49565b50506001600455565b6060816001600160401b0381111561219b5761219b614ece565b6040519080825280602002602001820160405280156121c4578160200160208202803683370190505b50905060005b8281101561223f576122038484838181106121e7576121e7614eb8565b905060200201356000908152600c602052604090205460ff1690565b1561222d57600182828151811061221c5761221c614eb8565b911515602092830291909101909101525b8061223781614df9565b9150506121ca565b5092915050565b6005546001600160a01b031633146122705760405162461bcd60e51b8152600401610f3590614927565b6001600160a01b0382166122bc5760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610f35565b600b5463ffffffff808316600160a01b909204161061230d5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610f35565b600b5461232890600160a01b900463ffffffff166001614b6a565b63ffffffff168163ffffffff16111561237f5760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610f35565b600b805463ffffffff909216600160a01b026001600160c01b03199092166001600160a01b0390931692909217179055565b80516001600160a01b0316331461240a5760405162461bcd60e51b815260206004820152601c60248201527f6f6e6c79206f776e65722063616e2062652072656769737465726564000000006044820152606401610f35565b61241381613179565b50565b61241f846123b1565b61242a838383610fe4565b50505050565b612439836123b1565b6110ff8282611f98565b6008818154811061245357600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b600054610100900460ff168061248f575060005460ff16155b6124f25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610f35565b600054610100900460ff16158015612514576000805461ffff19166101011790555b600f839055601082905580156110ff576000805461ff0019169055505050565b60008161256257507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b816001141561259257507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156125c257507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b81600314156125f257507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b816004141561262257507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b816005141561265257507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b816006141561268257507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b81600714156126b257507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b81600814156126e257507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b816009141561271257507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a141561274257507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b141561277257507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c14156127a257507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156127d257507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e141561280257507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f141561283257507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b816010141561286257507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b816011141561289157507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b81601214156128c157507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b81601314156128f157507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b816014141561292157507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b816015141561295157507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b816016141561298157507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b81601714156129b157507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b81601814156129e157507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b8160191415612a1157507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a1415612a4157507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b1415612a7157507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c1415612aa157507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d1415612ad157507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e1415612b0157507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f1415612b3157507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b6044820152606401610f35565b919050565b612b7c613bfb565b612b84613c19565b612b8c613bfb565b50506040805180820182528351815260208085015181830152825160808082018552868501518286019081526060808901519084015282528451808601865290870151815260a08701518184015281830152835180850190945260c0860151845260e0909501519083015293909150565b60005b826040015151811015612c9b57612c4383604001518281518110612c2657612c26614eb8565b60200260200101516000908152600c602052604090205460ff1690565b15612c895760405162461bcd60e51b8152602060048201526016602482015275125b9c1d5d081a5cc8185b1c9958591e481cdc195b9d60521b6044820152606401610f35565b80612c9381614df9565b915050612c00565b50600080516020614efa83398151915281604051602001612cbc919061495e565b6040516020818303038152906040528051906020012060001c612cdf9190614e38565b60a083015114612d315760405162461bcd60e51b815260206004820152601c60248201527f496e636f72726563742065787465726e616c20646174612068617368000000006044820152606401610f35565b612d4381602001518260600151610ef6565b826080015114612d8d5760405162461bcd60e51b8152602060048201526015602482015274125b9d985b1a59081c1d589b1a58c8185b5bdd5b9d605a1b6044820152606401610f35565b612d96826131c5565b60005b8260400151518110156110ff576001600c600085604001518481518110612dc257612dc2614eb8565b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080612dfa90614df9565b915050612d99565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015612e6457600080fd5b505afa158015612e78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9c919061454a565b905081156110ff57818110612edf576110ff6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016848461347f565b6040516340c10f1960e01b81526001600160a01b038481166004830152602482018490527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b158015610e4657600080fd5b60608201518051602090910151612f6091906134d1565b506060820151516003547ff3843eddcfcac65d12d9f26261dab50671fdbf5dc44441816c8bbdace2411afd9190612fa790600290640100000000900463ffffffff16614d51565b8360800151604051612fbb939291906147d9565b60405180910390a160608201517ff3843eddcfcac65d12d9f26261dab50671fdbf5dc44441816c8bbdace2411afd906001602002015160035461300e90600190640100000000900463ffffffff16614d51565b8360a00151604051613022939291906147d9565b60405180910390a160005b8260400151518110156110ff577f5e58f77bbf94b46d8d896e29753e4458c6e59b48581e20ed58c9558e96f297ce8360400151828151811061307157613071614eb8565b602002602001015160405161308891815260200190565b60405180910390a18061309a81614df9565b91505061302d565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561310457600080fd5b505afa158015613118573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061313c919061454a565b9050818110612edf576110ff6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016848461347f565b80600001516001600160a01b03167f2c1ca5c14df2aba59d26842c5ff53f6817052ef34f6f7537f8b4c9e3805a5e5082602001516040516131ba9190614807565b60405180910390a250565b806040015151600214156133245760008073__$c855d983235a063579a323068f4c8734f9$__63416e8491847f00000000000000000000000000000000000000000000000000000000000000006040518363ffffffff1660e01b815260040161322f9291906149cb565b60006040518083038186803b15801561324757600080fd5b505af415801561325b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261328391908101906141c6565b9150915061329081611755565b6132cc5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610f35565b82516132d890836135ff565b6110ff5760405162461bcd60e51b815260206004820152601960248201527f496e76616c6964207472616e73616374696f6e2070726f6f66000000000000006044820152606401610f35565b806040015151601014156134375760008073__$c855d983235a063579a323068f4c8734f9$__637dc45e3f847f00000000000000000000000000000000000000000000000000000000000000006040518363ffffffff1660e01b815260040161338e9291906149cb565b60006040518083038186803b1580156133a657600080fd5b505af41580156133ba573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526133e291908101906141c6565b915091506133ef81611755565b61342b5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610f35565b82516132d89083613729565b60405162461bcd60e51b815260206004820152601760248201527f756e737570706f7274656420696e70757420636f756e740000000000000000006044820152606401610f35565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526110ff9084906137b1565b6000828152600d602052604081205460ff16156135005760405162461bcd60e51b8152600401610f3590614865565b6000828152600d602052604090205460ff161561352f5760405162461bcd60e51b8152600401610f3590614865565b600061353b8484613883565b6000858152600d602090815260408083208054600160ff19918216811790925588855293829020805490941617909255815163ffffffff84168152429181019190915291925085917fe77f587aa74084fff834b53ccbab07695ee4594b9c9d5bfd8a7dd80c556124b5910160405180910390a2827fe77f587aa74084fff834b53ccbab07695ee4594b9c9d5bfd8a7dd80c556124b56135db836001614b6a565b6040805163ffffffff90921682524260208301520160405180910390a29392505050565b60008083806020019051810190613616919061412a565b9050600080600061362684612b74565b600b54604051638041ca5360e01b815293965091945092506001600160a01b031690638041ca5390613687908690869086908c907f00000000000000000000000000000000000000000000000000000000000000009060019060040161477d565b60206040518083038186803b15801561369f57600080fd5b505afa1580156136b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d7919061418b565b94508461371f5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b6044820152606401610f35565b5050505092915050565b60008083806020019051810190613740919061412a565b9050600080600061375084612b74565b600b54604051638041ca5360e01b815293965091945092506001600160a01b031690638041ca5390613687908690869086908c907f00000000000000000000000000000000000000000000000000000000000000009060009060040161477d565b6000613806826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613af09092919063ffffffff16565b8051909150156110ff5780806020019051810190613824919061418b565b6110ff5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610f35565b600354600090640100000000900463ffffffff166138c27f00000000000000000000000000000000000000000000000000000000000000006002614c1f565b63ffffffff168163ffffffff1614156139365760405162461bcd60e51b815260206004820152603060248201527f4d65726b6c6520747265652069732066756c6c2e204e6f206d6f7265206c656160448201526f1d995cc818d85b88189948185919195960821b6064820152608401610f35565b6000613943600283614bb7565b905060006139727f00000000000000000000000000000000000000000000000000000000000000008787611d6f565b905060008060015b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff161015613a5c576139b9600286614e4c565b63ffffffff166139f4578392506139d58163ffffffff16612534565b63ffffffff821660009081526001602052604090208590559150613a10565b63ffffffff811660009081526001602052604090205492508391505b613a3b7f00000000000000000000000000000000000000000000000000000000000000008484611d6f565b9350613a48600286614bb7565b945080613a5481614e14565b91505061397a565b50600354600090601e90613a779063ffffffff166001614b6a565b613a819190614e4c565b6003805463ffffffff191663ffffffff83169081179091556000908152600260208190526040909120869055909150613abb908790614b6a565b6003805463ffffffff929092166401000000000267ffffffff0000000019909216919091179055509394505050505092915050565b6060610fdc848460008585843b613b495760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610f35565b600080866001600160a01b03168587604051613b65919061462f565b60006040518083038185875af1925050503d8060008114613ba2576040519150601f19603f3d011682016040523d82523d6000602084013e613ba7565b606091505b5091509150613bb7828286613bc2565b979650505050505050565b60608315613bd1575081611ecb565b825115613be15782518084602001fd5b8160405162461bcd60e51b8152600401610f359190614807565b60405180604001604052806002906020820280368337509192915050565b60405180604001604052806002905b613c30613bfb565b815260200190600190039081613c285790505090565b8035612b6f81614ee4565b600082601f830112613c6257600080fd5b604051604081018181106001600160401b0382111715613c8457613c84614ece565b8060405250808385604086011115613c9b57600080fd5b60005b6002811015613cbd578135835260209283019290910190600101613c9e565b509195945050505050565b600082601f830112613cd957600080fd5b81356020613cee613ce983614b08565b614ad8565b80838252828201915082860187848660051b8901011115613d0e57600080fd5b60005b85811015613d2d57813584529284019290840190600101613d11565b5090979650505050505050565b600082601f830112613d4b57600080fd5b8135613d59613ce982614b2b565b818152846020838601011115613d6e57600080fd5b816020850160208301376000918101602001919091529392505050565b600060408284031215613d9d57600080fd5b604051604081016001600160401b038282108183111715613dc057613dc0614ece565b8160405282935084359150613dd482614ee4565b90825260208401359080821115613dea57600080fd5b50613df785828601613d3a565b6020830152505092915050565b600060c08284031215613e1657600080fd5b613e1e614a8d565b9050613e2982613c46565b815260208201356020820152613e4160408301613c46565b60408201526060820135606082015260808201356001600160401b0380821115613e6a57600080fd5b613e7685838601613d3a565b608084015260a0840135915080821115613e8f57600080fd5b50613e9c84828501613d3a565b60a08301525092915050565b600060e08284031215613eba57600080fd5b613ec2614a8d565b905081356001600160401b0380821115613edb57600080fd5b613ee785838601613d3a565b83526020840135915080821115613efd57600080fd5b613f0985838601613d3a565b60208401526040840135915080821115613f2257600080fd5b50613f2f84828501613cc8565b604083015250613f428360608401613c51565b606082015260a0820135608082015260c082013560a082015292915050565b803563ffffffff81168114612b6f57600080fd5b600080600060608486031215613f8a57600080fd5b8335613f9581614ee4565b92506020840135613fa581614ee4565b929592945050506040919091013590565b60008060408385031215613fc957600080fd5b8235613fd481614ee4565b946020939093013593505050565b60008060408385031215613ff557600080fd5b823561400081614ee4565b915061400e60208401613f61565b90509250929050565b6000806020838503121561402a57600080fd5b82356001600160401b038082111561404157600080fd5b818501915085601f83011261405557600080fd5b81358181111561406457600080fd5b8660208260051b850101111561407957600080fd5b60209290920196919550909350505050565b60006020828403121561409d57600080fd5b81356001600160401b038111156140b357600080fd5b610fdc84828501613cc8565b60006101008083850312156140d357600080fd5b83601f8401126140e257600080fd5b6140ea614ab5565b80848684870111156140fb57600080fd5b600093505b600884101561412057803583526001939093019260209283019201614100565b5095945050505050565b600061010080838503121561413e57600080fd5b83601f84011261414d57600080fd5b614155614ab5565b808486848701111561416657600080fd5b600093505b60088410156141205780518352600193909301926020928301920161416b565b60006020828403121561419d57600080fd5b81518015158114610fda57600080fd5b6000602082840312156141bf57600080fd5b5035919050565b600080604083850312156141d957600080fd5b82516001600160401b03808211156141f057600080fd5b818501915085601f83011261420457600080fd5b81516020614214613ce983614b2b565b828152888284870101111561422857600080fd5b61423783838301848801614dad565b8782015190965093508284111561424d57600080fd5b838701935087601f85011261426157600080fd5b83519250614271613ce984614b08565b8381528181019250848201600585901b860183018a101561429157600080fd5b600095505b848610156142b4578051845260019590950194928201928201614296565b5080955050505050509250929050565b6000806000606084860312156142d957600080fd5b83356142e481614ee4565b95602085013595506040909401359392505050565b6000806040838503121561430c57600080fd5b50508035926020909101359150565b60006020828403121561432d57600080fd5b81356001600160401b0381111561434357600080fd5b610fdc84828501613d8b565b60008060006060848603121561436457600080fd5b83356001600160401b038082111561437b57600080fd5b61438787838801613d8b565b9450602086013591508082111561439d57600080fd5b6143a987838801613ea8565b935060408601359150808211156143bf57600080fd5b506143cc86828701613e04565b9150509250925092565b600080600080608085870312156143ec57600080fd5b84356001600160401b038082111561440357600080fd5b61440f88838901613d8b565b9550602087013591508082111561442557600080fd5b61443188838901613ea8565b9450604087013591508082111561444757600080fd5b5061445487828801613e04565b925050606085013561446581614ee4565b939692955090935050565b6000806040838503121561448357600080fd5b82356001600160401b038082111561449a57600080fd5b6144a686838701613ea8565b935060208501359150808211156144bc57600080fd5b506144c985828601613e04565b9150509250929050565b6000806000606084860312156144e857600080fd5b83356001600160401b03808211156144ff57600080fd5b61450b87838801613ea8565b9450602086013591508082111561452157600080fd5b5061452e86828701613e04565b925050604084013561453f81614ee4565b809150509250925092565b60006020828403121561455c57600080fd5b5051919050565b60008060006060848603121561457857600080fd5b505081359360208301359350604090920135919050565b600080604083850312156145a257600080fd5b8235915061400e60208401613f61565b8060005b600281101561242a576145ca8483516145e0565b60409390930192602091909101906001016145b6565b8060005b600281101561242a5781518452602093840193909101906001016145e4565b6000815180845261461b816020860160208601614dad565b601f01601f19169290920160200192915050565b60008251614641818460208701614dad565b9190910192915050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6020808252825182820181905260009190848201906040850190845b818110156146a957835115158352928401929184019160010161468b565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156146a9578351835292840192918401916001016146d1565b602080825282518282018190526000919060409081850190868401855b82811015614739578151805185528681015187860152850151858501526060909301929085019060010161470a565b5091979650505050505050565b60408101610c5982846145e0565b610100810161476382866145e0565b61477060408301856145b2565b610fdc60c08301846145e0565b600061016061478c838a6145e0565b61479960408401896145b2565b6147a660c08401886145e0565b806101008401526147b981840187614603565b60ff95909516610120840152505090151561014090910152949350505050565b83815263ffffffff831660208201526060604082015260006147fe6060830184614603565b95945050505050565b602081526000611ecb6020830184614603565b6020808252602b908201527f616d6f756e74206973206c657373207468616e206d696e696d616c576974686460408201526a1c985dd85b105b5bdd5b9d60aa1b606082015260800190565b60208082526021908201527f54686520636f6d6d69746d656e7420686173206265656e207375626d697474656040820152601960fa1b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252602a908201527f616d6f756e74206973206c6172676572207468616e206d6178696d756d4465706040820152691bdcda5d105b5bdd5b9d60b21b606082015260800190565b60208082526019908201527f73656e646572206973206e6f74207468652068616e646c657200000000000000604082015260600190565b60208152600060018060a01b03808451166020840152602084015160408401528060408501511660608401525060608301516080830152608083015160c060a08401526149ae60e0840182614603565b905060a0840151601f198483030160c08501526147fe8282614603565b604081526000835160e060408401526149e8610120840182614603565b9050602080860151603f1980868503016060870152614a078483614603565b6040890151878203909201608088015281518082529184019450600092508301905b80831015614a495784518252938301936001929092019190830190614a29565b5060608801519350614a5e60a08701856145e0565b608088015160e087015260a088015161010087015260ff8716838701529350614a849050565b50509392505050565b60405160c081016001600160401b0381118282101715614aaf57614aaf614ece565b60405290565b60405161010081016001600160401b0381118282101715614aaf57614aaf614ece565b604051601f8201601f191681016001600160401b0381118282101715614b0057614b00614ece565b604052919050565b60006001600160401b03821115614b2157614b21614ece565b5060051b60200190565b60006001600160401b03821115614b4457614b44614ece565b50601f01601f191660200190565b60008219821115614b6557614b65614e8c565b500190565b600063ffffffff808316818516808303821115614b8957614b89614e8c565b01949350505050565b600060ff821660ff84168060ff03821115614baf57614baf614e8c565b019392505050565b600063ffffffff80841680614bce57614bce614ea2565b92169190910492915050565b600181815b80851115614c17578163ffffffff04821115614bfd57614bfd614e8c565b80851615614c0a57918102915b93841c9390800290614bdf565b509250929050565b600063ffffffff610fdc818516828516600082614c3e57506001610c59565b81614c4b57506000610c59565b8160018114614c615760028114614c6b57614c9c565b6001915050610c59565b60ff841115614c7c57614c7c614e8c565b6001841b915063ffffffff821115614c9657614c96614e8c565b50610c59565b5060208310610133831016604e8410600b8410161715614cd3575081810a63ffffffff811115614cce57614cce614e8c565b610c59565b614cdd8383614bda565b8063ffffffff04821115614cf357614cf3614e8c565b029392505050565b60008083128015600160ff1b850184121615614d1957614d19614e8c565b6001600160ff1b0384018313811615614d3457614d34614e8c565b50500390565b600082821015614d4c57614d4c614e8c565b500390565b600063ffffffff83811690831681811015614d6e57614d6e614e8c565b039392505050565b805160208201516001600160d01b03198082169291906006831015614da55780818460060360031b1b83161693505b505050919050565b60005b83811015614dc8578181015183820152602001614db0565b8381111561242a5750506000910152565b600063ffffffff821680614def57614def614e8c565b6000190192915050565b6000600019821415614e0d57614e0d614e8c565b5060010190565b600063ffffffff80831681811415614e2e57614e2e614e8c565b6001019392505050565b600082614e4757614e47614ea2565b500690565b600063ffffffff80841680614e6357614e63614ea2565b92169190910692915050565b6000600160ff1b821415614e8557614e85614e8c565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461241357600080fdfe30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a26469706673582212204fc8bb8fbe4a6180511c555fb50945c51d46905392782489123980074f5f213364736f6c63430008050033"; type VAnchorConstructorParams = | [linkLibraryAddresses: VAnchorLibraryAddresses, signer?: Signer] diff --git a/packages/utils/src/utils.ts b/packages/utils/src/utils.ts index eda35fdc6..6e19d8906 100644 --- a/packages/utils/src/utils.ts +++ b/packages/utils/src/utils.ts @@ -97,4 +97,15 @@ export function getExtDataHash({ ); const hash = ethers.utils.keccak256(encodedData) return BigNumber.from(hash).mod(FIELD_SIZE) +} + +/** + * Computes the updated chain ID with chain type. + * @param chainID Chain ID to encode into augmented chain ID Type, defaults to hardhat's chain ID. + * @returns + */ +export const getChainIdType = async (chainID: number = 31337): Promise => { + const CHAIN_TYPE = '0x0100'; + const chainIdType = CHAIN_TYPE + toFixedHex(chainID, 4).substr(2); + return BigInt(chainIdType); } \ No newline at end of file diff --git a/test/bridge/signatureBridge.test.ts b/test/bridge/signatureBridge.test.ts index 4d74386cf..80f7ffad0 100644 --- a/test/bridge/signatureBridge.test.ts +++ b/test/bridge/signatureBridge.test.ts @@ -81,7 +81,7 @@ describe('multichain tests for erc20 bridges', () => { await tokenInstance1.mintTokens(signers[1].address, '100000000000000000000000000'); }); - it('create 2 side bridge for one token', async () => { + it.only('create 2 side bridge for one token', async () => { bridge2WebbEthInput = { anchorInputs: { From ec6cc536edc657f97eb0c603938d8364b3bad302 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 26 Jan 2022 16:00:54 -0500 Subject: [PATCH 04/15] Update to modified chain ID --- packages/utils/src/utils.ts | 4 +- test/bridge/signatureBridge.test.ts | 186 +++++++++++++--------------- 2 files changed, 90 insertions(+), 100 deletions(-) diff --git a/packages/utils/src/utils.ts b/packages/utils/src/utils.ts index 6e19d8906..096a1df7b 100644 --- a/packages/utils/src/utils.ts +++ b/packages/utils/src/utils.ts @@ -104,8 +104,8 @@ export function getExtDataHash({ * @param chainID Chain ID to encode into augmented chain ID Type, defaults to hardhat's chain ID. * @returns */ -export const getChainIdType = async (chainID: number = 31337): Promise => { +export const getChainIdType = (chainID: number = 31337): number => { const CHAIN_TYPE = '0x0100'; const chainIdType = CHAIN_TYPE + toFixedHex(chainID, 4).substr(2); - return BigInt(chainIdType); + return Number(BigInt(chainIdType)); } \ No newline at end of file diff --git a/test/bridge/signatureBridge.test.ts b/test/bridge/signatureBridge.test.ts index 80f7ffad0..22bc84126 100644 --- a/test/bridge/signatureBridge.test.ts +++ b/test/bridge/signatureBridge.test.ts @@ -13,7 +13,7 @@ import { Anchor } from '@webb-tools/anchors'; import { SignatureBridge } from '@webb-tools/bridges'; import { BridgeInput } from '@webb-tools/interfaces'; import { MintableToken } from '@webb-tools/tokens'; -import { fetchComponentsFromFilePaths, ZkComponents } from '@webb-tools/utils'; +import { fetchComponentsFromFilePaths, getChainIdType, ZkComponents } from '@webb-tools/utils'; import { BigNumber } from '@ethersproject/bignumber'; import { Signer } from 'ethers'; import { startGanacheServer } from '../helpers/startGanacheServer'; @@ -21,6 +21,9 @@ import { startGanacheServer } from '../helpers/startGanacheServer'; export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); describe('multichain tests for erc20 bridges', () => { + const chainID1 = getChainIdType(31337); + const chainID2 = getChainIdType(1337); + const chainID3 = getChainIdType(9999); // setup ganache networks let ganacheServer2: any; let ganacheServer3: any; @@ -63,10 +66,10 @@ describe('multichain tests for erc20 bridges', () => { let tokenInstance2: MintableToken; let tokenInstance3: MintableToken; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); + let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:chainID2'); ganacheProvider2.pollingInterval = 1; let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); - let ganacheProvider3 = new ethers.providers.JsonRpcProvider('http://localhost:9999'); + let ganacheProvider3 = new ethers.providers.JsonRpcProvider('http://localhost:chainID3'); ganacheProvider3.pollingInterval = 1; let ganacheWallet3 = new ethers.Wallet('745ee040ef2b087f075dc7d314fa06797ed2ffd4ab59a4cc35c0a33e8d2b7791', ganacheProvider3); @@ -82,35 +85,32 @@ describe('multichain tests for erc20 bridges', () => { }); it.only('create 2 side bridge for one token', async () => { - bridge2WebbEthInput = { anchorInputs: { asset: { - 31337: [tokenInstance1.contract.address], - 1337: [tokenInstance2.contract.address], + [chainID1]: [tokenInstance1.contract.address], + [chainID2]: [tokenInstance2.contract.address], }, anchorSizes: ['1000000000000000000', '100000000000000000000', '10000000000000000000000'], }, - chainIDs: [31337, 1337] + chainIDs: [chainID1, chainID2] }; const signers = await ethers.getSigners(); const deploymentConfig = { - 31337: signers[1], - 1337: ganacheWallet2, + [chainID1]: signers[1], + [chainID2]: ganacheWallet2, }; const bridge = await SignatureBridge.deployFixedDepositBridge(bridge2WebbEthInput, deploymentConfig, zkComponents2); // Should be able to retrieve individual anchors - const chainId1 = 31337; - const chainId2 = 1337; const anchorSize = '1000000000000000000'; - const anchor1: Anchor = bridge.getAnchor(chainId1, anchorSize)! as Anchor; - const anchor2: Anchor = bridge.getAnchor(chainId2, anchorSize)! as Anchor; + const anchor1: Anchor = bridge.getAnchor(chainID1, anchorSize)! as Anchor; + const anchor2: Anchor = bridge.getAnchor(chainID2, anchorSize)! as Anchor; // Should be able to retrieve the token address (so we can mint tokens for test scenario) - const webbTokenAddress = bridge.getWebbTokenAddress(chainId1); + const webbTokenAddress = bridge.getWebbTokenAddress(chainID1); const webbToken = await MintableToken.tokenFromAddress(webbTokenAddress!, signers[1]); const tx = await webbToken.mintTokens(signers[2].address, '100000000000000000000000'); @@ -118,10 +118,10 @@ describe('multichain tests for erc20 bridges', () => { const sourceAnchorRootBefore = await anchor1.contract.getLastRoot(); // Deposit on the bridge - const depositNote = await bridge.deposit(chainId2, anchorSize, signers[2]); + const depositNote = await bridge.deposit(chainID2, anchorSize, signers[2]); // Check the state of anchors after deposit - let edgeIndex = await anchor2.contract.edgeIndex(chainId1); + let edgeIndex = await anchor2.contract.edgeIndex(chainID1); const sourceAnchorRootAfter = await anchor1.contract.getLastRoot(); const destAnchorEdgeAfter = await anchor2.contract.edgeList(edgeIndex); @@ -132,62 +132,57 @@ describe('multichain tests for erc20 bridges', () => { await bridge.withdraw(depositNote, anchorSize, signers[1].address, signers[1].address, ganacheWallet2); - const webbTokenAddress2 = bridge.getWebbTokenAddress(chainId2); + const webbTokenAddress2 = bridge.getWebbTokenAddress(chainID2); const webbToken2 = await MintableToken.tokenFromAddress(webbTokenAddress2!, ganacheWallet2); const webbTokenBalance2 = await webbToken2.getBalance(signers[1].address); assert.deepEqual(webbTokenBalance2, ethers.BigNumber.from(anchorSize)); }); - it('create 3 side bridge for one token', async () => { + it.only('create 3 side bridge for one token', async () => { bridge3WebbEthInput = { anchorInputs: { asset: { - 31337: [tokenInstance1.contract.address], - 1337: [tokenInstance2.contract.address], - 9999: [tokenInstance3.contract.address], + [chainID1]: [tokenInstance1.contract.address], + [chainID2]: [tokenInstance2.contract.address], + [chainID3]: [tokenInstance3.contract.address], }, anchorSizes: ['1000000000000000000', '100000000000000000000', '10000000000000000000000'], }, - chainIDs: [31337, 1337, 9999] + chainIDs: [chainID1, chainID2, chainID3] }; const signers = await ethers.getSigners(); const deploymentConfig = { - 31337: signers[1], - 1337: ganacheWallet2, - 9999: ganacheWallet3, + [chainID1]: signers[1], + [chainID2]: ganacheWallet2, + [chainID3]: ganacheWallet3, }; const bridge = await SignatureBridge.deployFixedDepositBridge(bridge3WebbEthInput, deploymentConfig, zkComponents3); - - // Should be able to retrieve individual anchors - const chainId1 = 31337; - const chainId2 = 1337; - const chainId3 = 9999; const anchorSize = '1000000000000000000'; - const anchor1: Anchor = bridge.getAnchor(chainId1, anchorSize)! as Anchor; - const anchor2: Anchor = bridge.getAnchor(chainId2, anchorSize)! as Anchor; - const anchor3: Anchor = bridge.getAnchor(chainId3, anchorSize)! as Anchor; + const anchor1: Anchor = bridge.getAnchor(chainID1, anchorSize)! as Anchor; + const anchor2: Anchor = bridge.getAnchor(chainID2, anchorSize)! as Anchor; + const anchor3: Anchor = bridge.getAnchor(chainID3, anchorSize)! as Anchor; // get the state of anchors before deposit const sourceAnchorRootBefore = await anchor1.contract.getLastRoot(); // Should be able to retrieve the token address (so we can mint tokens for test scenario) - const webbTokenAddress = bridge.webbTokenAddresses.get(chainId1); + const webbTokenAddress = bridge.webbTokenAddresses.get(chainID1); const webbToken = await MintableToken.tokenFromAddress(webbTokenAddress!, signers[1]); const tx = await webbToken.mintTokens(signers[2].address, '100000000000000000000000'); // Deposit on the bridge with dest chainID and - const depositNote = await bridge.deposit(chainId2, anchorSize, signers[2]); + const depositNote = await bridge.deposit(chainID2, anchorSize, signers[2]); // Check the state of anchors after deposit const sourceAnchorRootAfter = await anchor1.contract.getLastRoot(); - let edgeIndex = await anchor2.contract.edgeIndex(chainId1); + let edgeIndex = await anchor2.contract.edgeIndex(chainID1); const destAnchorEdge2After = await anchor2.contract.edgeList(edgeIndex); - edgeIndex = await anchor3.contract.edgeIndex(chainId1); + edgeIndex = await anchor3.contract.edgeIndex(chainID1); const destAnchorEdge3After = await anchor3.contract.edgeList(edgeIndex); // make sure the roots / anchors state have changed @@ -196,29 +191,29 @@ describe('multichain tests for erc20 bridges', () => { assert.deepStrictEqual(destAnchorEdge2After.root, destAnchorEdge3After.root); }).timeout(40000); - it('create 2 side bridge for multiple tokens', async () => { + it.only('create 2 side bridge for multiple tokens', async () => { bridge2WebbEthInput = { anchorInputs: { asset: { - 31337: [tokenInstance1.contract.address], - 1337: [tokenInstance2.contract.address], + [chainID1]: [tokenInstance1.contract.address], + [chainID2]: [tokenInstance2.contract.address], }, anchorSizes: ['1000000000000000000', '100000000000000000000', '10000000000000000000000'], }, - chainIDs: [31337, 1337] + chainIDs: [chainID1, chainID2] }; }); - it('create 2 side bridge for native and erc20 token', async () => { + it.only('create 2 side bridge for native and erc20 token', async () => { bridge2WebbEthInput = { anchorInputs: { asset: { - 31337: [tokenInstance1.contract.address, '0'], - 1337: [tokenInstance2.contract.address, '0x0000000000000000000000000000000000000000'], + [chainID1]: [tokenInstance1.contract.address, '0'], + [chainID2]: [tokenInstance2.contract.address, '0x0000000000000000000000000000000000000000'], }, anchorSizes: ['1000000000000000000', '100000000000000000000', '10000000000000000000000'], }, - chainIDs: [31337, 1337] + chainIDs: [chainID1, chainID2] }; }); }).timeout(50000); @@ -230,9 +225,7 @@ describe('multichain tests for erc20 bridges', () => { let existingToken2: MintableToken; let bridge: SignatureBridge; - const chainId1 = 31337; - const chainId2 = 1337; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); + let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:chainID2'); ganacheProvider2.pollingInterval = 1; let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); @@ -255,50 +248,50 @@ describe('multichain tests for erc20 bridges', () => { const existingTokenBridgeConfig = { anchorInputs: { asset: { - [chainId1]: [existingToken1.contract.address], - [chainId2]: [existingToken2.contract.address], + [chainID1]: [existingToken1.contract.address], + [chainID2]: [existingToken2.contract.address], }, anchorSizes: ['1000000000000000000', '100000000000000000000', '10000000000000000000000'], }, - chainIDs: [chainId1, chainId2] + chainIDs: [chainID1, chainID2] }; // setup the config for deployers of contracts (admins) const deploymentConfig = { - [chainId1]: signers[1], - [chainId2]: ganacheWallet2, + [chainID1]: signers[1], + [chainID2]: ganacheWallet2, } // deploy the bridge bridge = await SignatureBridge.deployFixedDepositBridge(existingTokenBridgeConfig, deploymentConfig, zkComponents2); // make one deposit so the edge exists - await bridge.wrapAndDeposit(chainId2, existingToken1.contract.address, '1000000000000000000', signers[1]); - await bridge.wrapAndDeposit(chainId1, existingToken2.contract.address, '1000000000000000000', ganacheWallet2); + await bridge.wrapAndDeposit(chainID2, existingToken1.contract.address, '1000000000000000000', signers[1]); + await bridge.wrapAndDeposit(chainID1, existingToken2.contract.address, '1000000000000000000', ganacheWallet2); }) describe('#bridging', () => { - it('should withdraw successfully from latest deposit', async () => { + it.only('should withdraw successfully from latest deposit', async () => { // Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); const anchorSize = '1000000000000000000'; - const anchor2: Anchor = bridge.getAnchor(chainId2, anchorSize)! as Anchor; - const anchor1: Anchor = bridge.getAnchor(chainId1, anchorSize)! as Anchor; - let edgeIndex = await anchor2.contract.edgeIndex(chainId1); + const anchor2: Anchor = bridge.getAnchor(chainID2, anchorSize)! as Anchor; + const anchor1: Anchor = bridge.getAnchor(chainID1, anchorSize)! as Anchor; + let edgeIndex = await anchor2.contract.edgeIndex(chainID1); const destAnchorEdge2Before = await anchor2.contract.edgeList(edgeIndex); const token = await MintableToken.tokenFromAddress(existingToken2.contract.address, ganacheWallet2); const startingBalanceDest = await token.getBalance(signers[2].address); // Make a deposit - const depositNote1 = await bridge.wrapAndDeposit(chainId2, existingToken1.contract.address, anchorSize, signers[1]); + const depositNote1 = await bridge.wrapAndDeposit(chainID2, existingToken1.contract.address, anchorSize, signers[1]); // Check the leaf index is incremented const destAnchorEdge2After = await anchor2.contract.edgeList(edgeIndex); assert.deepEqual(destAnchorEdge2Before.latestLeafIndex.add(1), destAnchorEdge2After.latestLeafIndex); // Check that the anchor has the appropriate amount of wrapped token balance - const wrappedTokenAddress = bridge.getWebbTokenAddress(chainId1); + const wrappedTokenAddress = bridge.getWebbTokenAddress(chainID1); const wrappedToken = await MintableToken.tokenFromAddress(wrappedTokenAddress!, signers[1]); const anchorWrappedTokenBalance = await wrappedToken.getBalance(anchor1.contract.address); assert.deepEqual(anchorWrappedTokenBalance, (ethers.BigNumber.from(anchorSize)).mul(2)); @@ -316,19 +309,19 @@ describe('multichain tests for erc20 bridges', () => { assert.deepEqual(endingBalanceDest, startingBalanceDest.add(anchorSize)); }) - it('should withdraw on hardhat from ganache deposit', async () => { + it.only('should withdraw on hardhat from ganache deposit', async () => { // Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); const anchorSize = '1000000000000000000'; - const anchor1: Anchor = bridge.getAnchor(chainId1, anchorSize)! as Anchor; - let edgeIndex = await anchor1.contract.edgeIndex(chainId2); + const anchor1: Anchor = bridge.getAnchor(chainID1, anchorSize)! as Anchor; + let edgeIndex = await anchor1.contract.edgeIndex(chainID2); const destAnchorEdge2Before = await anchor1.contract.edgeList(edgeIndex); const token = await MintableToken.tokenFromAddress(existingToken1.contract.address, signers[1]); const startingBalanceDest = await token.getBalance(signers[2].address); // Make a deposit - const depositNote1 = await bridge.wrapAndDeposit(chainId1, existingToken2.contract.address, anchorSize, ganacheWallet2); + const depositNote1 = await bridge.wrapAndDeposit(chainID1, existingToken2.contract.address, anchorSize, ganacheWallet2); // Check the leaf index is incremented const destAnchorEdge2After = await anchor1.contract.edgeList(edgeIndex); @@ -342,20 +335,20 @@ describe('multichain tests for erc20 bridges', () => { assert.deepStrictEqual(endingBalanceDest, startingBalanceDest.add(anchorSize)); }) - it('should update multiple deposits and withdraw historic deposit', async () => { + it.only('should update multiple deposits and withdraw historic deposit', async () => { // Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); const anchorSize = '1000000000000000000'; - const anchor2: Anchor = bridge.getAnchor(chainId2, anchorSize)! as Anchor; - let edgeIndex = await anchor2.contract.edgeIndex(chainId1); + const anchor2: Anchor = bridge.getAnchor(chainID2, anchorSize)! as Anchor; + let edgeIndex = await anchor2.contract.edgeIndex(chainID1); const destAnchorEdge2Before = await anchor2.contract.edgeList(edgeIndex); const webbToken = await MintableToken.tokenFromAddress(existingToken2.contract.address, ganacheWallet2); const startingBalanceDest = await webbToken.getBalance(signers[1].address); // Make two deposits - const depositNote1 = await bridge.wrapAndDeposit(chainId2, existingToken1.contract.address, anchorSize, signers[1]); - const depositNote2 = await bridge.wrapAndDeposit(chainId2, existingToken1.contract.address, anchorSize, signers[1]); + const depositNote1 = await bridge.wrapAndDeposit(chainID2, existingToken1.contract.address, anchorSize, signers[1]); + const depositNote2 = await bridge.wrapAndDeposit(chainID2, existingToken1.contract.address, anchorSize, signers[1]); // Check the leaf index is incremented by two const destAnchorEdge2After = await anchor2.contract.edgeList(edgeIndex); @@ -369,20 +362,20 @@ describe('multichain tests for erc20 bridges', () => { assert.deepStrictEqual(endingBalanceDest, startingBalanceDest.add(anchorSize)); }); - it('should update multiple deposits and withdraw historic deposit from ganache', async () => { + it.only('should update multiple deposits and withdraw historic deposit from ganache', async () => { // Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); const anchorSize = '1000000000000000000'; - const anchor2: Anchor = bridge.getAnchor(chainId1, anchorSize)! as Anchor; - let edgeIndex = await anchor2.contract.edgeIndex(chainId2); + const anchor2: Anchor = bridge.getAnchor(chainID1, anchorSize)! as Anchor; + let edgeIndex = await anchor2.contract.edgeIndex(chainID2); const destAnchorEdge2Before = await anchor2.contract.edgeList(edgeIndex); const webbToken = await MintableToken.tokenFromAddress(existingToken1.contract.address, signers[1]); const startingBalanceDest = await webbToken.getBalance(signers[1].address); // Make two deposits - const depositNote1 = await bridge.wrapAndDeposit(chainId1, existingToken2.contract.address, anchorSize, ganacheWallet2); - const depositNote2 = await bridge.wrapAndDeposit(chainId1, existingToken2.contract.address, anchorSize, ganacheWallet2); + const depositNote1 = await bridge.wrapAndDeposit(chainID1, existingToken2.contract.address, anchorSize, ganacheWallet2); + const depositNote2 = await bridge.wrapAndDeposit(chainID1, existingToken2.contract.address, anchorSize, ganacheWallet2); // Check the leaf index is incremented by two const destAnchorEdge2After = await anchor2.contract.edgeList(edgeIndex); @@ -406,15 +399,12 @@ describe('multichain tests for erc20 bridges', () => { let existingTokenSrc4: MintableToken; let bridge: SignatureBridge; - const chainId1 = 31337; - const chainId2 = 1337; - const chainId3 = 9999; const chainId4 = 4444; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); + let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:chainID2'); ganacheProvider2.pollingInterval = 1; let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); - let ganacheProvider3 = new ethers.providers.JsonRpcProvider('http://localhost:9999'); + let ganacheProvider3 = new ethers.providers.JsonRpcProvider('http://localhost:chainID3'); ganacheProvider3.pollingInterval = 1; let ganacheWallet3 = new ethers.Wallet('745ee040ef2b087f075dc7d314fa06797ed2ffd4ab59a4cc35c0a33e8d2b7791', ganacheProvider3); @@ -440,21 +430,21 @@ describe('multichain tests for erc20 bridges', () => { const existingTokenBridgeConfig: BridgeInput = { anchorInputs: { asset: { - [chainId1]: [existingTokenSrc.contract.address], - [chainId2]: [existingTokenSrc2.contract.address], - [chainId3]: [existingTokenSrc3.contract.address], + [chainID1]: [existingTokenSrc.contract.address], + [chainID2]: [existingTokenSrc2.contract.address], + [chainID3]: [existingTokenSrc3.contract.address], [chainId4]: [existingTokenSrc4.contract.address], }, anchorSizes: ['1000000000000000000', '100000000000000000000'], }, - chainIDs: [chainId1, chainId2, chainId3, chainId4] + chainIDs: [chainID1, chainID2, chainID3, chainId4] }; // setup the config for deployers of contracts (admins) const deploymentConfig = { - [chainId1]: signers[1], - [chainId2]: ganacheWallet2, - [chainId3]: ganacheWallet3, + [chainID1]: signers[1], + [chainID2]: ganacheWallet2, + [chainID3]: ganacheWallet3, [chainId4]: ganacheWallet4, } @@ -476,28 +466,28 @@ describe('multichain tests for erc20 bridges', () => { } }) - it('should withdraw successfully from latest deposits on all chains', async () => { + it.only('should withdraw successfully from latest deposits on all chains', async () => { const signers = await ethers.getSigners(); // make deposits so edges exists - await bridge.wrapAndDeposit(chainId2, existingTokenSrc.contract.address, '1000000000000000000', signers[1]); - await bridge.wrapAndDeposit(chainId3, existingTokenSrc2.contract.address, '1000000000000000000', ganacheWallet2); + await bridge.wrapAndDeposit(chainID2, existingTokenSrc.contract.address, '1000000000000000000', signers[1]); + await bridge.wrapAndDeposit(chainID3, existingTokenSrc2.contract.address, '1000000000000000000', ganacheWallet2); await bridge.wrapAndDeposit(chainId4, existingTokenSrc3.contract.address, '1000000000000000000', ganacheWallet3); - await bridge.wrapAndDeposit(chainId1, existingTokenSrc4.contract.address, '1000000000000000000', ganacheWallet4); + await bridge.wrapAndDeposit(chainID1, existingTokenSrc4.contract.address, '1000000000000000000', ganacheWallet4); // Fetch information about the anchor to be updated. const anchorSize = '1000000000000000000'; - const webbTokenAddress1 = bridge.getWebbTokenAddress(chainId1)!; + const webbTokenAddress1 = bridge.getWebbTokenAddress(chainID1)!; const tokenAddress1 = existingTokenSrc.contract.address; - const anchor1: Anchor = bridge.getAnchor(chainId1, anchorSize)! as Anchor; - let edgeIndex = await anchor1.contract.edgeIndex(chainId1); + const anchor1: Anchor = bridge.getAnchor(chainID1, anchorSize)! as Anchor; + let edgeIndex = await anchor1.contract.edgeIndex(chainID1); const destAnchorEdge1Before = await anchor1.contract.edgeList(edgeIndex); let cumulativeBalance = await calculateCumulativeBalance(signers[1].address, tokenAddress1, webbTokenAddress1, signers[1]); let currentBalance = cumulativeBalance; // Make a deposit on the second chain - const depositNote1 = await bridge.wrapAndDeposit(chainId1, existingTokenSrc2.contract.address, anchorSize, ganacheWallet2); + const depositNote1 = await bridge.wrapAndDeposit(chainID1, existingTokenSrc2.contract.address, anchorSize, ganacheWallet2); // Check the leaf index is incremented const destAnchorEdge1After = await anchor1.contract.edgeList(edgeIndex); @@ -512,9 +502,9 @@ describe('multichain tests for erc20 bridges', () => { currentBalance = cumulativeBalance; // make a deposit from the third connected chain - edgeIndex = await anchor1.contract.edgeIndex(chainId3); + edgeIndex = await anchor1.contract.edgeIndex(chainID3); const destAnchorEdge3Before = await anchor1.contract.edgeList(edgeIndex); - const depositNote3 = await bridge.wrapAndDeposit(chainId1, existingTokenSrc3.contract.address, anchorSize, ganacheWallet3); + const depositNote3 = await bridge.wrapAndDeposit(chainID1, existingTokenSrc3.contract.address, anchorSize, ganacheWallet3); // Check the leaf index is incremented const destAnchorEdge3After = await anchor1.contract.edgeList(edgeIndex); @@ -532,7 +522,7 @@ describe('multichain tests for erc20 bridges', () => { // make a deposit from the fourth connected chain edgeIndex = await anchor1.contract.edgeIndex(chainId4); const destAnchorEdge4Before = await anchor1.contract.edgeList(edgeIndex); - const depositNote4 = await bridge.wrapAndDeposit(chainId1, existingTokenSrc4.contract.address, anchorSize, ganacheWallet4); + const depositNote4 = await bridge.wrapAndDeposit(chainID1, existingTokenSrc4.contract.address, anchorSize, ganacheWallet4); // Check the leaf index is incremented const destAnchorEdge4After = await anchor1.contract.edgeList(edgeIndex); From 136c1358b5a51f93f07a1f5607ef7590ab88ab4e Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 26 Jan 2022 16:13:42 -0500 Subject: [PATCH 05/15] Fix port --- packages/bridges/src/SignatureBridge.ts | 2 -- test/bridge/signatureBridge.test.ts | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/bridges/src/SignatureBridge.ts b/packages/bridges/src/SignatureBridge.ts index e0532b4f2..ca213ff80 100644 --- a/packages/bridges/src/SignatureBridge.ts +++ b/packages/bridges/src/SignatureBridge.ts @@ -104,8 +104,6 @@ export class SignatureBridge { // and anchors in the subArrays of thhe same index should be linked together let createdAnchors: IAnchor[][] = []; - - for (let chainID of bridgeInput.chainIDs) { const adminAddress = await deployers[chainID].getAddress(); diff --git a/test/bridge/signatureBridge.test.ts b/test/bridge/signatureBridge.test.ts index 22bc84126..ad96ed99f 100644 --- a/test/bridge/signatureBridge.test.ts +++ b/test/bridge/signatureBridge.test.ts @@ -66,10 +66,10 @@ describe('multichain tests for erc20 bridges', () => { let tokenInstance2: MintableToken; let tokenInstance3: MintableToken; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:chainID2'); + let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); ganacheProvider2.pollingInterval = 1; let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); - let ganacheProvider3 = new ethers.providers.JsonRpcProvider('http://localhost:chainID3'); + let ganacheProvider3 = new ethers.providers.JsonRpcProvider('http://localhost:9999'); ganacheProvider3.pollingInterval = 1; let ganacheWallet3 = new ethers.Wallet('745ee040ef2b087f075dc7d314fa06797ed2ffd4ab59a4cc35c0a33e8d2b7791', ganacheProvider3); From b910bcdafebe6db978c1ff15b36d61da8ac113fa Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 26 Jan 2022 16:14:36 -0500 Subject: [PATCH 06/15] Fix port --- test/bridge/signatureBridge.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/bridge/signatureBridge.test.ts b/test/bridge/signatureBridge.test.ts index ad96ed99f..92f04c580 100644 --- a/test/bridge/signatureBridge.test.ts +++ b/test/bridge/signatureBridge.test.ts @@ -225,7 +225,7 @@ describe('multichain tests for erc20 bridges', () => { let existingToken2: MintableToken; let bridge: SignatureBridge; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:chainID2'); + let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); ganacheProvider2.pollingInterval = 1; let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); @@ -400,11 +400,11 @@ describe('multichain tests for erc20 bridges', () => { let bridge: SignatureBridge; const chainId4 = 4444; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:chainID2'); + let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); ganacheProvider2.pollingInterval = 1; let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); - let ganacheProvider3 = new ethers.providers.JsonRpcProvider('http://localhost:chainID3'); + let ganacheProvider3 = new ethers.providers.JsonRpcProvider('http://localhost:9999'); ganacheProvider3.pollingInterval = 1; let ganacheWallet3 = new ethers.Wallet('745ee040ef2b087f075dc7d314fa06797ed2ffd4ab59a4cc35c0a33e8d2b7791', ganacheProvider3); From 8eb553a0f9e1a96bf003913afc6f0e8848d2f1ac Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 26 Jan 2022 18:01:56 -0500 Subject: [PATCH 07/15] Updates all classes and tests with modified chain ID --- contracts/SignatureBridge.sol | 37 +-- contracts/anchors/FixedDepositAnchor.sol | 2 +- contracts/anchors/LinkableTree.sol | 23 +- contracts/handlers/AnchorHandler.sol | 12 +- contracts/libs/VAnchorEncodeInputs.sol | 19 +- contracts/utils/ChainIdWithType.sol | 24 ++ docs/VAnchorEncodeInputs.md | 34 +++ packages/anchors/src/Anchor.ts | 19 +- packages/anchors/src/VAnchor.ts | 56 +++-- packages/bridges/src/SignatureBridge.ts | 10 +- packages/bridges/src/SignatureBridgeSide.ts | 3 - packages/contracts/src/SignatureBridge.d.ts | 80 +++--- .../contracts/src/VAnchorEncodeInputs.d.ts | 38 +++ .../src/factories/AnchorHandler__factory.ts | 2 +- .../factories/FixedDepositAnchor__factory.ts | 2 +- .../src/factories/SignatureBridge__factory.ts | 51 ++-- .../factories/VAnchorEncodeInputs__factory.ts | 28 ++- .../src/factories/VAnchor__factory.ts | 2 +- packages/utils/src/Utxo.ts | 3 +- packages/vbridge/src/VBridge.ts | 40 ++- test/anchor/anchor.test.ts | 8 +- test/anchor/anchorProxy.test.ts | 8 +- test/bridge/signatureBridge.test.ts | 64 ++--- test/bridge/signatureBridgeSide.test.ts | 30 +-- test/governance/governable.test.ts | 2 +- test/helpers/startGanacheServer.ts | 1 - test/merkleTree/MerkleTreePoseidon.test.ts | 4 +- test/token/GovernedTokenWrapper.test.ts | 2 +- test/vanchor/vanchor.test.ts | 68 +++-- test/vbridge/signatureVBridge.test.ts | 234 +++++++++--------- 30 files changed, 487 insertions(+), 419 deletions(-) create mode 100644 contracts/utils/ChainIdWithType.sol diff --git a/contracts/SignatureBridge.sol b/contracts/SignatureBridge.sol index 1804ec2a8..c4744fd82 100644 --- a/contracts/SignatureBridge.sol +++ b/contracts/SignatureBridge.sol @@ -11,6 +11,7 @@ import "./utils/Pausable.sol"; import "./utils/SafeMath.sol"; import "./utils/SafeCast.sol"; import "./utils/Governable.sol"; +import "./utils/ChainIdWithType.sol"; import "./interfaces/IExecutor.sol"; import "hardhat/console.sol"; @@ -18,7 +19,7 @@ import "hardhat/console.sol"; @title Facilitates deposits, creation and voting of deposit proposals, and deposit executions. @author ChainSafe Systems & Webb Technologies. */ -contract SignatureBridge is Pausable, SafeMath, Governable { +contract SignatureBridge is Pausable, SafeMath, Governable, ChainIdWithType { // destinationChainID => number of deposits mapping(uint256 => uint64) public _counts; // resourceID => handler address @@ -37,15 +38,14 @@ contract SignatureBridge is Pausable, SafeMath, Governable { @notice Initializes SignatureBridge with a governor @param initialGovernor Addresses that should be initially granted the relayer role. */ - constructor (address initialGovernor) Governable(initialGovernor) { - } + constructor (address initialGovernor) Governable(initialGovernor) {} /** @notice Sets a new resource for handler contracts that use the IExecutor interface, and maps the {handlerAddress} to {resourceID} in {_resourceIDToHandlerAddress}. @notice Only callable by an address that currently has the admin role. @param handlerAddress Address of handler resource will be set for. - @param resourceID ResourceID to be used when making deposits. + @param resourceID Secondary resourceID begin mapped to a handler address. @param executionContextAddress Address of contract to be called when a proposal is ready to execute on it */ function adminSetResourceWithSignature( @@ -59,23 +59,6 @@ contract SignatureBridge is Pausable, SafeMath, Governable { handler.setResource(resourceID, executionContextAddress); } - /** - @notice Migrates the handlers to a new bridge. - @notice Expects the new bridge to have the same resourceID to handler mapping as the old bridge. - @param resourceIDs ResourceID array to migrate all active handlers to the new bridge - @param newBridge New bridge address to migrate handlers to. - */ - function adminMigrateBridgeWithSignature( - bytes32[] calldata resourceIDs, - address newBridge, - bytes memory sig - ) external signedByGovernor(keccak256(abi.encodePacked(resourceIDs, newBridge)), sig) { - for (uint i = 0; i < resourceIDs.length; i++) { - IExecutor handler = IExecutor(_resourceIDToHandlerAddress[resourceIDs[i]]); - handler.migrateBridge(newBridge); - } - } - /** @notice Executes a proposal signed by the governor. @param data Data meant for execution by execution handlers. @@ -87,18 +70,12 @@ contract SignatureBridge is Pausable, SafeMath, Governable { //Parse resourceID from the data bytes calldata resourceIDBytes = data[0:32]; bytes32 resourceID = bytes32(resourceIDBytes); - // Parse chain ID from the resource ID - bytes4 executionChainID = bytes4(resourceIDBytes[28:32]); + // Parse chain ID + chain type from the resource ID + uint48 executionChainIdType = uint48(bytes6(resourceIDBytes[26:32])); // Verify current chain matches chain ID from resource ID - require(uint32(getChainId()) == uint32(executionChainID), "executing on wrong chain"); + require(uint256(getChainIdType()) == uint256(executionChainIdType), "executing on wrong chain"); address handler = _resourceIDToHandlerAddress[resourceID]; IExecutor executionHandler = IExecutor(handler); executionHandler.executeProposal(resourceID, data); } - - function getChainId() public view returns (uint) { - uint chainId; - assembly { chainId := chainid() } - return chainId; - } } diff --git a/contracts/anchors/FixedDepositAnchor.sol b/contracts/anchors/FixedDepositAnchor.sol index 54589ed08..5d18e81ea 100644 --- a/contracts/anchors/FixedDepositAnchor.sol +++ b/contracts/anchors/FixedDepositAnchor.sol @@ -250,7 +250,7 @@ contract FixedDepositAnchor is AnchorBase, IFixedDepositAnchor { uint256(encodeInputsData._fee), uint256(encodeInputsData._refund), uint256(encodeInputsData._refreshCommitment), - uint256(getChainId()), + uint256(getChainIdType()), _roots ); diff --git a/contracts/anchors/LinkableTree.sol b/contracts/anchors/LinkableTree.sol index fb553cda8..18f3ab658 100644 --- a/contracts/anchors/LinkableTree.sol +++ b/contracts/anchors/LinkableTree.sol @@ -7,11 +7,11 @@ pragma solidity ^0.8.0; import "../trees/MerkleTreePoseidon.sol"; import "../interfaces/IVerifier.sol"; +import "../utils/ChainIdWithType.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "hardhat/console.sol"; -abstract contract LinkableTree is MerkleTreePoseidon, ReentrancyGuard { - bytes2 public constant EVM_CHAIN_ID_TYPE = 0x0100; +abstract contract LinkableTree is MerkleTreePoseidon, ReentrancyGuard, ChainIdWithType { address public handler; uint8 public immutable maxEdges; @@ -155,25 +155,6 @@ abstract contract LinkableTree is MerkleTreePoseidon, ReentrancyGuard { _; } - function getChainId() public view returns (uint) { - uint chainId; - assembly { chainId := chainid() } - return chainId; - } - - function getChainIdType() public view returns (uint48) { - // The chain ID and type pair is 6 bytes in length - // The first 2 bytes are reserved for the chain type. - // The last 4 bytes are reserved for a u32 (uint32) chain ID. - bytes4 chainID = bytes4(uint32(getChainId())); - bytes2 chainType = EVM_CHAIN_ID_TYPE; - // We encode the chain ID and type pair into packed bytes which - // should be 6 bytes using the encode packed method. We will - // cast this as a bytes32 in order to encode as a uint256 for zkp verification. - bytes memory chainIdWithType = abi.encodePacked(chainType, chainID); - return uint48(bytes6(chainIdWithType)); - } - function hasEdge(uint256 _chainID) external view returns (bool) { return edgeExistsForChain[_chainID]; } diff --git a/contracts/handlers/AnchorHandler.sol b/contracts/handlers/AnchorHandler.sol index 68063cf56..60ba7c268 100644 --- a/contracts/handlers/AnchorHandler.sol +++ b/contracts/handlers/AnchorHandler.sol @@ -102,14 +102,14 @@ contract AnchorHandler is IExecutor, HandlerHelpers { address newVerifier = address(bytes20(arguments[4:24])); anchor.setVerifier(newVerifier, nonce); } else if (functionSig == bytes4(keccak256("updateEdge(uint256,bytes32,uint256)"))) { - uint32 sourceChainId = uint32(bytes4(arguments[4:8])); - uint32 leafIndex = uint32(bytes4(arguments[8:12])); - bytes32 merkleRoot = bytes32(arguments[12:44]); + uint256 sourceChainId = uint48(bytes6(arguments[4:10])); + uint32 leafIndex = uint32(bytes4(arguments[10:14])); + bytes32 merkleRoot = bytes32(arguments[14:46]); anchor.updateEdge(sourceChainId, merkleRoot, leafIndex); } else if (functionSig == bytes4(keccak256("configureLimits(uint256,uint256)"))) { - uint256 _minimalWithdrawalAmount = uint256(bytes32(arguments[4:36])); - uint256 _maximumDepositAmount = uint256(bytes32(arguments[36:68])); - anchor.configureLimits(_minimalWithdrawalAmount, _maximumDepositAmount); + uint256 minimalWithdrawalAmount = uint256(bytes32(arguments[4:36])); + uint256 maximumDepositAmount = uint256(bytes32(arguments[36:68])); + anchor.configureLimits(minimalWithdrawalAmount, maximumDepositAmount); } else { revert("Invalid function sig"); } diff --git a/contracts/libs/VAnchorEncodeInputs.sol b/contracts/libs/VAnchorEncodeInputs.sol index 05d5f1e05..d0ad3a368 100644 --- a/contracts/libs/VAnchorEncodeInputs.sol +++ b/contracts/libs/VAnchorEncodeInputs.sol @@ -4,6 +4,8 @@ pragma solidity ^0.8.0; pragma experimental ABIEncoderV2; library VAnchorEncodeInputs { + bytes2 public constant EVM_CHAIN_ID_TYPE = 0x0100; + struct Proof { bytes proof; bytes roots; @@ -19,11 +21,24 @@ library VAnchorEncodeInputs { return chainId; } + function getChainIdType() public view returns (uint48) { + // The chain ID and type pair is 6 bytes in length + // The first 2 bytes are reserved for the chain type. + // The last 4 bytes are reserved for a u32 (uint32) chain ID. + bytes4 chainID = bytes4(uint32(getChainId())); + bytes2 chainType = EVM_CHAIN_ID_TYPE; + // We encode the chain ID and type pair into packed bytes which + // should be 6 bytes using the encode packed method. We will + // cast this as a bytes32 in order to encode as a uint256 for zkp verification. + bytes memory chainIdWithType = abi.encodePacked(chainType, chainID); + return uint48(bytes6(chainIdWithType)); + } + function _encodeInputs2( Proof memory _args, uint8 maxEdges ) public view returns (bytes memory, bytes32[] memory) { - uint256 _chainId = getChainId(); + uint256 _chainId = getChainIdType(); bytes32[] memory result = new bytes32[](maxEdges + 1); bytes memory encodedInput; @@ -145,7 +160,7 @@ library VAnchorEncodeInputs { Proof memory _args, uint8 maxEdges ) public view returns (bytes memory, bytes32[] memory) { - uint256 _chainId = getChainId(); + uint256 _chainId = getChainIdType(); bytes32[] memory result = new bytes32[](maxEdges + 1); bytes memory encodedInput; diff --git a/contracts/utils/ChainIdWithType.sol b/contracts/utils/ChainIdWithType.sol new file mode 100644 index 000000000..fc99dd975 --- /dev/null +++ b/contracts/utils/ChainIdWithType.sol @@ -0,0 +1,24 @@ +pragma solidity ^0.8.5; + +abstract contract ChainIdWithType { + bytes2 public constant EVM_CHAIN_ID_TYPE = 0x0100; + + function getChainId() public view returns (uint) { + uint chainId; + assembly { chainId := chainid() } + return chainId; + } + + function getChainIdType() public view returns (uint48) { + // The chain ID and type pair is 6 bytes in length + // The first 2 bytes are reserved for the chain type. + // The last 4 bytes are reserved for a u32 (uint32) chain ID. + bytes4 chainID = bytes4(uint32(getChainId())); + bytes2 chainType = EVM_CHAIN_ID_TYPE; + // We encode the chain ID and type pair into packed bytes which + // should be 6 bytes using the encode packed method. We will + // cast this as a bytes32 in order to encode as a uint256 for zkp verification. + bytes memory chainIdWithType = abi.encodePacked(chainType, chainID); + return uint48(bytes6(chainIdWithType)); + } +} \ No newline at end of file diff --git a/docs/VAnchorEncodeInputs.md b/docs/VAnchorEncodeInputs.md index 53fb4f98c..7ecfcacfe 100644 --- a/docs/VAnchorEncodeInputs.md +++ b/docs/VAnchorEncodeInputs.md @@ -10,6 +10,23 @@ ## Methods +### EVM_CHAIN_ID_TYPE + +```solidity +function EVM_CHAIN_ID_TYPE() external view returns (bytes2) +``` + + + + + + +#### Returns + +| Name | Type | Description | +|---|---|---| +| _0 | bytes2 | undefined + ### _encodeInputs16 ```solidity @@ -75,6 +92,23 @@ function getChainId() external view returns (uint256) |---|---|---| | _0 | uint256 | undefined +### getChainIdType + +```solidity +function getChainIdType() external view returns (uint48) +``` + + + + + + +#### Returns + +| Name | Type | Description | +|---|---|---| +| _0 | uint48 | undefined + diff --git a/packages/anchors/src/Anchor.ts b/packages/anchors/src/Anchor.ts index 2ecdd76e9..e97231cc7 100644 --- a/packages/anchors/src/Anchor.ts +++ b/packages/anchors/src/Anchor.ts @@ -2,7 +2,7 @@ import { BigNumberish, ethers, BigNumber } from 'ethers'; import { FixedDepositAnchor as AnchorContract, FixedDepositAnchor__factory as Anchor__factory} from '@webb-tools/contracts' import { RefreshEvent, WithdrawalEvent } from '@webb-tools/contracts/src/FixedDepositAnchor'; import { IAnchorDeposit, IAnchorDepositInfo, IAnchor, IFixedAnchorPublicInputs, IMerkleProofData } from '@webb-tools/interfaces'; -import { toFixedHex, toHex, rbigint, p256, PoseidonHasher, ZkComponents, Utxo } from '@webb-tools/utils'; +import { toFixedHex, toHex, rbigint, p256, PoseidonHasher, ZkComponents, Utxo, getChainIdType } from '@webb-tools/utils'; import { MerkleTree } from '@webb-tools/merkle-tree'; const snarkjs = require('snarkjs'); @@ -184,8 +184,7 @@ class Anchor implements IAnchor { public async createResourceId(): Promise { return toHex( this.contract.address - + toHex(1, 2).substr(2) - + toHex((await this.signer.getChainId()), 4).substr(2), + + toHex(getChainIdType(await this.signer.getChainId()), 6).substr(2), 32 ); } @@ -218,14 +217,14 @@ class Anchor implements IAnchor { const functionSig = ethers.utils.keccak256(ethers.utils.toUtf8Bytes("updateEdge(uint256,bytes32,uint256)")).slice(0, 10).padEnd(10, '0'); const dummyNonce = 1; - const chainID = await this.signer.getChainId(); + const chainID = getChainIdType(await this.signer.getChainId()); const merkleRoot = this.depositHistory[leafIndex]; return '0x' + toHex(resourceID, 32).substr(2)+ functionSig.slice(2) + toHex(dummyNonce,4).substr(2) + - toHex(chainID, 4).substr(2) + + toHex(chainID, 6).substr(2) + toHex(leafIndex, 4).substr(2) + toHex(merkleRoot, 32).substr(2); } @@ -234,7 +233,6 @@ class Anchor implements IAnchor { const resourceID = await this.createResourceId(); const functionSig = ethers.utils.keccak256(ethers.utils.toUtf8Bytes("setHandler(address,uint32)")).slice(0, 10).padEnd(10, '0'); const nonce = (await this.contract.getProposalNonce()) + 1;; - const chainID = await this.signer.getChainId(); return '0x' + toHex(resourceID, 32).substr(2)+ @@ -250,7 +248,7 @@ class Anchor implements IAnchor { * @returns */ public async deposit(destinationChainId?: number): Promise { - const originChainId = await this.signer.getChainId(); + const originChainId = getChainIdType(await this.signer.getChainId()); const destChainId = (destinationChainId) ? destinationChainId : originChainId; const deposit = Anchor.generateDeposit(destChainId); @@ -267,7 +265,7 @@ class Anchor implements IAnchor { } public async wrapAndDeposit(tokenAddress: string, destinationChainId?: number): Promise { - const originChainId = await this.signer.getChainId(); + const originChainId = getChainIdType(await this.signer.getChainId()); const chainId = (destinationChainId) ? destinationChainId : originChainId; const deposit = Anchor.generateDeposit(chainId); let tx; @@ -369,6 +367,9 @@ class Anchor implements IAnchor { const vKey = await snarkjs.zKey.exportVerificationKey(this.zkComponents.zkey); res = await snarkjs.groth16.verify(vKey, publicSignals, proof); + if (!res) { + throw new Error('Verification failed'); + } let proofEncoded = await Anchor.generateWithdrawProofCallData(proof, publicSignals); return proofEncoded; @@ -386,7 +387,7 @@ class Anchor implements IAnchor { await this.checkKnownRoot(); const { merkleRoot, pathElements, pathIndices } = await this.tree.path(index); - const chainId = await this.signer.getChainId(); + const chainId = getChainIdType(await this.signer.getChainId()); const roots = await this.populateRootsForProof(); diff --git a/packages/anchors/src/VAnchor.ts b/packages/anchors/src/VAnchor.ts index 67c8ad31a..1e9bbed21 100644 --- a/packages/anchors/src/VAnchor.ts +++ b/packages/anchors/src/VAnchor.ts @@ -1,6 +1,6 @@ import { BigNumber, BigNumberish, ethers } from 'ethers'; import { VAnchor as VAnchorContract, VAnchor__factory, VAnchorEncodeInputs__factory } from '@webb-tools/contracts'; -import { p256, toHex, RootInfo, Keypair, FIELD_SIZE, getExtDataHash, toFixedHex, Utxo } from '@webb-tools/utils'; +import { p256, toHex, RootInfo, Keypair, FIELD_SIZE, getExtDataHash, toFixedHex, Utxo, getChainIdType } from '@webb-tools/utils'; import { IAnchorDeposit, IAnchor, IExtData, IMerkleProofData, IUTXOInput, IVariableAnchorPublicInputs, IWitnessInput } from '@webb-tools/interfaces'; import { MerkleTree } from '@webb-tools/merkle-tree'; @@ -240,8 +240,7 @@ export class VAnchor implements IAnchor { public async createResourceId(): Promise { return toHex( this.contract.address - + toHex(1, 2).substr(2) - + toHex((await this.signer.getChainId()), 4).substr(2), + + toHex(getChainIdType(await this.signer.getChainId()), 6).substr(2), 32); } @@ -277,17 +276,17 @@ export class VAnchor implements IAnchor { leafIndex = this.tree.number_of_elements() - 1; } - const chainID = await this.signer.getChainId(); + const chainID = getChainIdType(await this.signer.getChainId()); const merkleRoot = this.depositHistory[leafIndex]; //bridgedTransact should update deposithistory const functionSig = ethers.utils.keccak256(ethers.utils.toUtf8Bytes("updateEdge(uint256,bytes32,uint256)")).slice(0, 10).padEnd(10, '0'); const dummyNonce = 1; return '0x' + - toHex(resourceID, 32).substr(2)+ - functionSig.slice(2) + + toHex(resourceID, 32).substr(2) + + functionSig.slice(2) + toHex(dummyNonce,4).substr(2) + - toHex(chainID, 4).substr(2) + - toHex(leafIndex, 4).substr(2) + + toHex(chainID, 6).substr(2) + + toHex(leafIndex, 4).substr(2) + toHex(merkleRoot, 32).substr(2); } @@ -324,7 +323,7 @@ export class VAnchor implements IAnchor { } }); let thisRoot = await this.contract.getLastRoot(); - const thisChainId = await this.signer.getChainId(); + const thisChainId = getChainIdType(await this.signer.getChainId()); return [{ merkleRoot: thisRoot, chainId: thisChainId, @@ -492,7 +491,6 @@ export class VAnchor implements IAnchor { : this.largeCircuitZkeyPath ); res = await snarkjs.groth16.verify(vKey, publicSignals, proof); - let proofEncoded = await VAnchor.generateWithdrawProofCallData(proof, publicSignals); return proofEncoded; } @@ -508,7 +506,7 @@ export class VAnchor implements IAnchor { ) { // first, check if the merkle root is known on chain - if not, then update await this.checkKnownRoot(); - const chainId = await this.signer.getChainId(); + const chainId = getChainIdType(await this.signer.getChainId()); const roots = await this.populateRootInfosForProof(); const { input, extData } = await this.generateWitnessInput( roots, @@ -561,14 +559,18 @@ export class VAnchor implements IAnchor { //console.log(`current root (transact, contract) is ${toFixedHex(await this.contract.getLastRoot())}`); while (inputs.length !== 2 && inputs.length < 16) { - inputs.push(new Utxo({chainId: BigNumber.from(31337)})); + inputs.push(new Utxo({ + chainId: BigNumber.from(getChainIdType(31337)) + })); } const merkleProofsForInputs = inputs.map((x) => this.getMerkleProof(x)); if (outputs.length < 2) { while (outputs.length < 2) { - outputs.push(new Utxo({chainId: BigNumber.from(31337)})); + outputs.push(new Utxo({ + chainId: BigNumber.from(getChainIdType(31337)) + })); } } @@ -614,14 +616,18 @@ export class VAnchor implements IAnchor { //console.log(`current root (transact, contract) is ${toFixedHex(await this.contract.getLastRoot())}`); while (inputs.length !== 2 && inputs.length < 16) { - inputs.push(new Utxo({chainId: BigNumber.from(31337)})); + inputs.push(new Utxo({ + chainId: BigNumber.from(getChainIdType(31337)) + })); } const merkleProofsForInputs = inputs.map((x) => this.getMerkleProof(x)); if (outputs.length < 2) { while (outputs.length < 2) { - outputs.push(new Utxo({chainId: BigNumber.from(31337)})); + outputs.push(new Utxo({ + chainId: BigNumber.from(getChainIdType(31337)) + })); } } @@ -691,7 +697,9 @@ export class VAnchor implements IAnchor { if (outputs.length < 2) { while (outputs.length < 2) { - outputs.push(new Utxo({originChainId: BigNumber.from(await this.signer.getChainId())})); + outputs.push(new Utxo({ + originChainId: BigNumber.from(getChainIdType(await this.signer.getChainId())) + })); } } @@ -742,7 +750,9 @@ export class VAnchor implements IAnchor { if (outputs.length < 2) { while (outputs.length < 2) { - outputs.push(new Utxo({originChainId: BigNumber.from(await this.signer.getChainId())})); + outputs.push(new Utxo({ + originChainId: BigNumber.from(getChainIdType(await this.signer.getChainId())) + })); } } @@ -809,7 +819,9 @@ export class VAnchor implements IAnchor { // const { pathElements, pathIndices, merkleRoot } = merkleProofsForInputs; while (inputs.length !== 2 && inputs.length < 16) { - inputs.push(new Utxo({chainId: BigNumber.from(31337)})); + inputs.push(new Utxo({ + chainId: BigNumber.from(getChainIdType(31337)) + })); } merkleProofsForInputs = inputs.map((x) => this.getMerkleProof(x)); @@ -820,16 +832,16 @@ export class VAnchor implements IAnchor { if (outputs.length < 2) { while (outputs.length < 2) { - outputs.push(new Utxo({chainId: BigNumber.from(31337)})); + outputs.push(new Utxo({ + chainId: BigNumber.from(getChainIdType(31337)) + })); } } let extAmount = BigNumber.from(fee) .add(outputs.reduce((sum, x) => sum.add(x.amount), BigNumber.from(0))) .sub(inputs.reduce((sum, x) => sum.add(x.amount), BigNumber.from(0))) - //console.log(`extAmount is ${extAmount}`); - //console.log("hi"); - //console.log(outputs); + const { extData, publicInputs } = await this.setupTransaction( inputs, outputs, diff --git a/packages/bridges/src/SignatureBridge.ts b/packages/bridges/src/SignatureBridge.ts index ca213ff80..bc1051946 100644 --- a/packages/bridges/src/SignatureBridge.ts +++ b/packages/bridges/src/SignatureBridge.ts @@ -1,5 +1,5 @@ import { ethers } from 'ethers'; -import { ZkComponents } from "@webb-tools/utils"; +import { getChainIdType, ZkComponents } from "@webb-tools/utils"; import { PoseidonT3__factory } from "@webb-tools/contracts"; import { MintableToken, GovernedTokenWrapper } from "@webb-tools/tokens"; import { BridgeInput, DeployerConfig, IAnchor, IAnchorDeposit } from "@webb-tools/interfaces"; @@ -110,8 +110,6 @@ export class SignatureBridge { // Create the bridgeSide const bridgeInstance = await SignatureBridgeSide.createBridgeSide( adminAddress, - 0, - 100, deployers[chainID], ); @@ -245,7 +243,7 @@ export class SignatureBridge { for (let anchor of anchorsToUpdate) { // get the bridge side which corresponds to this anchor const resourceID = await anchor.createResourceId(); - const chainId = await anchor.signer.getChainId(); + const chainId = getChainIdType(await anchor.signer.getChainId()); const bridgeSide = this.bridgeSides.get(chainId); await bridgeSide!.executeAnchorProposalWithSig(srcAnchor, resourceID); } @@ -287,7 +285,7 @@ export class SignatureBridge { } public async deposit(destinationChainId: number, anchorSize: ethers.BigNumberish, signer: ethers.Signer) { - const chainId = await signer.getChainId(); + const chainId = getChainIdType(await signer.getChainId()); const signerAddress = await signer.getAddress(); const anchor = this.getAnchor(chainId, anchorSize); if (!anchor) { @@ -324,7 +322,7 @@ export class SignatureBridge { } public async wrapAndDeposit(destinationChainId: number, tokenAddress: string, anchorSize: ethers.BigNumberish, signer: ethers.Signer) { - const chainId = await signer.getChainId(); + const chainId = getChainIdType(await signer.getChainId()); const signerAddress = await signer.getAddress(); const anchor = this.getAnchor(chainId, anchorSize); if (!anchor) { diff --git a/packages/bridges/src/SignatureBridgeSide.ts b/packages/bridges/src/SignatureBridgeSide.ts index b6f1a06d9..f41588799 100644 --- a/packages/bridges/src/SignatureBridgeSide.ts +++ b/packages/bridges/src/SignatureBridgeSide.ts @@ -32,12 +32,9 @@ export class SignatureBridgeSide implements IBridgeSide { public static async createBridgeSide( initialGovernor: string, - fee: ethers.BigNumberish, - expiry: ethers.BigNumberish, admin: ethers.Signer ): Promise { const bridgeFactory = new SignatureBridge__factory(admin); - const chainId = await admin.getChainId(); const deployedBridge = await bridgeFactory.deploy(initialGovernor); await deployedBridge.deployed(); const bridgeSide = new SignatureBridgeSide(deployedBridge, admin); diff --git a/packages/contracts/src/SignatureBridge.d.ts b/packages/contracts/src/SignatureBridge.d.ts index ad976980a..eb0057b4d 100644 --- a/packages/contracts/src/SignatureBridge.d.ts +++ b/packages/contracts/src/SignatureBridge.d.ts @@ -21,13 +21,14 @@ import type { TypedEventFilter, TypedEvent, TypedListener } from "./common"; interface SignatureBridgeInterface extends ethers.utils.Interface { functions: { + "EVM_CHAIN_ID_TYPE()": FunctionFragment; "_counts(uint256)": FunctionFragment; "_resourceIDToHandlerAddress(bytes32)": FunctionFragment; - "adminMigrateBridgeWithSignature(bytes32[],address,bytes)": FunctionFragment; "adminSetResourceWithSignature(address,bytes32,address,bytes)": FunctionFragment; "checkPubKey(bytes)": FunctionFragment; "executeProposalWithSignature(bytes,bytes)": FunctionFragment; "getChainId()": FunctionFragment; + "getChainIdType()": FunctionFragment; "governor()": FunctionFragment; "isGovernor()": FunctionFragment; "isSignatureFromGovernor(bytes,bytes)": FunctionFragment; @@ -41,6 +42,10 @@ interface SignatureBridgeInterface extends ethers.utils.Interface { "verify(bytes32,uint8,bytes32,bytes32)": FunctionFragment; }; + encodeFunctionData( + functionFragment: "EVM_CHAIN_ID_TYPE", + values?: undefined + ): string; encodeFunctionData( functionFragment: "_counts", values: [BigNumberish] @@ -49,10 +54,6 @@ interface SignatureBridgeInterface extends ethers.utils.Interface { functionFragment: "_resourceIDToHandlerAddress", values: [BytesLike] ): string; - encodeFunctionData( - functionFragment: "adminMigrateBridgeWithSignature", - values: [BytesLike[], string, BytesLike] - ): string; encodeFunctionData( functionFragment: "adminSetResourceWithSignature", values: [string, BytesLike, string, BytesLike] @@ -69,6 +70,10 @@ interface SignatureBridgeInterface extends ethers.utils.Interface { functionFragment: "getChainId", values?: undefined ): string; + encodeFunctionData( + functionFragment: "getChainIdType", + values?: undefined + ): string; encodeFunctionData(functionFragment: "governor", values?: undefined): string; encodeFunctionData( functionFragment: "isGovernor", @@ -108,13 +113,13 @@ interface SignatureBridgeInterface extends ethers.utils.Interface { values: [BytesLike, BigNumberish, BytesLike, BytesLike] ): string; - decodeFunctionResult(functionFragment: "_counts", data: BytesLike): Result; decodeFunctionResult( - functionFragment: "_resourceIDToHandlerAddress", + functionFragment: "EVM_CHAIN_ID_TYPE", data: BytesLike ): Result; + decodeFunctionResult(functionFragment: "_counts", data: BytesLike): Result; decodeFunctionResult( - functionFragment: "adminMigrateBridgeWithSignature", + functionFragment: "_resourceIDToHandlerAddress", data: BytesLike ): Result; decodeFunctionResult( @@ -130,6 +135,10 @@ interface SignatureBridgeInterface extends ethers.utils.Interface { data: BytesLike ): Result; decodeFunctionResult(functionFragment: "getChainId", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "getChainIdType", + data: BytesLike + ): Result; decodeFunctionResult(functionFragment: "governor", data: BytesLike): Result; decodeFunctionResult(functionFragment: "isGovernor", data: BytesLike): Result; decodeFunctionResult( @@ -231,6 +240,8 @@ export class SignatureBridge extends BaseContract { interface: SignatureBridgeInterface; functions: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise<[string]>; + _counts( arg0: BigNumberish, overrides?: CallOverrides @@ -241,13 +252,6 @@ export class SignatureBridge extends BaseContract { overrides?: CallOverrides ): Promise<[string]>; - adminMigrateBridgeWithSignature( - resourceIDs: BytesLike[], - newBridge: string, - sig: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - adminSetResourceWithSignature( handlerAddress: string, resourceID: BytesLike, @@ -269,6 +273,8 @@ export class SignatureBridge extends BaseContract { getChainId(overrides?: CallOverrides): Promise<[BigNumber]>; + getChainIdType(overrides?: CallOverrides): Promise<[number]>; + governor(overrides?: CallOverrides): Promise<[string]>; isGovernor(overrides?: CallOverrides): Promise<[boolean]>; @@ -322,6 +328,8 @@ export class SignatureBridge extends BaseContract { ): Promise<[boolean]>; }; + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + _counts(arg0: BigNumberish, overrides?: CallOverrides): Promise; _resourceIDToHandlerAddress( @@ -329,13 +337,6 @@ export class SignatureBridge extends BaseContract { overrides?: CallOverrides ): Promise; - adminMigrateBridgeWithSignature( - resourceIDs: BytesLike[], - newBridge: string, - sig: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - adminSetResourceWithSignature( handlerAddress: string, resourceID: BytesLike, @@ -354,6 +355,8 @@ export class SignatureBridge extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + governor(overrides?: CallOverrides): Promise; isGovernor(overrides?: CallOverrides): Promise; @@ -407,6 +410,8 @@ export class SignatureBridge extends BaseContract { ): Promise; callStatic: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + _counts(arg0: BigNumberish, overrides?: CallOverrides): Promise; _resourceIDToHandlerAddress( @@ -414,13 +419,6 @@ export class SignatureBridge extends BaseContract { overrides?: CallOverrides ): Promise; - adminMigrateBridgeWithSignature( - resourceIDs: BytesLike[], - newBridge: string, - sig: BytesLike, - overrides?: CallOverrides - ): Promise; - adminSetResourceWithSignature( handlerAddress: string, resourceID: BytesLike, @@ -439,6 +437,8 @@ export class SignatureBridge extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + governor(overrides?: CallOverrides): Promise; isGovernor(overrides?: CallOverrides): Promise; @@ -529,6 +529,8 @@ export class SignatureBridge extends BaseContract { }; estimateGas: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + _counts(arg0: BigNumberish, overrides?: CallOverrides): Promise; _resourceIDToHandlerAddress( @@ -536,13 +538,6 @@ export class SignatureBridge extends BaseContract { overrides?: CallOverrides ): Promise; - adminMigrateBridgeWithSignature( - resourceIDs: BytesLike[], - newBridge: string, - sig: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - adminSetResourceWithSignature( handlerAddress: string, resourceID: BytesLike, @@ -564,6 +559,8 @@ export class SignatureBridge extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + governor(overrides?: CallOverrides): Promise; isGovernor(overrides?: CallOverrides): Promise; @@ -618,6 +615,8 @@ export class SignatureBridge extends BaseContract { }; populateTransaction: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + _counts( arg0: BigNumberish, overrides?: CallOverrides @@ -628,13 +627,6 @@ export class SignatureBridge extends BaseContract { overrides?: CallOverrides ): Promise; - adminMigrateBridgeWithSignature( - resourceIDs: BytesLike[], - newBridge: string, - sig: BytesLike, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - adminSetResourceWithSignature( handlerAddress: string, resourceID: BytesLike, @@ -656,6 +648,8 @@ export class SignatureBridge extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + governor(overrides?: CallOverrides): Promise; isGovernor(overrides?: CallOverrides): Promise; diff --git a/packages/contracts/src/VAnchorEncodeInputs.d.ts b/packages/contracts/src/VAnchorEncodeInputs.d.ts index 67c6517d2..4cd83fc63 100644 --- a/packages/contracts/src/VAnchorEncodeInputs.d.ts +++ b/packages/contracts/src/VAnchorEncodeInputs.d.ts @@ -20,11 +20,17 @@ import type { TypedEventFilter, TypedEvent, TypedListener } from "./common"; interface VAnchorEncodeInputsInterface extends ethers.utils.Interface { functions: { + "EVM_CHAIN_ID_TYPE()": FunctionFragment; "_encodeInputs16((bytes,bytes,bytes32[],bytes32[2],uint256,bytes32),uint8)": FunctionFragment; "_encodeInputs2((bytes,bytes,bytes32[],bytes32[2],uint256,bytes32),uint8)": FunctionFragment; "getChainId()": FunctionFragment; + "getChainIdType()": FunctionFragment; }; + encodeFunctionData( + functionFragment: "EVM_CHAIN_ID_TYPE", + values?: undefined + ): string; encodeFunctionData( functionFragment: "_encodeInputs16", values: [ @@ -57,7 +63,15 @@ interface VAnchorEncodeInputsInterface extends ethers.utils.Interface { functionFragment: "getChainId", values?: undefined ): string; + encodeFunctionData( + functionFragment: "getChainIdType", + values?: undefined + ): string; + decodeFunctionResult( + functionFragment: "EVM_CHAIN_ID_TYPE", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "_encodeInputs16", data: BytesLike @@ -67,6 +81,10 @@ interface VAnchorEncodeInputsInterface extends ethers.utils.Interface { data: BytesLike ): Result; decodeFunctionResult(functionFragment: "getChainId", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "getChainIdType", + data: BytesLike + ): Result; events: {}; } @@ -115,6 +133,8 @@ export class VAnchorEncodeInputs extends BaseContract { interface: VAnchorEncodeInputsInterface; functions: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise<[string]>; + _encodeInputs16( _args: { proof: BytesLike; @@ -142,8 +162,12 @@ export class VAnchorEncodeInputs extends BaseContract { ): Promise<[string, string[]]>; getChainId(overrides?: CallOverrides): Promise<[BigNumber]>; + + getChainIdType(overrides?: CallOverrides): Promise<[number]>; }; + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + _encodeInputs16( _args: { proof: BytesLike; @@ -172,7 +196,11 @@ export class VAnchorEncodeInputs extends BaseContract { getChainId(overrides?: CallOverrides): Promise; + getChainIdType(overrides?: CallOverrides): Promise; + callStatic: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + _encodeInputs16( _args: { proof: BytesLike; @@ -200,11 +228,15 @@ export class VAnchorEncodeInputs extends BaseContract { ): Promise<[string, string[]]>; getChainId(overrides?: CallOverrides): Promise; + + getChainIdType(overrides?: CallOverrides): Promise; }; filters: {}; estimateGas: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + _encodeInputs16( _args: { proof: BytesLike; @@ -232,9 +264,13 @@ export class VAnchorEncodeInputs extends BaseContract { ): Promise; getChainId(overrides?: CallOverrides): Promise; + + getChainIdType(overrides?: CallOverrides): Promise; }; populateTransaction: { + EVM_CHAIN_ID_TYPE(overrides?: CallOverrides): Promise; + _encodeInputs16( _args: { proof: BytesLike; @@ -262,5 +298,7 @@ export class VAnchorEncodeInputs extends BaseContract { ): Promise; getChainId(overrides?: CallOverrides): Promise; + + getChainIdType(overrides?: CallOverrides): Promise; }; } diff --git a/packages/contracts/src/factories/AnchorHandler__factory.ts b/packages/contracts/src/factories/AnchorHandler__factory.ts index 20e47a026..efcc84b84 100644 --- a/packages/contracts/src/factories/AnchorHandler__factory.ts +++ b/packages/contracts/src/factories/AnchorHandler__factory.ts @@ -271,7 +271,7 @@ const _abi = [ ]; const _bytecode = - "0x60806040523480156200001157600080fd5b5060405162000e1d38038062000e1d83398101604081905262000034916200022e565b8051825114620000b05760405162461bcd60e51b815260206004820152603c60248201527f696e697469616c5265736f7572636549447320616e6420696e697469616c436f60448201527f6e7472616374416464726573736573206c656e206d69736d6174636800000000606482015260840160405180910390fd5b600080546001600160a01b0319166001600160a01b0385161781555b8251811015620001355762000120838281518110620000ef57620000ef62000393565b60200260200101518383815181106200010c576200010c62000393565b60200260200101516200013f60201b60201c565b806200012c8162000369565b915050620000cc565b50505050620003bf565b600082815260016020818152604080842080546001600160a01b039096166001600160a01b0319909616861790559383526002815283832094909455600390935220805460ff19169091179055565b80516001600160a01b0381168114620001a657600080fd5b919050565b600082601f830112620001bd57600080fd5b81516020620001d6620001d08362000343565b62000310565b80838252828201915082860187848660051b8901011115620001f757600080fd5b60005b8581101562000221576200020e826200018e565b84529284019290840190600101620001fa565b5090979650505050505050565b6000806000606084860312156200024457600080fd5b6200024f846200018e565b602085810151919450906001600160401b03808211156200026f57600080fd5b818701915087601f8301126200028457600080fd5b815162000295620001d08262000343565b8082825285820191508585018b878560051b8801011115620002b657600080fd5b600095505b83861015620002db578051835260019590950194918601918601620002bb565b5060408a01519097509450505080831115620002f657600080fd5b50506200030686828701620001ab565b9150509250925092565b604051601f8201601f191681016001600160401b03811182821017156200033b576200033b620003a9565b604052919050565b60006001600160401b038211156200035f576200035f620003a9565b5060051b60200190565b60006000198214156200038c57634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b610a4e80620003cf6000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c8063d75a068311610066578063d75a0683146101c6578063d7f5b35914610209578063e07384a81461021c578063e248cff214610275578063ec97d3b41461028857600080fd5b80630c9e9e14146100a3578063318c136e1461012a5780637f79bea814610155578063b8fa373614610188578063c54c2a111461019d575b600080fd5b6100f36100b1366004610912565b60046020818152600093845260408085209091529183529120805460018201546002830154600384015493909401546001600160a01b03909216939092909185565b604080516001600160a01b0390961686526020860194909452928401919091526060830152608082015260a0015b60405180910390f35b60005461013d906001600160a01b031681565b6040516001600160a01b039091168152602001610121565b61017861016336600461082f565b60036020526000908152604090205460ff1681565b6040519015158152602001610121565b61019b61019636600461086a565b6102b6565b005b61013d6101ab366004610851565b6001602052600090815260409020546001600160a01b031681565b6101f06101d4366004610851565b60056020526000908152604090205467ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610121565b61019b61021736600461082f565b61030e565b61022f61022a366004610934565b610338565b604051610121919081516001600160a01b031681526020808301519082015260408083015190820152606080830151908201526080918201519181019190915260a00190565b61019b610283366004610896565b6103ce565b6102a861029636600461082f565b60026020526000908152604090205481565b604051908152602001610121565b6102be6107b7565b600082815260016020818152604080842080546001600160a01b0319166001600160a01b0387169081179091558452600282528084208690556003909152909120805460ff191690911790555050565b6103166107b7565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915250600081815260046020818152604080842067ffffffffffffffff87168552825292839020835160a08101855281546001600160a01b031681526001820154928101929092526002810154938201939093526003830154606082015291015460808201525b92915050565b6103d66107b7565b60008036816103e8602082878961096d565b6103f1916109cc565b935061040160246020878961096d565b61040a916109ea565b9250610419856024818961096d565b6000898152600160209081526040808320546001600160a01b03168084526003909252909120549294509092509060ff166104ac5760405162461bcd60e51b815260206004820152602860248201527f70726f766964656420746f6b656e41646472657373206973206e6f74207768696044820152671d195b1a5cdd195960c21b60648201526084015b60405180910390fd5b806001600160e01b031985166372c1ad0360e01b14156105725760006104d5600482868861096d565b6104de916109ea565b60e01c905060006104f360186004878961096d565b6104fc91610997565b6040516372c1ad0360e01b815260609190911c6004820181905263ffffffff8416602483015291506001600160a01b038416906372c1ad03906044015b600060405180830381600087803b15801561055357600080fd5b505af1158015610567573d6000803e3d6000fd5b5050505050506107ac565b6001600160e01b0319851663a0d192f560e01b141561060257600061059a600482868861096d565b6105a3916109ea565b60e01c905060006105b860186004878961096d565b6105c191610997565b60405163a0d192f560e01b815260609190911c6004820181905263ffffffff8416602483015291506001600160a01b0384169063a0d192f590604401610539565b6001600160e01b031985166344347ba960e01b14156106e957600061062b60086004868861096d565b610634916109ea565b60e01c90506000610649600c6008878961096d565b610652916109ea565b60e01c90506000610667602c600c888a61096d565b610670916109cc565b6040516344347ba960e01b815263ffffffff808616600483015260248201839052841660448201529091506001600160a01b038516906344347ba990606401600060405180830381600087803b1580156106c957600080fd5b505af11580156106dd573d6000803e3d6000fd5b505050505050506107ac565b6001600160e01b031985166342d9071160e01b141561076d57600061071260246004868861096d565b61071b916109cc565b9050600061072d60446024878961096d565b610736916109cc565b6040516342d9071160e01b815260048101849052602481018290529091506001600160a01b038416906342d9071190604401610539565b60405162461bcd60e51b8152602060048201526014602482015273496e76616c69642066756e6374696f6e2073696760601b60448201526064016104a3565b505050505050505050565b6000546001600160a01b031633146108115760405162461bcd60e51b815260206004820152601e60248201527f73656e646572206d7573742062652062726964676520636f6e7472616374000060448201526064016104a3565b565b80356001600160a01b038116811461082a57600080fd5b919050565b60006020828403121561084157600080fd5b61084a82610813565b9392505050565b60006020828403121561086357600080fd5b5035919050565b6000806040838503121561087d57600080fd5b8235915061088d60208401610813565b90509250929050565b6000806000604084860312156108ab57600080fd5b83359250602084013567ffffffffffffffff808211156108ca57600080fd5b818601915086601f8301126108de57600080fd5b8135818111156108ed57600080fd5b8760208285010111156108ff57600080fd5b6020830194508093505050509250925092565b6000806040838503121561092557600080fd5b50508035926020909101359150565b6000806040838503121561094757600080fd5b823567ffffffffffffffff8116811461095f57600080fd5b946020939093013593505050565b6000808585111561097d57600080fd5b8386111561098a57600080fd5b5050820193919092039150565b6bffffffffffffffffffffffff1981358181169160148510156109c45780818660140360031b1b83161692505b505092915050565b803560208310156103c857600019602084900360031b1b1692915050565b6001600160e01b031981358181169160048510156109c45760049490940360031b84901b169092169291505056fea264697066735822122059534e2f4e336a2a9b544ca01b1cf5d8ca1a23d7eabedf10a557fd3d87acf48b64736f6c63430008050033"; + "0x60806040523480156200001157600080fd5b5060405162000e4a38038062000e4a83398101604081905262000034916200022e565b8051825114620000b05760405162461bcd60e51b815260206004820152603c60248201527f696e697469616c5265736f7572636549447320616e6420696e697469616c436f60448201527f6e7472616374416464726573736573206c656e206d69736d6174636800000000606482015260840160405180910390fd5b600080546001600160a01b0319166001600160a01b0385161781555b8251811015620001355762000120838281518110620000ef57620000ef62000393565b60200260200101518383815181106200010c576200010c62000393565b60200260200101516200013f60201b60201c565b806200012c8162000369565b915050620000cc565b50505050620003bf565b600082815260016020818152604080842080546001600160a01b039096166001600160a01b0319909616861790559383526002815283832094909455600390935220805460ff19169091179055565b80516001600160a01b0381168114620001a657600080fd5b919050565b600082601f830112620001bd57600080fd5b81516020620001d6620001d08362000343565b62000310565b80838252828201915082860187848660051b8901011115620001f757600080fd5b60005b8581101562000221576200020e826200018e565b84529284019290840190600101620001fa565b5090979650505050505050565b6000806000606084860312156200024457600080fd5b6200024f846200018e565b602085810151919450906001600160401b03808211156200026f57600080fd5b818701915087601f8301126200028457600080fd5b815162000295620001d08262000343565b8082825285820191508585018b878560051b8801011115620002b657600080fd5b600095505b83861015620002db578051835260019590950194918601918601620002bb565b5060408a01519097509450505080831115620002f657600080fd5b50506200030686828701620001ab565b9150509250925092565b604051601f8201601f191681016001600160401b03811182821017156200033b576200033b620003a9565b604052919050565b60006001600160401b038211156200035f576200035f620003a9565b5060051b60200190565b60006000198214156200038c57634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b610a7b80620003cf6000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c8063d75a068311610066578063d75a0683146101c6578063d7f5b35914610209578063e07384a81461021c578063e248cff214610275578063ec97d3b41461028857600080fd5b80630c9e9e14146100a3578063318c136e1461012a5780637f79bea814610155578063b8fa373614610188578063c54c2a111461019d575b600080fd5b6100f36100b1366004610911565b60046020818152600093845260408085209091529183529120805460018201546002830154600384015493909401546001600160a01b03909216939092909185565b604080516001600160a01b0390961686526020860194909452928401919091526060830152608082015260a0015b60405180910390f35b60005461013d906001600160a01b031681565b6040516001600160a01b039091168152602001610121565b61017861016336600461082e565b60036020526000908152604090205460ff1681565b6040519015158152602001610121565b61019b610196366004610869565b6102b6565b005b61013d6101ab366004610850565b6001602052600090815260409020546001600160a01b031681565b6101f06101d4366004610850565b60056020526000908152604090205467ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610121565b61019b61021736600461082e565b61030e565b61022f61022a366004610933565b610338565b604051610121919081516001600160a01b031681526020808301519082015260408083015190820152606080830151908201526080918201519181019190915260a00190565b61019b610283366004610895565b6103ce565b6102a861029636600461082e565b60026020526000908152604090205481565b604051908152602001610121565b6102be6107b6565b600082815260016020818152604080842080546001600160a01b0319166001600160a01b0387169081179091558452600282528084208690556003909152909120805460ff191690911790555050565b6103166107b6565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915250600081815260046020818152604080842067ffffffffffffffff87168552825292839020835160a08101855281546001600160a01b031681526001820154928101929092526002810154938201939093526003830154606082015291015460808201525b92915050565b6103d66107b6565b60008036816103e8602082878961096c565b6103f1916109cb565b935061040160246020878961096c565b61040a916109e9565b9250610419856024818961096c565b6000898152600160209081526040808320546001600160a01b03168084526003909252909120549294509092509060ff166104ac5760405162461bcd60e51b815260206004820152602860248201527f70726f766964656420746f6b656e41646472657373206973206e6f74207768696044820152671d195b1a5cdd195960c21b60648201526084015b60405180910390fd5b806001600160e01b031985166372c1ad0360e01b14156105725760006104d5600482868861096c565b6104de916109e9565b60e01c905060006104f360186004878961096c565b6104fc91610996565b6040516372c1ad0360e01b815260609190911c6004820181905263ffffffff8416602483015291506001600160a01b038416906372c1ad03906044015b600060405180830381600087803b15801561055357600080fd5b505af1158015610567573d6000803e3d6000fd5b5050505050506107ab565b6001600160e01b0319851663a0d192f560e01b141561060257600061059a600482868861096c565b6105a3916109e9565b60e01c905060006105b860186004878961096c565b6105c191610996565b60405163a0d192f560e01b815260609190911c6004820181905263ffffffff8416602483015291506001600160a01b0384169063a0d192f590604401610539565b6001600160e01b031985166344347ba960e01b14156106e857600061062b600a6004868861096c565b61063491610a17565b60d01c90506000610649600e600a878961096c565b610652916109e9565b60e01c90506000610667602e600e888a61096c565b610670916109cb565b6040516344347ba960e01b8152600481018590526024810182905263ffffffff841660448201529091506001600160a01b038516906344347ba990606401600060405180830381600087803b1580156106c857600080fd5b505af11580156106dc573d6000803e3d6000fd5b505050505050506107ab565b6001600160e01b031985166342d9071160e01b141561076c57600061071160246004868861096c565b61071a916109cb565b9050600061072c60446024878961096c565b610735916109cb565b6040516342d9071160e01b815260048101849052602481018290529091506001600160a01b038416906342d9071190604401610539565b60405162461bcd60e51b8152602060048201526014602482015273496e76616c69642066756e6374696f6e2073696760601b60448201526064016104a3565b505050505050505050565b6000546001600160a01b031633146108105760405162461bcd60e51b815260206004820152601e60248201527f73656e646572206d7573742062652062726964676520636f6e7472616374000060448201526064016104a3565b565b80356001600160a01b038116811461082957600080fd5b919050565b60006020828403121561084057600080fd5b61084982610812565b9392505050565b60006020828403121561086257600080fd5b5035919050565b6000806040838503121561087c57600080fd5b8235915061088c60208401610812565b90509250929050565b6000806000604084860312156108aa57600080fd5b83359250602084013567ffffffffffffffff808211156108c957600080fd5b818601915086601f8301126108dd57600080fd5b8135818111156108ec57600080fd5b8760208285010111156108fe57600080fd5b6020830194508093505050509250925092565b6000806040838503121561092457600080fd5b50508035926020909101359150565b6000806040838503121561094657600080fd5b823567ffffffffffffffff8116811461095e57600080fd5b946020939093013593505050565b6000808585111561097c57600080fd5b8386111561098957600080fd5b5050820193919092039150565b6bffffffffffffffffffffffff1981358181169160148510156109c35780818660140360031b1b83161692505b505092915050565b803560208310156103c857600019602084900360031b1b1692915050565b6001600160e01b031981358181169160048510156109c35760049490940360031b84901b1690921692915050565b6001600160d01b031981358181169160068510156109c35760069490940360031b84901b169092169291505056fea2646970667358221220ec11d6e79b7a5e4a9db84a1e1df88510bdb8ac602007af6b6a798b263049375164736f6c63430008050033"; export class AnchorHandler__factory extends ContractFactory { constructor( diff --git a/packages/contracts/src/factories/FixedDepositAnchor__factory.ts b/packages/contracts/src/factories/FixedDepositAnchor__factory.ts index a2659cf5b..d99e16b0e 100644 --- a/packages/contracts/src/factories/FixedDepositAnchor__factory.ts +++ b/packages/contracts/src/factories/FixedDepositAnchor__factory.ts @@ -1155,7 +1155,7 @@ const _abi = [ ]; const _bytecode = - "0x610120604052600380546001600160401b0319169055600b805463ffffffff60a01b191690553480156200003257600080fd5b50604051620052f9380380620052f9833981016040819052620000559162000931565b8685858484848383838183818160008263ffffffff1611620000ca5760405162461bcd60e51b815260206004820152602360248201527f5f6c6576656c732073686f756c642062652067726561746572207468616e207a60448201526265726f60e81b60648201526084015b60405180910390fd5b60208263ffffffff1610620001225760405162461bcd60e51b815260206004820152601e60248201527f5f6c6576656c732073686f756c64206265206c657373207468616e20333200006044820152606401620000c1565b60e09190911b6001600160e01b03191660a05260601b6001600160601b03191660805260005b8263ffffffff168163ffffffff16101562000199576200016e63ffffffff8216620002cb565b63ffffffff821660009081526001602052604090205580620001908162000a05565b91505062000148565b50620001b7620001ab600184620009dd565b63ffffffff16620002cb565b6000805260026020527fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b5550506001600455600580546001600160a01b03199081166001600160a01b039687161790915560f89190911b7fff000000000000000000000000000000000000000000000000000000000000001660c052600b805490911697909316969096179091555050508515159250620002ac9150505760405162461bcd60e51b815260206004820152602560248201527f64656e6f6d696e6174696f6e2073686f756c6420626520677265617465722074604482015264068616e20360dc1b6064820152608401620000c1565b505061010052505060601b6001600160601b03191660e0525062000a5b565b600081620002fa57507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b81600114156200032b57507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156200035c57507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b81600314156200038d57507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b8160041415620003be57507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b8160051415620003ef57507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b81600614156200042057507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b81600714156200045157507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b81600814156200048257507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b8160091415620004b357507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a1415620004e457507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b14156200051557507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c14156200054657507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156200057757507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e1415620005a857507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f1415620005d957507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b81601014156200060a57507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b81601114156200063a57507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b81601214156200066b57507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b81601314156200069c57507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b8160141415620006cd57507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b8160151415620006fe57507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b81601614156200072f57507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b81601714156200076057507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b81601814156200079157507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b8160191415620007c257507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a1415620007f357507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b14156200082457507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c14156200085557507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d14156200088657507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e1415620008b757507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f1415620008e857507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b815260206004820152601360248201527f496e646578206f7574206f6620626f756e6473000000000000000000000000006044820152606401620000c1565b600080600080600080600060e0888a0312156200094d57600080fd5b87516200095a8162000a42565b60208901519097506200096d8162000a42565b6040890151909650620009808162000a42565b6060890151909550620009938162000a42565b608089015160a08a0151919550935063ffffffff81168114620009b557600080fd5b60c089015190925060ff81168114620009cd57600080fd5b8091505092959891949750929550565b600063ffffffff83811690831681811015620009fd57620009fd62000a2c565b039392505050565b600063ffffffff8083168181141562000a225762000a2262000a2c565b6001019392505050565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811462000a5857600080fd5b50565b60805160601c60a05160e01c60c05160f81c60e05160601c6101005161474362000bb660003960008181610397015281816106b401528181611d6601528181611e7301528181611fca01528181612188015281816124870152818161268c0152818161336201528181613391015261345b0152600081816103d401528181610a48015281816111c90152818161129d015281816114d101528181611d3501528181611e9901528181611f5801528181611ff80152818161265c015281816132dc015281816133bf015281816133f90152818161342f015261350c0152600081816105ed01528181610b2801528181610b93015281816110180152818161134c01528181611741015281816117ce015281816131b80152818161373401526137a601526000818161051e01528181610c1c0152818161188d01528181612ec10152612f640152600081816109880152612ffd01526147436000f3fe6080604052600436106102c95760003560e01c80638ea3099e11610175578063d0e8d34a116100dc578063ec73295911610095578063f5ab0dd61161006f578063f5ab0dd6146109d7578063fa73168714610a06578063fc0c546a14610a36578063fc7e9c6f14610a6a57600080fd5b8063ec73295914610942578063ed33639f14610976578063f178e47c146109aa57600080fd5b8063d0e8d34a14610864578063dbc916b814610877578063df203aa7146108b2578063e5285dcc146108c5578063e70ea87c146108f5578063e82955881461092257600080fd5b8063b214faa51161012e578063b214faa5146107b2578063ba70f757146107c5578063c2b40ae4146107ef578063c80916d41461081c578063cd3a95501461083c578063cd87a3b41461084f57600080fd5b80638ea3099e146106f857806390eeb02b1461071857806392156311146107355780639fa12d0b146107655780639ff8006314610540578063a0d192f51461079257600080fd5b80634c830cbd116102345780636d9833e3116101ed578063839df945116101c7578063839df945146106415780638b7e8782146106715780638bca6d16146106a25780638c0d34d8146106d657600080fd5b80636d9833e3146105bb57806371523c32146105db57806372c1ad031461062157600080fd5b80634c830cbd146104e05780634ecf518b1461050c5780634f401241146105405780635d2d766c14610560578063616e0957146105935780636ad481f3146105b357600080fd5b80632b7ac3f3116102865780632b7ac3f31461040c5780633408e4701461042c578063414a37ba1461043f57806343e7119f1461047357806344347ba9146104ab578063460b53e3146104c057600080fd5b80630b27fb9a146102ce57806311e4dcb91461030657806317cc915c146103365780631e627617146103665780631fc601c91461038857806321df0da7146103c5575b600080fd5b3480156102da57600080fd5b50600b54600160a01b900463ffffffff165b60405163ffffffff90911681526020015b60405180910390f35b34801561031257600080fd5b50610326610321366004613f1b565b610a8f565b60405190151581526020016102fd565b34801561034257600080fd5b50610326610351366004613dcf565b600c6020526000908152604090205460ff1681565b34801561037257600080fd5b5061037b610b24565b6040516102fd91906140d9565b34801561039457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020016102fd565b3480156103d157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020016102fd565b34801561041857600080fd5b50600b546103f4906001600160a01b031681565b34801561043857600080fd5b50466103b7565b34801561044b57600080fd5b506103b77f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b34801561047f57600080fd5b506103b761048e366004613f69565b600960209081526000928352604080842090915290825290205481565b6104be6104b9366004613f3d565b610c7b565b005b3480156104cc57600080fd5b506104be6104db366004613b5e565b6111b2565b3480156104ec57600080fd5b506104f5611238565b60405165ffffffffffff90911681526020016102fd565b34801561051857600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000000081565b34801561054c57600080fd5b506104be61055b366004613b5e565b611286565b34801561056c57600080fd5b506102ec61057b366004613dcf565b600a6020526000908152604090205463ffffffff1681565b34801561059f57600080fd5b506103266105ae366004613c34565b6112d6565b6104be6114ba565b3480156105c757600080fd5b506103266105d6366004613dcf565b611541565b3480156105e757600080fd5b5061060f7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016102fd565b34801561062d57600080fd5b506104be61063c366004613b8a565b6115bc565b34801561064d57600080fd5b5061032661065c366004613dcf565b600d6020526000908152604090205460ff1681565b34801561067d57600080fd5b50610689600160f81b81565b6040516001600160f01b031990911681526020016102fd565b3480156106ae57600080fd5b506103b77f000000000000000000000000000000000000000000000000000000000000000081565b3480156106e257600080fd5b506106eb61173d565b6040516102fd9190614111565b34801561070457600080fd5b506103b7610713366004613ecd565b6118f1565b34801561072457600080fd5b506003546102ec9063ffffffff1681565b34801561074157600080fd5b50610326610750366004613dcf565b60009081526007602052604090205460ff1690565b34801561077157600080fd5b50610785610780366004613bbf565b611a78565b6040516102fd9190614093565b34801561079e57600080fd5b506104be6107ad366004613b8a565b611b3e565b6104be6107c0366004613dcf565b611ca9565b3480156107d157600080fd5b5060035463ffffffff166000908152600260205260409020546103b7565b3480156107fb57600080fd5b506103b761080a366004613dcf565b60026020526000908152604090205481565b34801561082857600080fd5b506005546103f4906001600160a01b031681565b6104be61084a366004613b5e565b611e27565b34801561085b57600080fd5b506102ec601e81565b6104be610872366004613de8565b61215e565b34801561088357600080fd5b50610897610892366004613dcf565b61242a565b604080519384526020840192909252908201526060016102fd565b6104be6108c0366004613e51565b61245d565b3480156108d157600080fd5b506103266108e0366004613dcf565b6000908152600c602052604090205460ff1690565b34801561090157600080fd5b506103b7610910366004613dcf565b60066020526000908152604090205481565b34801561092e57600080fd5b506103b761093d366004613dcf565b612736565b34801561094e57600080fd5b506103b77f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c81565b34801561098257600080fd5b506103f47f000000000000000000000000000000000000000000000000000000000000000081565b3480156109b657600080fd5b506103b76109c5366004613dcf565b60016020526000908152604090205481565b3480156109e357600080fd5b506109f76109f2366004613ce1565b612d76565b6040516102fd93929190614178565b348015610a1257600080fd5b50610326610a21366004613dcf565b60076020526000908152604090205460ff1681565b348015610a4257600080fd5b506103f47f000000000000000000000000000000000000000000000000000000000000000081565b348015610a7657600080fd5b506003546102ec90640100000000900463ffffffff1681565b600081610a9e57506000610b1e565b6000838152600a602052604090205463ffffffff16805b600085815260096020908152604080832063ffffffff85168452909152902054841415610ae757600192505050610b1e565b63ffffffff8116610af65750601e5b80610b008161461b565b9150508163ffffffff168163ffffffff161415610ab5576000925050505b92915050565b60607f000000000000000000000000000000000000000000000000000000000000000060ff1667ffffffffffffffff811115610b6257610b626146df565b604051908082528060200260200182016040528015610b8b578160200160208202803683370190505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610c7757610bc78160016143bb565b60085410610c175760088181548110610be257610be26146c9565b906000526020600020906003020160010154828281518110610c0657610c066146c9565b602002602001018181525050610c65565b610c467f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612736565b828281518110610c5857610c586146c9565b6020026020010181815250505b80610c6f8161463b565b915050610b91565b5090565b6005546001600160a01b03163314610cae5760405162461bcd60e51b8152600401610ca5906142b8565b60405180910390fd5b60026004541415610cd15760405162461bcd60e51b8152600401610ca590614281565b60026004908155604051639215631160e01b8152908101849052309063921563119060240160206040518083038186803b158015610d0e57600080fd5b505afa158015610d22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d469190613dad565b156110115760008381526007602052604090205460ff16610dcf5760405162461bcd60e51b815260206004820152603760248201527f436861696e206d75737420626520696e74656772617465642066726f6d20746860448201527f6520627269646765206265666f726520757064617465730000000000000000006064820152608401610ca5565b600083815260066020526040902054600880548392908110610df357610df36146c9565b90600052602060002090600302016002015410610e525760405162461bcd60e51b815260206004820152601e60248201527f4e6577206c65616620696e646578206d757374206265206772656174657200006044820152606401610ca5565b600083815260066020526040902054600880549091908110610e7657610e766146c9565b90600052602060002090600302016002015462010000610e9691906143bb565b8110610ef45760405162461bcd60e51b815260206004820152602760248201527f4e6577206c65616620696e646578206d7573742077697468696e20325e3136206044820152667570646174657360c81b6064820152608401610ca5565b6000838152600660209081526040918290205482516060810184528681529182018590529181018390526008805483908110610f3257610f326146c9565b60009182526020808320845160039093020191825583810151600180840191909155604094850151600290930192909255878352600a9052918120549091601e91610f859163ffffffff909116906143d3565b610f8f919061467a565b6000868152600a60209081526040808320805463ffffffff191663ffffffff86169081179091556009835281842090845282529182902087905581518881529081018690529081018690529091507f675e61f04bcf314a9c310a93f2346f417a03d704c1caf9c6af8a65ad8addfa3f9060600160405180910390a150506111a8565b60085460ff7f000000000000000000000000000000000000000000000000000000000000000016116110855760405162461bcd60e51b815260206004820152601a60248201527f5468697320416e63686f722069732061742063617061636974790000000000006044820152606401610ca5565b6000838152600760209081526040808320805460ff19166001908117909155600880548351606080820186528a82528187018a81528287018a815295840185559388528151600384027ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee381019190915593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee485015593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee590930192909255888652600685528386208190556009855283862086805285528386208890558351898152948501879052928401879052919391927fcf4749969bace1552af6a97fe7e4affedf68875511f9746c6332eb40647b3054910160405180910390a15050505b5050600160045550565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca69388906112029033908690869060040161406f565b600060405180830381600087803b15801561121c57600080fd5b505af1158015611230573d6000803e3d6000fd5b505050505050565b60408051600160f81b602082018190524660e01b6001600160e01b0319811660228401528351808403600601815260269093019093526000929161127b816145b8565b60d01c935050505090565b60405163130e405b60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063261c80b6906112029033908690869060040161406f565b60006112fb826000815181106112ee576112ee6146c9565b6020026020010151611541565b6113475760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f742066696e6420796f7572206d65726b6c6520726f6f74000000006044820152606401610ca5565b6113727f000000000000000000000000000000000000000000000000000000000000000060016143fb565b60ff168251146113c45760405162461bcd60e51b815260206004820152601b60248201527f496e636f727265637420726f6f74206172726179206c656e67746800000000006044820152606401610ca5565b60005b6008548110156114b1576000600882815481106113e6576113e66146c9565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905061145281600001518584600161143591906143bb565b81518110611445576114456146c9565b6020026020010151610a8f565b61149e5760405162461bcd60e51b815260206004820152601760248201527f4e65696768626f7220726f6f74206e6f7420666f756e640000000000000000006044820152606401610ca5565b50806114a98161463b565b9150506113c7565b50600192915050565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca6938890349061150d903390600090819060040161406f565b6000604051808303818588803b15801561152657600080fd5b505af115801561153a573d6000803e3d6000fd5b5050505050565b60008161155057506000919050565b60035463ffffffff16805b63ffffffff8116600090815260026020526040902054841415611582575060019392505050565b63ffffffff81166115915750601e5b8061159b8161461b565b9150508163ffffffff168163ffffffff16141561155b575060009392505050565b6005546001600160a01b031633146115e65760405162461bcd60e51b8152600401610ca5906142b8565b6001600160a01b0382166116325760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610ca5565b600b5463ffffffff808316600160a01b90920416106116835760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610ca5565b600b5461169e90600160a01b900463ffffffff1660016143d3565b63ffffffff168163ffffffff1611156116f55760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610ca5565b600580546001600160a01b039093166001600160a01b031990931692909217909155600b805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b60607f000000000000000000000000000000000000000000000000000000000000000060ff1667ffffffffffffffff81111561177b5761177b6146df565b6040519080825280602002602001820160405280156117c657816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816117995790505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610c77576118028160016143bb565b60085410611876576008818154811061181d5761181d6146c9565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050828281518110611866576118666146c9565b60200260200101819052506118df565b6040518060600160405280600081526020016118b77f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612736565b815260200160008152508282815181106118d3576118d36146c9565b60200260200101819052505b806118e98161463b565b9150506117cc565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000183106119625760405162461bcd60e51b815260206004820181905260248201527f5f6c6566742073686f756c6420626520696e7369646520746865206669656c646044820152606401610ca5565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182106119db5760405162461bcd60e51b815260206004820152602160248201527f5f72696768742073686f756c6420626520696e7369646520746865206669656c6044820152601960fa1b6064820152608401610ca5565b6040805180820182528481526020810184905290516314d2f97b60e11b8152849184916001600160a01b038816916329a5f2f691611a1c919060040161416a565b60206040518083038186803b158015611a3457600080fd5b505afa158015611a48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6c9190613f02565b925050505b9392505050565b60608167ffffffffffffffff811115611a9357611a936146df565b604051908082528060200260200182016040528015611abc578160200160208202803683370190505b50905060005b82811015611b3757611afb848483818110611adf57611adf6146c9565b905060200201356000908152600c602052604090205460ff1690565b15611b25576001828281518110611b1457611b146146c9565b911515602092830291909101909101525b80611b2f8161463b565b915050611ac2565b5092915050565b6005546001600160a01b03163314611b685760405162461bcd60e51b8152600401610ca5906142b8565b6001600160a01b038216611bb45760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610ca5565b600b5463ffffffff808316600160a01b9092041610611c055760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610ca5565b600b54611c2090600160a01b900463ffffffff1660016143d3565b63ffffffff168163ffffffff161115611c775760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610ca5565b600b805463ffffffff909216600160a01b026001600160c01b03199092166001600160a01b0390931692909217179055565b3415611d105760405162461bcd60e51b815260206004820152603060248201527f4554482076616c756520697320737570706f73656420746f206265203020666f60448201526f7220455243323020696e7374616e636560801b6064820152608401610ca5565b6000611d1b82612dff565b6040516323b872dd60e01b81529091506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906323b872dd90611d8e90339030907f00000000000000000000000000000000000000000000000000000000000000009060040161406f565b602060405180830381600087803b158015611da857600080fd5b505af1158015611dbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de09190613dad565b5060408051338152426020820152839163ffffffff8416917fb50b68adb3452534cd51b362b06e4194335b46951229ec1945a94a158c2b48b2910160405180910390a35050565b6000818152600d602052604090205460ff1615611e565760405162461bcd60e51b8152600401610ca590614240565b6001600160a01b038216611fbb57604051634b66a6ff60e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906396cd4dfe9060240160206040518083038186803b158015611ee357600080fd5b505afa158015611ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f1b9190613f02565b3414611f2657600080fd5b604051633d97186b60e11b81523360048201526001600160a01b038381166024830152600060448301523060648301527f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d69034906084016000604051808303818588803b158015611f9d57600080fd5b505af1158015611fb1573d6000803e3d6000fd5b50505050506120ec565b604051634b66a6ff60e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d6903390859084906396cd4dfe9060240160206040518083038186803b15801561204657600080fd5b505afa15801561205a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207e9190613f02565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152306064820152608401600060405180830381600087803b1580156120d357600080fd5b505af11580156120e7573d6000803e3d6000fd5b505050505b60006120f782612ea8565b6000838152600d6020908152604091829020805460ff1916600117905581513381524291810191909152919250839163ffffffff8416917fb50b68adb3452534cd51b362b06e4194335b46951229ec1945a94a158c2b48b2910160405180910390a3505050565b600260045414156121815760405162461bcd60e51b8152600401610ca590614281565b60026004557f000000000000000000000000000000000000000000000000000000000000000060a082013511156121fa5760405162461bcd60e51b815260206004820152601a60248201527f4665652065786365656473207472616e736665722076616c75650000000000006044820152606401610ca5565b61221781602001356000908152600c602052604090205460ff1690565b156122645760405162461bcd60e51b815260206004820152601f60248201527f546865206e6f746520686173206265656e20616c7265616479207370656e74006044820152606401610ca5565b600080612270836130d2565b9150915061227d816112d6565b6122b95760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610ca5565b6122fa85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525086925061315b915050565b6123165760405162461bcd60e51b8152600401610ca590614210565b6020808401356000908152600c909152604090819020805460ff19166001179055830135612375576123706123516080850160608601613b41565b61236160a0860160808701613b41565b8560a001358660c0013561325c565b61241e565b6040808401356000908152600d602052205460ff16156123a75760405162461bcd60e51b8152600401610ca590614240565b60006123b68460400135612ea8565b6040858101356000818152600d602090815290839020805460ff19166001179055825181890135815263ffffffff851691810191909152929350917f138604f043594af1377bf30140984eef19cad0fb0c801cbb9b879005eddc06f0910160405180910390a2505b50506001600455505050565b6008818154811061243a57600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b600260045414156124805760405162461bcd60e51b8152600401610ca590614281565b60026004557f000000000000000000000000000000000000000000000000000000000000000060a083013511156124f95760405162461bcd60e51b815260206004820152601a60248201527f4665652065786365656473207472616e736665722076616c75650000000000006044820152606401610ca5565b6020808301356000908152600c909152604090205460ff161561255e5760405162461bcd60e51b815260206004820152601f60248201527f546865206e6f746520686173206265656e20616c7265616479207370656e74006044820152606401610ca5565b60008061256a846130d2565b91509150612577816112d6565b6125b35760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610ca5565b6125f486868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525086925061315b915050565b6126105760405162461bcd60e51b8152600401610ca590614210565b6020808501356000908152600c90915260409020805460ff191660011790556126523061264360a0870160808801613b41565b8660a001358760c0013561325c565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016634808285e846126b060a08801357f0000000000000000000000000000000000000000000000000000000000000000614583565b6126c06080890160608a01613b41565b60405160e085901b6001600160e01b03191681526001600160a01b03938416600482015260248101929092529091166044820152606401600060405180830381600087803b15801561271157600080fd5b505af1158015612725573d6000803e3d6000fd5b505060016004555050505050505050565b60008161276457507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b816001141561279457507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156127c457507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b81600314156127f457507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b816004141561282457507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b816005141561285457507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b816006141561288457507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b81600714156128b457507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b81600814156128e457507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b816009141561291457507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a141561294457507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b141561297457507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c14156129a457507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156129d457507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e1415612a0457507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f1415612a3457507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b8160101415612a6457507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b8160111415612a9357507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b8160121415612ac357507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b8160131415612af357507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b8160141415612b2357507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b8160151415612b5357507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b8160161415612b8357507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b8160171415612bb357507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b8160181415612be357507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b8160191415612c1357507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a1415612c4357507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b1415612c7357507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c1415612ca357507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d1415612cd357507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e1415612d0357507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f1415612d3357507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b6044820152606401610ca5565b919050565b612d7e613a81565b612d86613a9f565b612d8e613a81565b50506040805180820182528351815260208085015181830152825160808082018552868501518286019081526060808901519084015282528451808601865290870151815260a08701518184015281830152835180850190945260c0860151845260e0909501519083015293909150565b6000818152600d602052604081205460ff1615612e2e5760405162461bcd60e51b8152600401610ca590614240565b6000612e3983612ea8565b6000848152600d602052604090819020805460ff191660011790555190915083907fe77f587aa74084fff834b53ccbab07695ee4594b9c9d5bfd8a7dd80c556124b590612e9a908490429063ffffffff929092168252602082015260400190565b60405180910390a292915050565b600354600090640100000000900463ffffffff16612ee77f00000000000000000000000000000000000000000000000000000000000000006002614488565b63ffffffff168163ffffffff161415612f5b5760405162461bcd60e51b815260206004820152603060248201527f4d65726b6c6520747265652069732066756c6c2e204e6f206d6f7265206c656160448201526f1d995cc818d85b88189948185919195960821b6064820152608401610ca5565b8083600080805b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff16101561304457612fa160028661467a565b63ffffffff16612fdc57839250612fbd8163ffffffff16612736565b63ffffffff821660009081526001602052604090208590559150612ff8565b63ffffffff811660009081526001602052604090205492508391505b6130237f000000000000000000000000000000000000000000000000000000000000000084846118f1565b9350613030600286614420565b94508061303c81614656565b915050612f62565b50600354600090601e9061305f9063ffffffff1660016143d3565b613069919061467a565b6003805463ffffffff191663ffffffff83169081179091556000908152600260205260409020859055905061309f8660016143d3565b6003805463ffffffff929092166401000000000267ffffffff000000001990921691909117905550939695505050505050565b6060806131526130e284806142ef565b6040805160c0810182526020808901358252888301359082015290810161310f6080890160608a01613b41565b6001600160a01b0316815260200161312d60a0890160808a01613b41565b6001600160a01b031681526020018760a0013581526020018760c0013581525061364f565b91509150915091565b600080838060200190518101906131729190613d4c565b9050600080600061318284612d76565b600b54604051638041ca5360e01b815293965091945092506001600160a01b031690638041ca53906131e3908690869086908c907f0000000000000000000000000000000000000000000000000000000000000000906001906004016141a1565b60206040518083038186803b1580156131fb57600080fd5b505afa15801561320f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132339190613dad565b9450846132525760405162461bcd60e51b8152600401610ca590614210565b5050505092915050565b8034146132c45760405162461bcd60e51b815260206004820152603060248201527f496e636f727265637420726566756e6420616d6f756e7420726563656976656460448201526f08189e481d1a194818dbdb9d1c9858dd60821b6064820152608401610ca5565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561332657600080fd5b505afa15801561333a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061335e9190613f02565b90507f00000000000000000000000000000000000000000000000000000000000000008110613425576133e6856133b5857f0000000000000000000000000000000000000000000000000000000000000000614583565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691906136d6565b8215613420576134206001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001685856136d6565b613569565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166340c10f198661347f867f0000000000000000000000000000000000000000000000000000000000000000614583565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156134c557600080fd5b505af11580156134d9573d6000803e3d6000fd5b505050506000831115613569576040516340c10f1960e01b81526001600160a01b038581166004830152602482018590527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b15801561355057600080fd5b505af1158015613564573d6000803e3d6000fd5b505050505b604080516001600160a01b038781168252602082018690528616917f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b6398910160405180910390a2811561153a576000856001600160a01b03168360405160006040518083038185875af1925050503d8060008114613602576040519150601f19603f3d011682016040523d82523d6000602084013e613607565b606091505b5050905080611230576040516001600160a01b0386169084156108fc029085906000818181858888f19350505050158015613646573d6000803e3d6000fd5b50505050505050565b6060806000836000015160001c84604001516001600160a01b031685606001516001600160a01b031686608001518760a00151886020015160001c6136914690565b8c8c6040516020016136ab9998979695949392919061402b565b604051602081830303815290604052905060006136c8878761372d565b919791965090945050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052613728908490613837565b505050565b606061375a7f000000000000000000000000000000000000000000000000000000000000000060016143fb565b60ff1667ffffffffffffffff811115613775576137756146df565b60405190808252806020026020018201604052801561379e578160200160208202803683370190505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff168111611b375783836137db836020614564565b906137e78460016143bb565b6137f2906020614564565b926137ff93929190614391565b6138089161459a565b82828151811061381a5761381a6146c9565b60209081029190910101528061382f8161463b565b9150506137a4565b600061388c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166139099092919063ffffffff16565b80519091501561372857808060200190518101906138aa9190613dad565b6137285760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610ca5565b60606139188484600085613920565b949350505050565b6060824710156139815760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610ca5565b843b6139cf5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca5565b600080866001600160a01b031685876040516139eb919061400f565b60006040518083038185875af1925050503d8060008114613a28576040519150601f19603f3d011682016040523d82523d6000602084013e613a2d565b606091505b5091509150613a3d828286613a48565b979650505050505050565b60608315613a57575081611a71565b825115613a675782518084602001fd5b8160405162461bcd60e51b8152600401610ca591906141fd565b60405180604001604052806002906020820280368337509192915050565b60405180604001604052806002905b613ab6613a81565b815260200190600190039081613aae5790505090565b60008083601f840112613ade57600080fd5b50813567ffffffffffffffff811115613af657600080fd5b602083019150836020828501011115613b0e57600080fd5b9250929050565b600060e08284031215613b2757600080fd5b50919050565b803563ffffffff81168114612d7157600080fd5b600060208284031215613b5357600080fd5b8135611a71816146f5565b60008060408385031215613b7157600080fd5b8235613b7c816146f5565b946020939093013593505050565b60008060408385031215613b9d57600080fd5b8235613ba8816146f5565b9150613bb660208401613b2d565b90509250929050565b60008060208385031215613bd257600080fd5b823567ffffffffffffffff80821115613bea57600080fd5b818501915085601f830112613bfe57600080fd5b813581811115613c0d57600080fd5b8660208260051b8501011115613c2257600080fd5b60209290920196919550909350505050565b60006020808385031215613c4757600080fd5b823567ffffffffffffffff80821115613c5f57600080fd5b818501915085601f830112613c7357600080fd5b813581811115613c8557613c856146df565b8060051b9150613c96848301614360565b8181528481019084860184860187018a1015613cb157600080fd5b600095505b83861015613cd4578035835260019590950194918601918601613cb6565b5098975050505050505050565b6000610100808385031215613cf557600080fd5b83601f840112613d0457600080fd5b613d0c614336565b8084868487011115613d1d57600080fd5b600093505b6008841015613d4257803583526001939093019260209283019201613d22565b5095945050505050565b6000610100808385031215613d6057600080fd5b83601f840112613d6f57600080fd5b613d77614336565b8084868487011115613d8857600080fd5b600093505b6008841015613d4257805183526001939093019260209283019201613d8d565b600060208284031215613dbf57600080fd5b81518015158114611a7157600080fd5b600060208284031215613de157600080fd5b5035919050565b600080600060408486031215613dfd57600080fd5b833567ffffffffffffffff80821115613e1557600080fd5b613e2187838801613acc565b90955093506020860135915080821115613e3a57600080fd5b50613e4786828701613b15565b9150509250925092565b60008060008060608587031215613e6757600080fd5b843567ffffffffffffffff80821115613e7f57600080fd5b613e8b88838901613acc565b90965094506020870135915080821115613ea457600080fd5b50613eb187828801613b15565b9250506040850135613ec2816146f5565b939692955090935050565b600080600060608486031215613ee257600080fd5b8335613eed816146f5565b95602085013595506040909401359392505050565b600060208284031215613f1457600080fd5b5051919050565b60008060408385031215613f2e57600080fd5b50508035926020909101359150565b600080600060608486031215613f5257600080fd5b505081359360208301359350604090920135919050565b60008060408385031215613f7c57600080fd5b82359150613bb660208401613b2d565b8060005b6002811015613fba57613fa4848351613fc0565b6040939093019260209190910190600101613f90565b50505050565b8060005b6002811015613fba578151845260209384019390910190600101613fc4565b60008151808452613ffb8160208601602086016145ef565b601f01601f19169290920160200192915050565b600082516140218184602087016145ef565b9190910192915050565b8981528860208201528760408201528660608201528560808201528460a08201528360c0820152818360e08301376000910160e00190815298975050505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6020808252825182820181905260009190848201906040850190845b818110156140cd5783511515835292840192918401916001016140af565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156140cd578351835292840192918401916001016140f5565b602080825282518282018190526000919060409081850190868401855b8281101561415d578151805185528681015187860152850151858501526060909301929085019060010161412e565b5091979650505050505050565b60408101610b1e8284613fc0565b61010081016141878286613fc0565b6141946040830185613f8c565b61391860c0830184613fc0565b60006101606141b0838a613fc0565b6141bd6040840189613f8c565b6141ca60c0840188613fc0565b806101008401526141dd81840187613fe3565b60ff95909516610120840152505090151561014090910152949350505050565b602081526000611a716020830184613fe3565b60208082526016908201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b604082015260600190565b60208082526021908201527f54686520636f6d6d69746d656e7420686173206265656e207375626d697474656040820152601960fa1b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526019908201527f73656e646572206973206e6f74207468652068616e646c657200000000000000604082015260600190565b6000808335601e1984360301811261430657600080fd5b83018035915067ffffffffffffffff82111561432157600080fd5b602001915036819003821315613b0e57600080fd5b604051610100810167ffffffffffffffff8111828210171561435a5761435a6146df565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614389576143896146df565b604052919050565b600080858511156143a157600080fd5b838611156143ae57600080fd5b5050820193919092039150565b600082198211156143ce576143ce61469d565b500190565b600063ffffffff8083168185168083038211156143f2576143f261469d565b01949350505050565b600060ff821660ff84168060ff038211156144185761441861469d565b019392505050565b600063ffffffff80841680614437576144376146b3565b92169190910492915050565b600181815b80851115614480578163ffffffff048211156144665761446661469d565b8085161561447357918102915b93841c9390800290614448565b509250929050565b600063ffffffff6139188185168285166000826144a757506001610b1e565b816144b457506000610b1e565b81600181146144ca57600281146144d457614505565b6001915050610b1e565b60ff8411156144e5576144e561469d565b6001841b915063ffffffff8211156144ff576144ff61469d565b50610b1e565b5060208310610133831016604e8410600b841016171561453c575081810a63ffffffff8111156145375761453761469d565b610b1e565b6145468383614443565b8063ffffffff0482111561455c5761455c61469d565b029392505050565b600081600019048311821515161561457e5761457e61469d565b500290565b6000828210156145955761459561469d565b500390565b80356020831015610b1e57600019602084900360031b1b1692915050565b805160208201516001600160d01b031980821692919060068310156145e75780818460060360031b1b83161693505b505050919050565b60005b8381101561460a5781810151838201526020016145f2565b83811115613fba5750506000910152565b600063ffffffff8216806146315761463161469d565b6000190192915050565b600060001982141561464f5761464f61469d565b5060010190565b600063ffffffff808316818114156146705761467061469d565b6001019392505050565b600063ffffffff80841680614691576146916146b3565b92169190910692915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461470a57600080fd5b5056fea2646970667358221220c0ccd0ad910d236cd2bf38a65e3a1f5824a69fb7dbf27a93d770b5509c6434a264736f6c63430008050033"; + "0x610120604052600380546001600160401b0319169055600b805463ffffffff60a01b191690553480156200003257600080fd5b506040516200530238038062005302833981016040819052620000559162000931565b8685858484848383838183818160008263ffffffff1611620000ca5760405162461bcd60e51b815260206004820152602360248201527f5f6c6576656c732073686f756c642062652067726561746572207468616e207a60448201526265726f60e81b60648201526084015b60405180910390fd5b60208263ffffffff1610620001225760405162461bcd60e51b815260206004820152601e60248201527f5f6c6576656c732073686f756c64206265206c657373207468616e20333200006044820152606401620000c1565b60e09190911b6001600160e01b03191660a05260601b6001600160601b03191660805260005b8263ffffffff168163ffffffff16101562000199576200016e63ffffffff8216620002cb565b63ffffffff821660009081526001602052604090205580620001908162000a05565b91505062000148565b50620001b7620001ab600184620009dd565b63ffffffff16620002cb565b6000805260026020527fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b5550506001600455600580546001600160a01b03199081166001600160a01b039687161790915560f89190911b7fff000000000000000000000000000000000000000000000000000000000000001660c052600b805490911697909316969096179091555050508515159250620002ac9150505760405162461bcd60e51b815260206004820152602560248201527f64656e6f6d696e6174696f6e2073686f756c6420626520677265617465722074604482015264068616e20360dc1b6064820152608401620000c1565b505061010052505060601b6001600160601b03191660e0525062000a5b565b600081620002fa57507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b81600114156200032b57507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156200035c57507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b81600314156200038d57507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b8160041415620003be57507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b8160051415620003ef57507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b81600614156200042057507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b81600714156200045157507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b81600814156200048257507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b8160091415620004b357507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a1415620004e457507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b14156200051557507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c14156200054657507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156200057757507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e1415620005a857507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f1415620005d957507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b81601014156200060a57507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b81601114156200063a57507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b81601214156200066b57507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b81601314156200069c57507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b8160141415620006cd57507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b8160151415620006fe57507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b81601614156200072f57507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b81601714156200076057507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b81601814156200079157507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b8160191415620007c257507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a1415620007f357507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b14156200082457507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c14156200085557507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d14156200088657507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e1415620008b757507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f1415620008e857507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b815260206004820152601360248201527f496e646578206f7574206f6620626f756e6473000000000000000000000000006044820152606401620000c1565b600080600080600080600060e0888a0312156200094d57600080fd5b87516200095a8162000a42565b60208901519097506200096d8162000a42565b6040890151909650620009808162000a42565b6060890151909550620009938162000a42565b608089015160a08a0151919550935063ffffffff81168114620009b557600080fd5b60c089015190925060ff81168114620009cd57600080fd5b8091505092959891949750929550565b600063ffffffff83811690831681811015620009fd57620009fd62000a2c565b039392505050565b600063ffffffff8083168181141562000a225762000a2262000a2c565b6001019392505050565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811462000a5857600080fd5b50565b60805160601c60a05160e01c60c05160f81c60e05160601c6101005161474c62000bb660003960008181610397015281816106b401528181611d6601528181611e7301528181611fca01528181612188015281816124870152818161268c0152818161336201528181613391015261345b0152600081816103d401528181610a48015281816111c90152818161129d015281816114d101528181611d3501528181611e9901528181611f5801528181611ff80152818161265c015281816132dc015281816133bf015281816133f90152818161342f015261350c0152600081816105ed01528181610b2801528181610b93015281816110180152818161134c01528181611741015281816117ce015281816131b80152818161373d01526137af01526000818161051e01528181610c1c0152818161188d01528181612ec10152612f640152600081816109880152612ffd015261474c6000f3fe6080604052600436106102c95760003560e01c80638ea3099e11610175578063d0e8d34a116100dc578063ec73295911610095578063f5ab0dd61161006f578063f5ab0dd6146109d7578063fa73168714610a06578063fc0c546a14610a36578063fc7e9c6f14610a6a57600080fd5b8063ec73295914610942578063ed33639f14610976578063f178e47c146109aa57600080fd5b8063d0e8d34a14610864578063dbc916b814610877578063df203aa7146108b2578063e5285dcc146108c5578063e70ea87c146108f5578063e82955881461092257600080fd5b8063b214faa51161012e578063b214faa5146107b2578063ba70f757146107c5578063c2b40ae4146107ef578063c80916d41461081c578063cd3a95501461083c578063cd87a3b41461084f57600080fd5b80638ea3099e146106f857806390eeb02b1461071857806392156311146107355780639fa12d0b146107655780639ff8006314610540578063a0d192f51461079257600080fd5b80634c830cbd116102345780636d9833e3116101ed578063839df945116101c7578063839df945146106415780638b7e8782146106715780638bca6d16146106a25780638c0d34d8146106d657600080fd5b80636d9833e3146105bb57806371523c32146105db57806372c1ad031461062157600080fd5b80634c830cbd146104e05780634ecf518b1461050c5780634f401241146105405780635d2d766c14610560578063616e0957146105935780636ad481f3146105b357600080fd5b80632b7ac3f3116102865780632b7ac3f31461040c5780633408e4701461042c578063414a37ba1461043f57806343e7119f1461047357806344347ba9146104ab578063460b53e3146104c057600080fd5b80630b27fb9a146102ce57806311e4dcb91461030657806317cc915c146103365780631e627617146103665780631fc601c91461038857806321df0da7146103c5575b600080fd5b3480156102da57600080fd5b50600b54600160a01b900463ffffffff165b60405163ffffffff90911681526020015b60405180910390f35b34801561031257600080fd5b50610326610321366004613f24565b610a8f565b60405190151581526020016102fd565b34801561034257600080fd5b50610326610351366004613dd8565b600c6020526000908152604090205460ff1681565b34801561037257600080fd5b5061037b610b24565b6040516102fd91906140e2565b34801561039457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020016102fd565b3480156103d157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020016102fd565b34801561041857600080fd5b50600b546103f4906001600160a01b031681565b34801561043857600080fd5b50466103b7565b34801561044b57600080fd5b506103b77f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b34801561047f57600080fd5b506103b761048e366004613f72565b600960209081526000928352604080842090915290825290205481565b6104be6104b9366004613f46565b610c7b565b005b3480156104cc57600080fd5b506104be6104db366004613b67565b6111b2565b3480156104ec57600080fd5b506104f5611238565b60405165ffffffffffff90911681526020016102fd565b34801561051857600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000000081565b34801561054c57600080fd5b506104be61055b366004613b67565b611286565b34801561056c57600080fd5b506102ec61057b366004613dd8565b600a6020526000908152604090205463ffffffff1681565b34801561059f57600080fd5b506103266105ae366004613c3d565b6112d6565b6104be6114ba565b3480156105c757600080fd5b506103266105d6366004613dd8565b611541565b3480156105e757600080fd5b5061060f7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016102fd565b34801561062d57600080fd5b506104be61063c366004613b93565b6115bc565b34801561064d57600080fd5b5061032661065c366004613dd8565b600d6020526000908152604090205460ff1681565b34801561067d57600080fd5b50610689600160f81b81565b6040516001600160f01b031990911681526020016102fd565b3480156106ae57600080fd5b506103b77f000000000000000000000000000000000000000000000000000000000000000081565b3480156106e257600080fd5b506106eb61173d565b6040516102fd919061411a565b34801561070457600080fd5b506103b7610713366004613ed6565b6118f1565b34801561072457600080fd5b506003546102ec9063ffffffff1681565b34801561074157600080fd5b50610326610750366004613dd8565b60009081526007602052604090205460ff1690565b34801561077157600080fd5b50610785610780366004613bc8565b611a78565b6040516102fd919061409c565b34801561079e57600080fd5b506104be6107ad366004613b93565b611b3e565b6104be6107c0366004613dd8565b611ca9565b3480156107d157600080fd5b5060035463ffffffff166000908152600260205260409020546103b7565b3480156107fb57600080fd5b506103b761080a366004613dd8565b60026020526000908152604090205481565b34801561082857600080fd5b506005546103f4906001600160a01b031681565b6104be61084a366004613b67565b611e27565b34801561085b57600080fd5b506102ec601e81565b6104be610872366004613df1565b61215e565b34801561088357600080fd5b50610897610892366004613dd8565b61242a565b604080519384526020840192909252908201526060016102fd565b6104be6108c0366004613e5a565b61245d565b3480156108d157600080fd5b506103266108e0366004613dd8565b6000908152600c602052604090205460ff1690565b34801561090157600080fd5b506103b7610910366004613dd8565b60066020526000908152604090205481565b34801561092e57600080fd5b506103b761093d366004613dd8565b612736565b34801561094e57600080fd5b506103b77f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c81565b34801561098257600080fd5b506103f47f000000000000000000000000000000000000000000000000000000000000000081565b3480156109b657600080fd5b506103b76109c5366004613dd8565b60016020526000908152604090205481565b3480156109e357600080fd5b506109f76109f2366004613cea565b612d76565b6040516102fd93929190614181565b348015610a1257600080fd5b50610326610a21366004613dd8565b60076020526000908152604090205460ff1681565b348015610a4257600080fd5b506103f47f000000000000000000000000000000000000000000000000000000000000000081565b348015610a7657600080fd5b506003546102ec90640100000000900463ffffffff1681565b600081610a9e57506000610b1e565b6000838152600a602052604090205463ffffffff16805b600085815260096020908152604080832063ffffffff85168452909152902054841415610ae757600192505050610b1e565b63ffffffff8116610af65750601e5b80610b0081614624565b9150508163ffffffff168163ffffffff161415610ab5576000925050505b92915050565b60607f000000000000000000000000000000000000000000000000000000000000000060ff1667ffffffffffffffff811115610b6257610b626146e8565b604051908082528060200260200182016040528015610b8b578160200160208202803683370190505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610c7757610bc78160016143c4565b60085410610c175760088181548110610be257610be26146d2565b906000526020600020906003020160010154828281518110610c0657610c066146d2565b602002602001018181525050610c65565b610c467f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612736565b828281518110610c5857610c586146d2565b6020026020010181815250505b80610c6f81614644565b915050610b91565b5090565b6005546001600160a01b03163314610cae5760405162461bcd60e51b8152600401610ca5906142c1565b60405180910390fd5b60026004541415610cd15760405162461bcd60e51b8152600401610ca59061428a565b60026004908155604051639215631160e01b8152908101849052309063921563119060240160206040518083038186803b158015610d0e57600080fd5b505afa158015610d22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d469190613db6565b156110115760008381526007602052604090205460ff16610dcf5760405162461bcd60e51b815260206004820152603760248201527f436861696e206d75737420626520696e74656772617465642066726f6d20746860448201527f6520627269646765206265666f726520757064617465730000000000000000006064820152608401610ca5565b600083815260066020526040902054600880548392908110610df357610df36146d2565b90600052602060002090600302016002015410610e525760405162461bcd60e51b815260206004820152601e60248201527f4e6577206c65616620696e646578206d757374206265206772656174657200006044820152606401610ca5565b600083815260066020526040902054600880549091908110610e7657610e766146d2565b90600052602060002090600302016002015462010000610e9691906143c4565b8110610ef45760405162461bcd60e51b815260206004820152602760248201527f4e6577206c65616620696e646578206d7573742077697468696e20325e3136206044820152667570646174657360c81b6064820152608401610ca5565b6000838152600660209081526040918290205482516060810184528681529182018590529181018390526008805483908110610f3257610f326146d2565b60009182526020808320845160039093020191825583810151600180840191909155604094850151600290930192909255878352600a9052918120549091601e91610f859163ffffffff909116906143dc565b610f8f9190614683565b6000868152600a60209081526040808320805463ffffffff191663ffffffff86169081179091556009835281842090845282529182902087905581518881529081018690529081018690529091507f675e61f04bcf314a9c310a93f2346f417a03d704c1caf9c6af8a65ad8addfa3f9060600160405180910390a150506111a8565b60085460ff7f000000000000000000000000000000000000000000000000000000000000000016116110855760405162461bcd60e51b815260206004820152601a60248201527f5468697320416e63686f722069732061742063617061636974790000000000006044820152606401610ca5565b6000838152600760209081526040808320805460ff19166001908117909155600880548351606080820186528a82528187018a81528287018a815295840185559388528151600384027ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee381019190915593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee485015593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee590930192909255888652600685528386208190556009855283862086805285528386208890558351898152948501879052928401879052919391927fcf4749969bace1552af6a97fe7e4affedf68875511f9746c6332eb40647b3054910160405180910390a15050505b5050600160045550565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca693889061120290339086908690600401614078565b600060405180830381600087803b15801561121c57600080fd5b505af1158015611230573d6000803e3d6000fd5b505050505050565b60408051600160f81b602082018190524660e01b6001600160e01b0319811660228401528351808403600601815260269093019093526000929161127b816145c1565b60d01c935050505090565b60405163130e405b60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063261c80b69061120290339086908690600401614078565b60006112fb826000815181106112ee576112ee6146d2565b6020026020010151611541565b6113475760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f742066696e6420796f7572206d65726b6c6520726f6f74000000006044820152606401610ca5565b6113727f00000000000000000000000000000000000000000000000000000000000000006001614404565b60ff168251146113c45760405162461bcd60e51b815260206004820152601b60248201527f496e636f727265637420726f6f74206172726179206c656e67746800000000006044820152606401610ca5565b60005b6008548110156114b1576000600882815481106113e6576113e66146d2565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905061145281600001518584600161143591906143c4565b81518110611445576114456146d2565b6020026020010151610a8f565b61149e5760405162461bcd60e51b815260206004820152601760248201527f4e65696768626f7220726f6f74206e6f7420666f756e640000000000000000006044820152606401610ca5565b50806114a981614644565b9150506113c7565b50600192915050565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca6938890349061150d9033906000908190600401614078565b6000604051808303818588803b15801561152657600080fd5b505af115801561153a573d6000803e3d6000fd5b5050505050565b60008161155057506000919050565b60035463ffffffff16805b63ffffffff8116600090815260026020526040902054841415611582575060019392505050565b63ffffffff81166115915750601e5b8061159b81614624565b9150508163ffffffff168163ffffffff16141561155b575060009392505050565b6005546001600160a01b031633146115e65760405162461bcd60e51b8152600401610ca5906142c1565b6001600160a01b0382166116325760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610ca5565b600b5463ffffffff808316600160a01b90920416106116835760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610ca5565b600b5461169e90600160a01b900463ffffffff1660016143dc565b63ffffffff168163ffffffff1611156116f55760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610ca5565b600580546001600160a01b039093166001600160a01b031990931692909217909155600b805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b60607f000000000000000000000000000000000000000000000000000000000000000060ff1667ffffffffffffffff81111561177b5761177b6146e8565b6040519080825280602002602001820160405280156117c657816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816117995790505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610c77576118028160016143c4565b60085410611876576008818154811061181d5761181d6146d2565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050828281518110611866576118666146d2565b60200260200101819052506118df565b6040518060600160405280600081526020016118b77f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612736565b815260200160008152508282815181106118d3576118d36146d2565b60200260200101819052505b806118e981614644565b9150506117cc565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000183106119625760405162461bcd60e51b815260206004820181905260248201527f5f6c6566742073686f756c6420626520696e7369646520746865206669656c646044820152606401610ca5565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182106119db5760405162461bcd60e51b815260206004820152602160248201527f5f72696768742073686f756c6420626520696e7369646520746865206669656c6044820152601960fa1b6064820152608401610ca5565b6040805180820182528481526020810184905290516314d2f97b60e11b8152849184916001600160a01b038816916329a5f2f691611a1c9190600401614173565b60206040518083038186803b158015611a3457600080fd5b505afa158015611a48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6c9190613f0b565b925050505b9392505050565b60608167ffffffffffffffff811115611a9357611a936146e8565b604051908082528060200260200182016040528015611abc578160200160208202803683370190505b50905060005b82811015611b3757611afb848483818110611adf57611adf6146d2565b905060200201356000908152600c602052604090205460ff1690565b15611b25576001828281518110611b1457611b146146d2565b911515602092830291909101909101525b80611b2f81614644565b915050611ac2565b5092915050565b6005546001600160a01b03163314611b685760405162461bcd60e51b8152600401610ca5906142c1565b6001600160a01b038216611bb45760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610ca5565b600b5463ffffffff808316600160a01b9092041610611c055760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610ca5565b600b54611c2090600160a01b900463ffffffff1660016143dc565b63ffffffff168163ffffffff161115611c775760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610ca5565b600b805463ffffffff909216600160a01b026001600160c01b03199092166001600160a01b0390931692909217179055565b3415611d105760405162461bcd60e51b815260206004820152603060248201527f4554482076616c756520697320737570706f73656420746f206265203020666f60448201526f7220455243323020696e7374616e636560801b6064820152608401610ca5565b6000611d1b82612dff565b6040516323b872dd60e01b81529091506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906323b872dd90611d8e90339030907f000000000000000000000000000000000000000000000000000000000000000090600401614078565b602060405180830381600087803b158015611da857600080fd5b505af1158015611dbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de09190613db6565b5060408051338152426020820152839163ffffffff8416917fb50b68adb3452534cd51b362b06e4194335b46951229ec1945a94a158c2b48b2910160405180910390a35050565b6000818152600d602052604090205460ff1615611e565760405162461bcd60e51b8152600401610ca590614249565b6001600160a01b038216611fbb57604051634b66a6ff60e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906396cd4dfe9060240160206040518083038186803b158015611ee357600080fd5b505afa158015611ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f1b9190613f0b565b3414611f2657600080fd5b604051633d97186b60e11b81523360048201526001600160a01b038381166024830152600060448301523060648301527f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d69034906084016000604051808303818588803b158015611f9d57600080fd5b505af1158015611fb1573d6000803e3d6000fd5b50505050506120ec565b604051634b66a6ff60e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d6903390859084906396cd4dfe9060240160206040518083038186803b15801561204657600080fd5b505afa15801561205a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207e9190613f0b565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152306064820152608401600060405180830381600087803b1580156120d357600080fd5b505af11580156120e7573d6000803e3d6000fd5b505050505b60006120f782612ea8565b6000838152600d6020908152604091829020805460ff1916600117905581513381524291810191909152919250839163ffffffff8416917fb50b68adb3452534cd51b362b06e4194335b46951229ec1945a94a158c2b48b2910160405180910390a3505050565b600260045414156121815760405162461bcd60e51b8152600401610ca59061428a565b60026004557f000000000000000000000000000000000000000000000000000000000000000060a082013511156121fa5760405162461bcd60e51b815260206004820152601a60248201527f4665652065786365656473207472616e736665722076616c75650000000000006044820152606401610ca5565b61221781602001356000908152600c602052604090205460ff1690565b156122645760405162461bcd60e51b815260206004820152601f60248201527f546865206e6f746520686173206265656e20616c7265616479207370656e74006044820152606401610ca5565b600080612270836130d2565b9150915061227d816112d6565b6122b95760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610ca5565b6122fa85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525086925061315b915050565b6123165760405162461bcd60e51b8152600401610ca590614219565b6020808401356000908152600c909152604090819020805460ff19166001179055830135612375576123706123516080850160608601613b4a565b61236160a0860160808701613b4a565b8560a001358660c0013561325c565b61241e565b6040808401356000908152600d602052205460ff16156123a75760405162461bcd60e51b8152600401610ca590614249565b60006123b68460400135612ea8565b6040858101356000818152600d602090815290839020805460ff19166001179055825181890135815263ffffffff851691810191909152929350917f138604f043594af1377bf30140984eef19cad0fb0c801cbb9b879005eddc06f0910160405180910390a2505b50506001600455505050565b6008818154811061243a57600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b600260045414156124805760405162461bcd60e51b8152600401610ca59061428a565b60026004557f000000000000000000000000000000000000000000000000000000000000000060a083013511156124f95760405162461bcd60e51b815260206004820152601a60248201527f4665652065786365656473207472616e736665722076616c75650000000000006044820152606401610ca5565b6020808301356000908152600c909152604090205460ff161561255e5760405162461bcd60e51b815260206004820152601f60248201527f546865206e6f746520686173206265656e20616c7265616479207370656e74006044820152606401610ca5565b60008061256a846130d2565b91509150612577816112d6565b6125b35760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610ca5565b6125f486868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525086925061315b915050565b6126105760405162461bcd60e51b8152600401610ca590614219565b6020808501356000908152600c90915260409020805460ff191660011790556126523061264360a0870160808801613b4a565b8660a001358760c0013561325c565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016634808285e846126b060a08801357f000000000000000000000000000000000000000000000000000000000000000061458c565b6126c06080890160608a01613b4a565b60405160e085901b6001600160e01b03191681526001600160a01b03938416600482015260248101929092529091166044820152606401600060405180830381600087803b15801561271157600080fd5b505af1158015612725573d6000803e3d6000fd5b505060016004555050505050505050565b60008161276457507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b816001141561279457507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156127c457507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b81600314156127f457507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b816004141561282457507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b816005141561285457507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b816006141561288457507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b81600714156128b457507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b81600814156128e457507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b816009141561291457507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a141561294457507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b141561297457507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c14156129a457507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156129d457507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e1415612a0457507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f1415612a3457507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b8160101415612a6457507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b8160111415612a9357507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b8160121415612ac357507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b8160131415612af357507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b8160141415612b2357507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b8160151415612b5357507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b8160161415612b8357507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b8160171415612bb357507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b8160181415612be357507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b8160191415612c1357507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a1415612c4357507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b1415612c7357507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c1415612ca357507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d1415612cd357507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e1415612d0357507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f1415612d3357507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b6044820152606401610ca5565b919050565b612d7e613a8a565b612d86613aa8565b612d8e613a8a565b50506040805180820182528351815260208085015181830152825160808082018552868501518286019081526060808901519084015282528451808601865290870151815260a08701518184015281830152835180850190945260c0860151845260e0909501519083015293909150565b6000818152600d602052604081205460ff1615612e2e5760405162461bcd60e51b8152600401610ca590614249565b6000612e3983612ea8565b6000848152600d602052604090819020805460ff191660011790555190915083907fe77f587aa74084fff834b53ccbab07695ee4594b9c9d5bfd8a7dd80c556124b590612e9a908490429063ffffffff929092168252602082015260400190565b60405180910390a292915050565b600354600090640100000000900463ffffffff16612ee77f00000000000000000000000000000000000000000000000000000000000000006002614491565b63ffffffff168163ffffffff161415612f5b5760405162461bcd60e51b815260206004820152603060248201527f4d65726b6c6520747265652069732066756c6c2e204e6f206d6f7265206c656160448201526f1d995cc818d85b88189948185919195960821b6064820152608401610ca5565b8083600080805b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff16101561304457612fa1600286614683565b63ffffffff16612fdc57839250612fbd8163ffffffff16612736565b63ffffffff821660009081526001602052604090208590559150612ff8565b63ffffffff811660009081526001602052604090205492508391505b6130237f000000000000000000000000000000000000000000000000000000000000000084846118f1565b9350613030600286614429565b94508061303c8161465f565b915050612f62565b50600354600090601e9061305f9063ffffffff1660016143dc565b6130699190614683565b6003805463ffffffff191663ffffffff83169081179091556000908152600260205260409020859055905061309f8660016143dc565b6003805463ffffffff929092166401000000000267ffffffff000000001990921691909117905550939695505050505050565b6060806131526130e284806142f8565b6040805160c0810182526020808901358252888301359082015290810161310f6080890160608a01613b4a565b6001600160a01b0316815260200161312d60a0890160808a01613b4a565b6001600160a01b031681526020018760a0013581526020018760c0013581525061364f565b91509150915091565b600080838060200190518101906131729190613d55565b9050600080600061318284612d76565b600b54604051638041ca5360e01b815293965091945092506001600160a01b031690638041ca53906131e3908690869086908c907f0000000000000000000000000000000000000000000000000000000000000000906001906004016141aa565b60206040518083038186803b1580156131fb57600080fd5b505afa15801561320f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132339190613db6565b9450846132525760405162461bcd60e51b8152600401610ca590614219565b5050505092915050565b8034146132c45760405162461bcd60e51b815260206004820152603060248201527f496e636f727265637420726566756e6420616d6f756e7420726563656976656460448201526f08189e481d1a194818dbdb9d1c9858dd60821b6064820152608401610ca5565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561332657600080fd5b505afa15801561333a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061335e9190613f0b565b90507f00000000000000000000000000000000000000000000000000000000000000008110613425576133e6856133b5857f000000000000000000000000000000000000000000000000000000000000000061458c565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691906136df565b8215613420576134206001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001685856136df565b613569565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166340c10f198661347f867f000000000000000000000000000000000000000000000000000000000000000061458c565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156134c557600080fd5b505af11580156134d9573d6000803e3d6000fd5b505050506000831115613569576040516340c10f1960e01b81526001600160a01b038581166004830152602482018590527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b15801561355057600080fd5b505af1158015613564573d6000803e3d6000fd5b505050505b604080516001600160a01b038781168252602082018690528616917f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b6398910160405180910390a2811561153a576000856001600160a01b03168360405160006040518083038185875af1925050503d8060008114613602576040519150601f19603f3d011682016040523d82523d6000602084013e613607565b606091505b5050905080611230576040516001600160a01b0386169084156108fc029085906000818181858888f19350505050158015613646573d6000803e3d6000fd5b50505050505050565b6060806000836000015160001c84604001516001600160a01b031685606001516001600160a01b031686608001518760a00151886020015160001c613692611238565b65ffffffffffff168c8c6040516020016136b499989796959493929190614034565b604051602081830303815290604052905060006136d18787613736565b919791965090945050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052613731908490613840565b505050565b60606137637f00000000000000000000000000000000000000000000000000000000000000006001614404565b60ff1667ffffffffffffffff81111561377e5761377e6146e8565b6040519080825280602002602001820160405280156137a7578160200160208202803683370190505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff168111611b375783836137e483602061456d565b906137f08460016143c4565b6137fb90602061456d565b926138089392919061439a565b613811916145a3565b828281518110613823576138236146d2565b60209081029190910101528061383881614644565b9150506137ad565b6000613895826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166139129092919063ffffffff16565b80519091501561373157808060200190518101906138b39190613db6565b6137315760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610ca5565b60606139218484600085613929565b949350505050565b60608247101561398a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610ca5565b843b6139d85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca5565b600080866001600160a01b031685876040516139f49190614018565b60006040518083038185875af1925050503d8060008114613a31576040519150601f19603f3d011682016040523d82523d6000602084013e613a36565b606091505b5091509150613a46828286613a51565b979650505050505050565b60608315613a60575081611a71565b825115613a705782518084602001fd5b8160405162461bcd60e51b8152600401610ca59190614206565b60405180604001604052806002906020820280368337509192915050565b60405180604001604052806002905b613abf613a8a565b815260200190600190039081613ab75790505090565b60008083601f840112613ae757600080fd5b50813567ffffffffffffffff811115613aff57600080fd5b602083019150836020828501011115613b1757600080fd5b9250929050565b600060e08284031215613b3057600080fd5b50919050565b803563ffffffff81168114612d7157600080fd5b600060208284031215613b5c57600080fd5b8135611a71816146fe565b60008060408385031215613b7a57600080fd5b8235613b85816146fe565b946020939093013593505050565b60008060408385031215613ba657600080fd5b8235613bb1816146fe565b9150613bbf60208401613b36565b90509250929050565b60008060208385031215613bdb57600080fd5b823567ffffffffffffffff80821115613bf357600080fd5b818501915085601f830112613c0757600080fd5b813581811115613c1657600080fd5b8660208260051b8501011115613c2b57600080fd5b60209290920196919550909350505050565b60006020808385031215613c5057600080fd5b823567ffffffffffffffff80821115613c6857600080fd5b818501915085601f830112613c7c57600080fd5b813581811115613c8e57613c8e6146e8565b8060051b9150613c9f848301614369565b8181528481019084860184860187018a1015613cba57600080fd5b600095505b83861015613cdd578035835260019590950194918601918601613cbf565b5098975050505050505050565b6000610100808385031215613cfe57600080fd5b83601f840112613d0d57600080fd5b613d1561433f565b8084868487011115613d2657600080fd5b600093505b6008841015613d4b57803583526001939093019260209283019201613d2b565b5095945050505050565b6000610100808385031215613d6957600080fd5b83601f840112613d7857600080fd5b613d8061433f565b8084868487011115613d9157600080fd5b600093505b6008841015613d4b57805183526001939093019260209283019201613d96565b600060208284031215613dc857600080fd5b81518015158114611a7157600080fd5b600060208284031215613dea57600080fd5b5035919050565b600080600060408486031215613e0657600080fd5b833567ffffffffffffffff80821115613e1e57600080fd5b613e2a87838801613ad5565b90955093506020860135915080821115613e4357600080fd5b50613e5086828701613b1e565b9150509250925092565b60008060008060608587031215613e7057600080fd5b843567ffffffffffffffff80821115613e8857600080fd5b613e9488838901613ad5565b90965094506020870135915080821115613ead57600080fd5b50613eba87828801613b1e565b9250506040850135613ecb816146fe565b939692955090935050565b600080600060608486031215613eeb57600080fd5b8335613ef6816146fe565b95602085013595506040909401359392505050565b600060208284031215613f1d57600080fd5b5051919050565b60008060408385031215613f3757600080fd5b50508035926020909101359150565b600080600060608486031215613f5b57600080fd5b505081359360208301359350604090920135919050565b60008060408385031215613f8557600080fd5b82359150613bbf60208401613b36565b8060005b6002811015613fc357613fad848351613fc9565b6040939093019260209190910190600101613f99565b50505050565b8060005b6002811015613fc3578151845260209384019390910190600101613fcd565b600081518084526140048160208601602086016145f8565b601f01601f19169290920160200192915050565b6000825161402a8184602087016145f8565b9190910192915050565b8981528860208201528760408201528660608201528560808201528460a08201528360c0820152818360e08301376000910160e00190815298975050505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6020808252825182820181905260009190848201906040850190845b818110156140d65783511515835292840192918401916001016140b8565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156140d6578351835292840192918401916001016140fe565b602080825282518282018190526000919060409081850190868401855b828110156141665781518051855286810151878601528501518585015260609093019290850190600101614137565b5091979650505050505050565b60408101610b1e8284613fc9565b61010081016141908286613fc9565b61419d6040830185613f95565b61392160c0830184613fc9565b60006101606141b9838a613fc9565b6141c66040840189613f95565b6141d360c0840188613fc9565b806101008401526141e681840187613fec565b60ff95909516610120840152505090151561014090910152949350505050565b602081526000611a716020830184613fec565b60208082526016908201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b604082015260600190565b60208082526021908201527f54686520636f6d6d69746d656e7420686173206265656e207375626d697474656040820152601960fa1b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526019908201527f73656e646572206973206e6f74207468652068616e646c657200000000000000604082015260600190565b6000808335601e1984360301811261430f57600080fd5b83018035915067ffffffffffffffff82111561432a57600080fd5b602001915036819003821315613b1757600080fd5b604051610100810167ffffffffffffffff81118282101715614363576143636146e8565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614392576143926146e8565b604052919050565b600080858511156143aa57600080fd5b838611156143b757600080fd5b5050820193919092039150565b600082198211156143d7576143d76146a6565b500190565b600063ffffffff8083168185168083038211156143fb576143fb6146a6565b01949350505050565b600060ff821660ff84168060ff03821115614421576144216146a6565b019392505050565b600063ffffffff80841680614440576144406146bc565b92169190910492915050565b600181815b80851115614489578163ffffffff0482111561446f5761446f6146a6565b8085161561447c57918102915b93841c9390800290614451565b509250929050565b600063ffffffff6139218185168285166000826144b057506001610b1e565b816144bd57506000610b1e565b81600181146144d357600281146144dd5761450e565b6001915050610b1e565b60ff8411156144ee576144ee6146a6565b6001841b915063ffffffff821115614508576145086146a6565b50610b1e565b5060208310610133831016604e8410600b8410161715614545575081810a63ffffffff811115614540576145406146a6565b610b1e565b61454f838361444c565b8063ffffffff04821115614565576145656146a6565b029392505050565b6000816000190483118215151615614587576145876146a6565b500290565b60008282101561459e5761459e6146a6565b500390565b80356020831015610b1e57600019602084900360031b1b1692915050565b805160208201516001600160d01b031980821692919060068310156145f05780818460060360031b1b83161693505b505050919050565b60005b838110156146135781810151838201526020016145fb565b83811115613fc35750506000910152565b600063ffffffff82168061463a5761463a6146a6565b6000190192915050565b6000600019821415614658576146586146a6565b5060010190565b600063ffffffff80831681811415614679576146796146a6565b6001019392505050565b600063ffffffff8084168061469a5761469a6146bc565b92169190910692915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461471357600080fd5b5056fea2646970667358221220ef5a316fbf437152da5d29a2ddb7b0ceb82c7e52d7801857b676b0c32e6257c364736f6c63430008050033"; export class FixedDepositAnchor__factory extends ContractFactory { constructor( diff --git a/packages/contracts/src/factories/SignatureBridge__factory.ts b/packages/contracts/src/factories/SignatureBridge__factory.ts index 9c8de6259..36efc43f9 100644 --- a/packages/contracts/src/factories/SignatureBridge__factory.ts +++ b/packages/contracts/src/factories/SignatureBridge__factory.ts @@ -79,6 +79,19 @@ const _abi = [ name: "Unpaused", type: "event", }, + { + inputs: [], + name: "EVM_CHAIN_ID_TYPE", + outputs: [ + { + internalType: "bytes2", + name: "", + type: "bytes2", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [ { @@ -117,29 +130,6 @@ const _abi = [ stateMutability: "view", type: "function", }, - { - inputs: [ - { - internalType: "bytes32[]", - name: "resourceIDs", - type: "bytes32[]", - }, - { - internalType: "address", - name: "newBridge", - type: "address", - }, - { - internalType: "bytes", - name: "sig", - type: "bytes", - }, - ], - name: "adminMigrateBridgeWithSignature", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, { inputs: [ { @@ -218,6 +208,19 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "getChainIdType", + outputs: [ + { + internalType: "uint48", + name: "", + type: "uint48", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [], name: "governor", @@ -420,7 +423,7 @@ const _abi = [ ]; const _bytecode = - "0x60806040526000805463ffffffff60a81b1916905534801561002057600080fd5b506040516119f13803806119f183398101604081905261003f9161009d565b600080546001600160a81b0319166101006001600160a01b03848116820292909217808455604051859492909104909216917f1f323489f404e3bad762215fc05447f9a77bb7f3b630a6f08a2851b999db41f7908290a350506100cd565b6000602082840312156100af57600080fd5b81516001600160a01b03811681146100c657600080fd5b9392505050565b611915806100dc6000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638755bcad116100a2578063a6e94c9111610071578063a6e94c9114610253578063c7af335214610266578063d4066f4c1461027e578063d75a068314610291578063f1835db7146102d457600080fd5b80638755bcad1461020757806387ac4f511461021a578063911005e71461022d5780639d2b1ed71461024057600080fd5b80633408e470116100e95780633408e4701461019e5780635c975abb146101ac578063715018a6146101c35780637296b5d8146101cb57806384db809f146101de57600080fd5b80630c340a241461011b57806313cb01f91461014a5780631ed13d1b146101765780631eee6bc81461018b575b600080fd5b60005461010090046001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b60005461016190600160a81b900463ffffffff1681565b60405163ffffffff9091168152602001610141565b6101896101843660046114e2565b6102e7565b005b61018961019936600461124d565b610337565b604051468152602001610141565b60005460ff165b6040519015158152602001610141565b610189610481565b6101896101d9366004611546565b6104ff565b61012d6101ec3660046113e5565b6003602052600090815260409020546001600160a01b031681565b6101b36102153660046114e2565b610665565b610189610228366004611346565b61069b565b61018961023b3660046112e8565b6107dc565b61018961024e366004611483565b610967565b6101896102613660046112b5565b610b11565b60005461010090046001600160a01b031633146101b3565b6101b361028c366004611441565b610be7565b6102bb61029f3660046113e5565b60026020526000908152604090205467ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610141565b6101b36102e23660046113fe565b610c1d565b8151602083012060006102fa8284610d12565b6040519091506001600160a01b038216907f391f5edd7209ba797e8055bce97cab2d1a480a2849b0c7fe965c370457166dc490600090a250505050565b6040516001600160601b0319606086811b821660208401526034830186905284901b166054820152606801604051602081830303815290604052805190602001208160006040518060400160405280601c81526020016000805160206118c083398151915281525090506103cc81846040516020016103b792919061162d565b60405160208183030381529060405283610665565b6103f15760405162461bcd60e51b81526004016103e8906116ff565b60405180910390fd5b6000868152600360205260409081902080546001600160a01b0319166001600160a01b038a81169182179092559151635c7d1b9b60e11b815260048101899052908716602482015288919063b8fa373690604401600060405180830381600087803b15801561045f57600080fd5b505af1158015610473573d6000803e3d6000fd5b505050505050505050505050565b60005461010090046001600160a01b031633146104b05760405162461bcd60e51b81526004016103e8906116b9565b600080546040516101009091046001600160a01b0316907f1f323489f404e3bad762215fc05447f9a77bb7f3b630a6f08a2851b999db41f7908390a360008054610100600160a81b0319169055565b60005463ffffffff808416600160a81b90920416106105305760405162461bcd60e51b81526004016103e89061174e565b60005461054b90600160a81b900463ffffffff1660016117d6565b63ffffffff168263ffffffff1611156105765760405162461bcd60e51b81526004016103e890611775565b604080518082018252601c81526000805160206118c083398151915260208083019190915285518682012092519192916000916105b7918791899101611663565b60408051808303601f190181528282528051602091820120908301819052925083916106139186910160408051601f19818403018152908290526105fe9291602001611646565b60405160208183030381529060405286610665565b61062f5760405162461bcd60e51b81526004016103e8906116b9565b61063881610d36565b50506000805463ffffffff909516600160a81b0263ffffffff60a81b199095169490941790935550505050565b815160208301206000908161067a8285610d12565b60005461010090046001600160a01b03908116911614925050505b92915050565b8383836040516020016106b0939291906115de565b604051602081830303815290604052805190602001208160006040518060400160405280601c81526020016000805160206118c0833981519152815250905061070581846040516020016103b792919061162d565b6107215760405162461bcd60e51b81526004016103e8906116ff565b60005b868110156107d2576000600360008a8a8581811061074457610744611893565b60209081029290920135835250810191909152604090810160002054905163d7f5b35960e01b81526001600160a01b0389811660048301529091169150819063d7f5b35990602401600060405180830381600087803b1580156107a657600080fd5b505af11580156107ba573d6000803e3d6000fd5b505050505080806107ca9061184c565b915050610724565b5050505050505050565b60005463ffffffff808416600160a81b909204161061080d5760405162461bcd60e51b81526004016103e89061174e565b60005461082890600160a81b900463ffffffff1660016117d6565b63ffffffff168263ffffffff1611156108535760405162461bcd60e51b81526004016103e890611775565b60006040518060400160405280601c81526020016000805160206118c08339815191528152509050600083856040516020016108b592919060e09290921b6001600160e01b031916825260601b6001600160601b031916600482015260180190565b60405160208183030381529060405280519060200120905061091782826040516020016108e491815260200190565b60408051601f19818403018152908290526109029291602001611646565b60405160208183030381529060405284610665565b6109335760405162461bcd60e51b81526004016103e8906116b9565b61093c85610d36565b50506000805463ffffffff909316600160a81b0263ffffffff60a81b19909316929092179091555050565b828260405161097792919061161d565b60405180910390208160006040518060400160405280601c81526020016000805160206118c083398151915281525090506109be81846040516020016103b792919061162d565b6109da5760405162461bcd60e51b81526004016103e8906116ff565b3660006109ea602082898b6117ac565b909250905060006109fb82846117fe565b90506000610a0d6020601c85876117ac565b610a169161181c565b905060e081901c4663ffffffff1614610a715760405162461bcd60e51b815260206004820152601860248201527f657865637574696e67206f6e2077726f6e6720636861696e000000000000000060448201526064016103e8565b60006003600084815260200190815260200160002060009054906101000a90046001600160a01b031690506000819050806001600160a01b031663e248cff2858e8e6040518463ffffffff1660e01b8152600401610ad193929190611683565b600060405180830381600087803b158015610aeb57600080fd5b505af1158015610aff573d6000803e3d6000fd5b50505050505050505050505050505050565b60005461010090046001600160a01b03163314610b405760405162461bcd60e51b81526004016103e8906116b9565b60005463ffffffff808316600160a81b9092041610610b715760405162461bcd60e51b81526004016103e89061174e565b600054610b8c90600160a81b900463ffffffff1660016117d6565b63ffffffff168163ffffffff161115610bb75760405162461bcd60e51b81526004016103e890611775565b610bc082610d36565b6000805463ffffffff909216600160a81b0263ffffffff60a81b1990921691909117905550565b6000336001600160a01b03168383604051610c0392919061161d565b6040519081900390206001600160a01b0316149392505050565b6000806040518060400160405280601c81526020016000805160206118c0833981519152815250905060008187604051602001610c5b92919061162d565b604051602081830303815290604052805190602001209050610c8b6000546001600160a01b036101009091041690565b6001600160a01b031660018288888860405160008152602001604052604051610cd0949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610cf2573d6000803e3d6000fd5b505050602060405103516001600160a01b03161492505050949350505050565b6000806000610d218585610e04565b91509150610d2e81610e74565b509392505050565b6001600160a01b038116610d9e5760405162461bcd60e51b815260206004820152602960248201527f476f7665726e61626c653a206e6577206f776e657220697320746865207a65726044820152686f206164647265737360b81b60648201526084016103e8565b600080546040516001600160a01b038085169361010090930416917f1f323489f404e3bad762215fc05447f9a77bb7f3b630a6f08a2851b999db41f791a3600080546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600080825160411415610e3b5760208301516040840151606085015160001a610e2f87828585611032565b94509450505050610e6d565b825160401415610e655760208301516040840151610e5a86838361111f565b935093505050610e6d565b506000905060025b9250929050565b6000816004811115610e8857610e8861187d565b1415610e915750565b6001816004811115610ea557610ea561187d565b1415610ef35760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016103e8565b6002816004811115610f0757610f0761187d565b1415610f555760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016103e8565b6003816004811115610f6957610f6961187d565b1415610fc25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016103e8565b6004816004811115610fd657610fd661187d565b141561102f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016103e8565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156110695750600090506003611116565b8460ff16601b1415801561108157508460ff16601c14155b156110925750600090506004611116565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156110e6573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661110f57600060019250925050611116565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b0161114087828885611032565b935093505050935093915050565b80356001600160a01b038116811461116557600080fd5b919050565b60008083601f84011261117c57600080fd5b50813567ffffffffffffffff81111561119457600080fd5b602083019150836020828501011115610e6d57600080fd5b600082601f8301126111bd57600080fd5b813567ffffffffffffffff808211156111d8576111d86118a9565b604051601f8301601f19908116603f01168101908282118183101715611200576112006118a9565b8160405283815286602085880101111561121957600080fd5b836020870160208301376000602085830101528094505050505092915050565b803563ffffffff8116811461116557600080fd5b6000806000806080858703121561126357600080fd5b61126c8561114e565b9350602085013592506112816040860161114e565b9150606085013567ffffffffffffffff81111561129d57600080fd5b6112a9878288016111ac565b91505092959194509250565b600080604083850312156112c857600080fd5b6112d18361114e565b91506112df60208401611239565b90509250929050565b6000806000606084860312156112fd57600080fd5b6113068461114e565b925061131460208501611239565b9150604084013567ffffffffffffffff81111561133057600080fd5b61133c868287016111ac565b9150509250925092565b6000806000806060858703121561135c57600080fd5b843567ffffffffffffffff8082111561137457600080fd5b818701915087601f83011261138857600080fd5b81358181111561139757600080fd5b8860208260051b85010111156113ac57600080fd5b602083019650809550506113c26020880161114e565b935060408701359150808211156113d857600080fd5b506112a9878288016111ac565b6000602082840312156113f757600080fd5b5035919050565b6000806000806080858703121561141457600080fd5b84359350602085013560ff8116811461142c57600080fd5b93969395505050506040820135916060013590565b6000806020838503121561145457600080fd5b823567ffffffffffffffff81111561146b57600080fd5b6114778582860161116a565b90969095509350505050565b60008060006040848603121561149857600080fd5b833567ffffffffffffffff808211156114b057600080fd5b6114bc8783880161116a565b909550935060208601359150808211156114d557600080fd5b5061133c868287016111ac565b600080604083850312156114f557600080fd5b823567ffffffffffffffff8082111561150d57600080fd5b611519868387016111ac565b9350602085013591508082111561152f57600080fd5b5061153c858286016111ac565b9150509250929050565b60008060006060848603121561155b57600080fd5b833567ffffffffffffffff8082111561157357600080fd5b61157f878388016111ac565b945061158d60208701611239565b935060408601359150808211156114d557600080fd5b6000815160005b818110156115c457602081850181015186830152016115aa565b818111156115d3576000828601525b509290920192915050565b60006001600160fb1b038411156115f457600080fd5b8360051b8086843760609390931b6001600160601b031916919092019081526014019392505050565b8183823760009101908152919050565b600061163982856115a3565b9283525050602001919050565b600061165b61165583866115a3565b846115a3565b949350505050565b60e083901b6001600160e01b0319168152600061165b60048301846115a3565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b60208082526026908201527f476f7665726e61626c653a2063616c6c6572206973206e6f742074686520676f6040820152653b32b93737b960d11b606082015260800190565b6020808252602f908201527f7369676e656420627920676f7665726e6f723a204e6f742076616c696420736960408201526e3390333937b69033b7bb32b93737b960891b606082015260800190565b6020808252600d908201526c496e76616c6964206e6f6e636560981b604082015260600190565b60208082526019908201527f4e6f6e6365206d75737420696e6372656d656e74206279203100000000000000604082015260600190565b600080858511156117bc57600080fd5b838611156117c957600080fd5b5050820193919092039150565b600063ffffffff8083168185168083038211156117f5576117f5611867565b01949350505050565b8035602083101561069557600019602084900360031b1b1692915050565b6001600160e01b031981358181169160048510156118445780818660040360031b1b83161692505b505092915050565b600060001982141561186057611860611867565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfe19457468657265756d205369676e6564204d6573736167653a0a333200000000a26469706673582212200c3a5dcebaf8b3ced5ff4e7c961c31488045d4eebd37b889ff94dbb3897bb63d64736f6c63430008050033"; + "0x60806040526000805463ffffffff60a81b1916905534801561002057600080fd5b5060405161186b38038061186b83398101604081905261003f9161009d565b600080546001600160a81b0319166101006001600160a01b03848116820292909217808455604051859492909104909216917f1f323489f404e3bad762215fc05447f9a77bb7f3b630a6f08a2851b999db41f7908290a350506100cd565b6000602082840312156100af57600080fd5b81516001600160a01b03811681146100c657600080fd5b9392505050565b61178f806100dc6000396000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c806384db809f116100ad578063a6e94c9111610071578063a6e94c911461028e578063c7af3352146102a1578063d4066f4c146102b9578063d75a0683146102cc578063f1835db71461030f57600080fd5b806384db809f146102085780638755bcad146102315780638b7e878214610244578063911005e7146102685780639d2b1ed71461027b57600080fd5b80633408e470116100f45780633408e470146101a95780634c830cbd146101b75780635c975abb146101d6578063715018a6146101ed5780637296b5d8146101f557600080fd5b80630c340a241461012657806313cb01f9146101555780631ed13d1b146101815780631eee6bc814610196575b600080fd5b60005461010090046001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b60005461016c90600160a81b900463ffffffff1681565b60405163ffffffff909116815260200161014c565b61019461018f36600461139d565b610322565b005b6101946101a43660046111a7565b610372565b60405146815260200161014c565b6101bf6104c1565b60405165ffffffffffff909116815260200161014c565b60005460ff165b604051901515815260200161014c565b61019461050f565b610194610203366004611401565b61058d565b6101386102163660046112a0565b6003602052600090815260409020546001600160a01b031681565b6101dd61023f36600461139d565b6106f3565b61024f600160f81b81565b6040516001600160f01b0319909116815260200161014c565b610194610276366004611242565b610729565b61019461028936600461133e565b6108b9565b61019461029c36600461120f565b610a6b565b60005461010090046001600160a01b031633146101dd565b6101dd6102c73660046112fc565b610b41565b6102f66102da3660046112a0565b60026020526000908152604090205467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161014c565b6101dd61031d3660046112b9565b610b77565b8151602083012060006103358284610c6c565b6040519091506001600160a01b038216907f391f5edd7209ba797e8055bce97cab2d1a480a2849b0c7fe965c370457166dc490600090a250505050565b6040516bffffffffffffffffffffffff19606086811b821660208401526034830186905284901b166054820152606801604051602081830303815290604052805190602001208160006040518060400160405280601c815260200160008051602061173a833981519152815250905061040c81846040516020016103f79291906114a9565b604051602081830303815290604052836106f3565b6104315760405162461bcd60e51b81526004016104289061157b565b60405180910390fd5b6000868152600360205260409081902080546001600160a01b0319166001600160a01b038a81169182179092559151635c7d1b9b60e11b815260048101899052908716602482015288919063b8fa373690604401600060405180830381600087803b15801561049f57600080fd5b505af11580156104b3573d6000803e3d6000fd5b505050505050505050505050565b60408051600160f81b602082018190524660e01b6001600160e01b03198116602284015283518084036006018152602690930190935260009291610504816116d6565b60d01c935050505090565b60005461010090046001600160a01b0316331461053e5760405162461bcd60e51b815260040161042890611535565b600080546040516101009091046001600160a01b0316907f1f323489f404e3bad762215fc05447f9a77bb7f3b630a6f08a2851b999db41f7908390a360008054610100600160a81b0319169055565b60005463ffffffff808416600160a81b90920416106105be5760405162461bcd60e51b8152600401610428906115ca565b6000546105d990600160a81b900463ffffffff166001611652565b63ffffffff168263ffffffff1611156106045760405162461bcd60e51b8152600401610428906115f1565b604080518082018252601c815260008051602061173a83398151915260208083019190915285518682012092519192916000916106459187918991016114df565b60408051808303601f190181528282528051602091820120908301819052925083916106a19186910160408051601f198184030181529082905261068c92916020016114c2565b604051602081830303815290604052866106f3565b6106bd5760405162461bcd60e51b815260040161042890611535565b6106c681610c90565b50506000805463ffffffff909516600160a81b0263ffffffff60a81b199095169490941790935550505050565b81516020830120600090816107088285610c6c565b60005461010090046001600160a01b03908116911614925050505b92915050565b60005463ffffffff808416600160a81b909204161061075a5760405162461bcd60e51b8152600401610428906115ca565b60005461077590600160a81b900463ffffffff166001611652565b63ffffffff168263ffffffff1611156107a05760405162461bcd60e51b8152600401610428906115f1565b60006040518060400160405280601c815260200160008051602061173a83398151915281525090506000838560405160200161080792919060e09290921b6001600160e01b031916825260601b6bffffffffffffffffffffffff1916600482015260180190565b604051602081830303815290604052805190602001209050610869828260405160200161083691815260200190565b60408051601f198184030181529082905261085492916020016114c2565b604051602081830303815290604052846106f3565b6108855760405162461bcd60e51b815260040161042890611535565b61088e85610c90565b50506000805463ffffffff909316600160a81b0263ffffffff60a81b19909316929092179091555050565b82826040516108c9929190611499565b60405180910390208160006040518060400160405280601c815260200160008051602061173a833981519152815250905061091081846040516020016103f79291906114a9565b61092c5760405162461bcd60e51b81526004016104289061157b565b36600061093c602082898b611628565b9092509050600061094d8284611688565b9050600061095f6020601a8587611628565b610968916116a6565b60d01c9050806109766104c1565b65ffffffffffff16146109cb5760405162461bcd60e51b815260206004820152601860248201527f657865637574696e67206f6e2077726f6e6720636861696e00000000000000006044820152606401610428565b60006003600084815260200190815260200160002060009054906101000a90046001600160a01b031690506000819050806001600160a01b031663e248cff2858e8e6040518463ffffffff1660e01b8152600401610a2b939291906114ff565b600060405180830381600087803b158015610a4557600080fd5b505af1158015610a59573d6000803e3d6000fd5b50505050505050505050505050505050565b60005461010090046001600160a01b03163314610a9a5760405162461bcd60e51b815260040161042890611535565b60005463ffffffff808316600160a81b9092041610610acb5760405162461bcd60e51b8152600401610428906115ca565b600054610ae690600160a81b900463ffffffff166001611652565b63ffffffff168163ffffffff161115610b115760405162461bcd60e51b8152600401610428906115f1565b610b1a82610c90565b6000805463ffffffff909216600160a81b0263ffffffff60a81b1990921691909117905550565b6000336001600160a01b03168383604051610b5d929190611499565b6040519081900390206001600160a01b0316149392505050565b6000806040518060400160405280601c815260200160008051602061173a833981519152815250905060008187604051602001610bb59291906114a9565b604051602081830303815290604052805190602001209050610be56000546001600160a01b036101009091041690565b6001600160a01b031660018288888860405160008152602001604052604051610c2a949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610c4c573d6000803e3d6000fd5b505050602060405103516001600160a01b03161492505050949350505050565b6000806000610c7b8585610d5e565b91509150610c8881610dce565b509392505050565b6001600160a01b038116610cf85760405162461bcd60e51b815260206004820152602960248201527f476f7665726e61626c653a206e6577206f776e657220697320746865207a65726044820152686f206164647265737360b81b6064820152608401610428565b600080546040516001600160a01b038085169361010090930416917f1f323489f404e3bad762215fc05447f9a77bb7f3b630a6f08a2851b999db41f791a3600080546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600080825160411415610d955760208301516040840151606085015160001a610d8987828585610f8c565b94509450505050610dc7565b825160401415610dbf5760208301516040840151610db4868383611079565b935093505050610dc7565b506000905060025b9250929050565b6000816004811115610de257610de261170d565b1415610deb5750565b6001816004811115610dff57610dff61170d565b1415610e4d5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610428565b6002816004811115610e6157610e6161170d565b1415610eaf5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610428565b6003816004811115610ec357610ec361170d565b1415610f1c5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610428565b6004816004811115610f3057610f3061170d565b1415610f895760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610428565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610fc35750600090506003611070565b8460ff16601b14158015610fdb57508460ff16601c14155b15610fec5750600090506004611070565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611040573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661106957600060019250925050611070565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b0161109a87828885610f8c565b935093505050935093915050565b80356001600160a01b03811681146110bf57600080fd5b919050565b60008083601f8401126110d657600080fd5b50813567ffffffffffffffff8111156110ee57600080fd5b602083019150836020828501011115610dc757600080fd5b600082601f83011261111757600080fd5b813567ffffffffffffffff8082111561113257611132611723565b604051601f8301601f19908116603f0116810190828211818310171561115a5761115a611723565b8160405283815286602085880101111561117357600080fd5b836020870160208301376000602085830101528094505050505092915050565b803563ffffffff811681146110bf57600080fd5b600080600080608085870312156111bd57600080fd5b6111c6856110a8565b9350602085013592506111db604086016110a8565b9150606085013567ffffffffffffffff8111156111f757600080fd5b61120387828801611106565b91505092959194509250565b6000806040838503121561122257600080fd5b61122b836110a8565b915061123960208401611193565b90509250929050565b60008060006060848603121561125757600080fd5b611260846110a8565b925061126e60208501611193565b9150604084013567ffffffffffffffff81111561128a57600080fd5b61129686828701611106565b9150509250925092565b6000602082840312156112b257600080fd5b5035919050565b600080600080608085870312156112cf57600080fd5b84359350602085013560ff811681146112e757600080fd5b93969395505050506040820135916060013590565b6000806020838503121561130f57600080fd5b823567ffffffffffffffff81111561132657600080fd5b611332858286016110c4565b90969095509350505050565b60008060006040848603121561135357600080fd5b833567ffffffffffffffff8082111561136b57600080fd5b611377878388016110c4565b9095509350602086013591508082111561139057600080fd5b5061129686828701611106565b600080604083850312156113b057600080fd5b823567ffffffffffffffff808211156113c857600080fd5b6113d486838701611106565b935060208501359150808211156113ea57600080fd5b506113f785828601611106565b9150509250929050565b60008060006060848603121561141657600080fd5b833567ffffffffffffffff8082111561142e57600080fd5b61143a87838801611106565b945061144860208701611193565b9350604086013591508082111561139057600080fd5b6000815160005b8181101561147f5760208185018101518683015201611465565b8181111561148e576000828601525b509290920192915050565b8183823760009101908152919050565b60006114b5828561145e565b9283525050602001919050565b60006114d76114d1838661145e565b8461145e565b949350505050565b60e083901b6001600160e01b031916815260006114d7600483018461145e565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b60208082526026908201527f476f7665726e61626c653a2063616c6c6572206973206e6f742074686520676f6040820152653b32b93737b960d11b606082015260800190565b6020808252602f908201527f7369676e656420627920676f7665726e6f723a204e6f742076616c696420736960408201526e3390333937b69033b7bb32b93737b960891b606082015260800190565b6020808252600d908201526c496e76616c6964206e6f6e636560981b604082015260600190565b60208082526019908201527f4e6f6e6365206d75737420696e6372656d656e74206279203100000000000000604082015260600190565b6000808585111561163857600080fd5b8386111561164557600080fd5b5050820193919092039150565b600063ffffffff80831681851680830382111561167f57634e487b7160e01b600052601160045260246000fd5b01949350505050565b8035602083101561072357600019602084900360031b1b1692915050565b6001600160d01b031981358181169160068510156116ce5780818660060360031b1b83161692505b505092915050565b805160208201516001600160d01b031980821692919060068310156117055780818460060360031b1b83161693505b505050919050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fdfe19457468657265756d205369676e6564204d6573736167653a0a333200000000a2646970667358221220be990bad99b9341f8ed86cdf81e780863c8e9b6da5bcfe92f3a30f3dfb6b1d8b64736f6c63430008050033"; export class SignatureBridge__factory extends ContractFactory { constructor( diff --git a/packages/contracts/src/factories/VAnchorEncodeInputs__factory.ts b/packages/contracts/src/factories/VAnchorEncodeInputs__factory.ts index ef2b8fcc1..aa3fb6c9d 100644 --- a/packages/contracts/src/factories/VAnchorEncodeInputs__factory.ts +++ b/packages/contracts/src/factories/VAnchorEncodeInputs__factory.ts @@ -10,6 +10,19 @@ import type { } from "../VAnchorEncodeInputs"; const _abi = [ + { + inputs: [], + name: "EVM_CHAIN_ID_TYPE", + outputs: [ + { + internalType: "bytes2", + name: "", + type: "bytes2", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [ { @@ -145,10 +158,23 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "getChainIdType", + outputs: [ + { + internalType: "uint48", + name: "", + type: "uint48", + }, + ], + stateMutability: "view", + type: "function", + }, ]; const _bytecode = - "0x61237561003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361061004b5760003560e01c80633408e47014610050578063416e8491146100635780637dc45e3f14610084575b600080fd5b6040514681526020015b60405180910390f35b61007661007136600461207a565b610097565b60405161005a9291906121d2565b61007661009236600461207a565b6108b4565b6060804660006100a88560016122e0565b60ff1667ffffffffffffffff8111156100c3576100c3612329565b6040519080825280602002602001820160405280156100ec578160200160208202803683370190505b50905060608560ff166001141561022957610105611b8c565b6000886020015180602001905181019061011f9190611e26565b905080600060200201518460008151811061013c5761013c612313565b602090810291909101015280600160200201518460018151811061016257610162612313565b60209081029190910181019190915260808a0151835260a08a0151908301526040890151805160009061019757610197612313565b602090810291909101015182600260200201526040890151805160019081106101c2576101c2612313565b6020908102919091018101516060808501919091528a0180515160808501525181015160a084015260c08301869052815160e0840152818101516101008401526040516102119184910161219d565b604051602081830303815290604052925050506108a9565b8560ff16600214156103755761023d611bab565b600088602001518060200190518101906102579190611e83565b905080600060200201518460008151811061027457610274612313565b602090810291909101015280600160200201518460018151811061029a5761029a612313565b60209081029190910101528060026020020151846002815181106102c0576102c0612313565b60209081029190910181019190915260808a0151835260a08a015190830152604089015180516000906102f5576102f5612313565b6020908102919091010151826002602002015260408901518051600190811061032057610320612313565b6020908102919091018101516060808501919091528a0180515160808501525181015160a084015260c08301869052815160e084015281015161010083015260408101518260095b6020020152506108a99050565b8560ff16600314156104e957610389611bca565b600088602001518060200190518101906103a39190611f09565b90508060006020020151846000815181106103c0576103c0612313565b60209081029190910101528060016020020151846001815181106103e6576103e6612313565b602090810291909101015280600260200201518460028151811061040c5761040c612313565b602090810291909101015280600360200201518460038151811061043257610432612313565b60209081029190910181019190915260808a0151835260a08a0151908301526040890151805160009061046757610467612313565b6020908102919091010151826002602002015260408901518051600190811061049257610492612313565b6020908102919091018101516060808501919091528a810180515160808601525182015160a085015260c08401879052825160e085015290820151610100840152604082015161012084015281015182600a610368565b8560ff1660041415610691576104fd611be9565b600088602001518060200190518101906105179190611f84565b905080600060200201518460008151811061053457610534612313565b602090810291909101015280600160200201518460018151811061055a5761055a612313565b602090810291909101015280600260200201518460028151811061058057610580612313565b60209081029190910101528060036020020151846003815181106105a6576105a6612313565b60209081029190910101528060046020020151846004815181106105cc576105cc612313565b60209081029190910181019190915260808a0151835260a08a0151908301526040890151805160009061060157610601612313565b6020908102919091010151826002602002015260408901518051600190811061062c5761062c612313565b6020908102919091018101516060808501919091528a8101805151608080870191909152905183015160a086015260c08501889052835160e086015291830151610100850152604083015161012085015282015161014084015281015182600b610368565b8560ff166005141561086d576106a5611c08565b600088602001518060200190518101906106bf9190611fff565b90508060006020020151846000815181106106dc576106dc612313565b602090810291909101015280600160200201518460018151811061070257610702612313565b602090810291909101015280600260200201518460028151811061072857610728612313565b602090810291909101015280600360200201518460038151811061074e5761074e612313565b602090810291909101015280600460200201518460048151811061077457610774612313565b602090810291909101015280600560200201518460058151811061079a5761079a612313565b60209081029190910181019190915260808a0151835260a08a015190830152604089015180516000906107cf576107cf612313565b602090810291909101015182600260200201526040890151805160019081106107fa576107fa612313565b6020908102919091018101516060808501919091528a8101805151608080870191909152905183015160a08087019190915260c08601899052845160e08701529284015161010086015260408401516101208601529083015161014085015282015161016084015281015182600c610368565b60405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420656467657360981b604482015260640160405180910390fd5b969095509350505050565b6060804660006108c58560016122e0565b60ff1667ffffffffffffffff8111156108e0576108e0612329565b604051908082528060200260200182016040528015610909578160200160208202803683370190505b50905060608560ff1660011415610c6a57610922611c27565b6000886020015180602001905181019061093c9190611e26565b905080600060200201518460008151811061095957610959612313565b602090810291909101015280600160200201518460018151811061097f5761097f612313565b60209081029190910181019190915260808a0151835260a08a015190830152604089015180516000906109b4576109b4612313565b602090810291909101015182600260200201526040890151805160019081106109df576109df612313565b60209081029190910101516060830152604089015180516002908110610a0757610a07612313565b60209081029190910101516080830152604089015180516003908110610a2f57610a2f612313565b602090810291909101015160a0830152604089015180516004908110610a5757610a57612313565b602090810291909101015160c0830152604089015180516005908110610a7f57610a7f612313565b602090810291909101015160e0830152604089015180516006908110610aa757610aa7612313565b6020908102919091010151610100830152604089015180516007908110610ad057610ad0612313565b6020908102919091010151610120830152604089015180516008908110610af957610af9612313565b6020908102919091010151610140830152604089015180516009908110610b2257610b22612313565b602090810291909101015161016083015260408901518051600a908110610b4b57610b4b612313565b602090810291909101015161018083015260408901518051600b908110610b7457610b74612313565b60209081029190910101516101a083015260408901518051600c908110610b9d57610b9d612313565b60209081029190910101516101c083015260408901518051600d908110610bc657610bc6612313565b60209081029190910101516101e083015260408901518051600e908110610bef57610bef612313565b602090810291909101015161020083015260408901518051600f908110610c1857610c18612313565b60209081029190910181015161022084015260608a0180515161024085015251810151610260840152610280830186905281516102a0840152818101516102c084015260405161021191849101612168565b8560ff1660021415610fe957610c7e611c46565b60008860200151806020019051810190610c989190611e83565b9050806000602002015184600081518110610cb557610cb5612313565b6020908102919091010152806001602002015184600181518110610cdb57610cdb612313565b6020908102919091010152806002602002015184600281518110610d0157610d01612313565b60209081029190910181019190915260808a0151835260a08a01519083015260408901518051600090610d3657610d36612313565b60209081029190910101518260026020020152604089015180516001908110610d6157610d61612313565b60209081029190910101516060830152604089015180516002908110610d8957610d89612313565b60209081029190910101516080830152604089015180516003908110610db157610db1612313565b602090810291909101015160a0830152604089015180516004908110610dd957610dd9612313565b602090810291909101015160c0830152604089015180516005908110610e0157610e01612313565b602090810291909101015160e0830152604089015180516006908110610e2957610e29612313565b6020908102919091010151610100830152604089015180516007908110610e5257610e52612313565b6020908102919091010151610120830152604089015180516008908110610e7b57610e7b612313565b6020908102919091010151610140830152604089015180516009908110610ea457610ea4612313565b602090810291909101015161016083015260408901518051600a908110610ecd57610ecd612313565b602090810291909101015161018083015260408901518051600b908110610ef657610ef6612313565b60209081029190910101516101a083015260408901518051600c908110610f1f57610f1f612313565b60209081029190910101516101c083015260408901518051600d908110610f4857610f48612313565b60209081029190910101516101e083015260408901518051600e908110610f7157610f71612313565b602090810291909101015161020083015260408901518051600f908110610f9a57610f9a612313565b60209081029190910181015161022084015260608a0180515161024085015251810151610260840152610280830186905281516102a08401528101516102c08301526040810151826017610368565b8560ff166003141561139957610ffd611c65565b600088602001518060200190518101906110179190611f09565b905080600060200201518460008151811061103457611034612313565b602090810291909101015280600160200201518460018151811061105a5761105a612313565b602090810291909101015280600260200201518460028151811061108057611080612313565b60209081029190910101528060036020020151846003815181106110a6576110a6612313565b60209081029190910181019190915260808a0151835260a08a015190830152604089015180516000906110db576110db612313565b6020908102919091010151826002602002015260408901518051600190811061110657611106612313565b6020908102919091010151606083015260408901518051600290811061112e5761112e612313565b6020908102919091010151608083015260408901518051600390811061115657611156612313565b602090810291909101015160a083015260408901518051600490811061117e5761117e612313565b602090810291909101015160c08301526040890151805160059081106111a6576111a6612313565b602090810291909101015160e08301526040890151805160069081106111ce576111ce612313565b60209081029190910101516101008301526040890151805160079081106111f7576111f7612313565b602090810291909101015161012083015260408901518051600890811061122057611220612313565b602090810291909101015161014083015260408901518051600990811061124957611249612313565b602090810291909101015161016083015260408901518051600a90811061127257611272612313565b602090810291909101015161018083015260408901518051600b90811061129b5761129b612313565b60209081029190910101516101a083015260408901518051600c9081106112c4576112c4612313565b60209081029190910101516101c083015260408901518051600d9081106112ed576112ed612313565b60209081029190910101516101e083015260408901518051600e90811061131657611316612313565b602090810291909101015161020083015260408901518051600f90811061133f5761133f612313565b60209081029190910181015161022084015260608a810180515161024086015251820151610260850152610280840187905282516102a0850152908201516102c084015260408201516102e0840152810151826018610368565b8560ff166004141561177a576113ad611c84565b600088602001518060200190518101906113c79190611f84565b90508060006020020151846000815181106113e4576113e4612313565b602090810291909101015280600160200201518460018151811061140a5761140a612313565b602090810291909101015280600260200201518460028151811061143057611430612313565b602090810291909101015280600360200201518460038151811061145657611456612313565b602090810291909101015280600460200201518460048151811061147c5761147c612313565b60209081029190910181019190915260808a0151835260a08a015190830152604089015180516000906114b1576114b1612313565b602090810291909101015182600260200201526040890151805160019081106114dc576114dc612313565b6020908102919091010151606083015260408901518051600290811061150457611504612313565b6020908102919091010151608083015260408901518051600390811061152c5761152c612313565b602090810291909101015160a083015260408901518051600490811061155457611554612313565b602090810291909101015160c083015260408901518051600590811061157c5761157c612313565b602090810291909101015160e08301526040890151805160069081106115a4576115a4612313565b60209081029190910101516101008301526040890151805160079081106115cd576115cd612313565b60209081029190910101516101208301526040890151805160089081106115f6576115f6612313565b602090810291909101015161014083015260408901518051600990811061161f5761161f612313565b602090810291909101015161016083015260408901518051600a90811061164857611648612313565b602090810291909101015161018083015260408901518051600b90811061167157611671612313565b60209081029190910101516101a083015260408901518051600c90811061169a5761169a612313565b60209081029190910101516101c083015260408901518051600d9081106116c3576116c3612313565b60209081029190910101516101e083015260408901518051600e9081106116ec576116ec612313565b602090810291909101015161020083015260408901518051600f90811061171557611715612313565b60209081029190910181015161022084015260608a810180515161024086015251820151610260850152610280840187905282516102a0850152908201516102c084015260408201516102e08401528101516103008301526080810151826019610368565b8560ff166005141561086d5761178e611ca3565b600088602001518060200190518101906117a89190611fff565b90508060006020020151846000815181106117c5576117c5612313565b60209081029190910101528060016020020151846001815181106117eb576117eb612313565b602090810291909101015280600260200201518460028151811061181157611811612313565b602090810291909101015280600360200201518460038151811061183757611837612313565b602090810291909101015280600460200201518460048151811061185d5761185d612313565b602090810291909101015280600560200201518460058151811061188357611883612313565b60209081029190910181019190915260808a0151835260a08a015190830152604089015180516000906118b8576118b8612313565b602090810291909101015182600260200201526040890151805160019081106118e3576118e3612313565b6020908102919091010151606083015260408901518051600290811061190b5761190b612313565b6020908102919091010151608083015260408901518051600390811061193357611933612313565b602090810291909101015160a083015260408901518051600490811061195b5761195b612313565b602090810291909101015160c083015260408901518051600590811061198357611983612313565b602090810291909101015160e08301526040890151805160069081106119ab576119ab612313565b60209081029190910101516101008301526040890151805160079081106119d4576119d4612313565b60209081029190910101516101208301526040890151805160089081106119fd576119fd612313565b6020908102919091010151610140830152604089015180516009908110611a2657611a26612313565b602090810291909101015161016083015260408901518051600a908110611a4f57611a4f612313565b602090810291909101015161018083015260408901518051600b908110611a7857611a78612313565b60209081029190910101516101a083015260408901518051600c908110611aa157611aa1612313565b60209081029190910101516101c083015260408901518051600d908110611aca57611aca612313565b60209081029190910101516101e083015260408901518051600e908110611af357611af3612313565b602090810291909101015161020083015260408901518051600f908110611b1c57611b1c612313565b60209081029190910181015161022084015260608a810180515161024086015251820151610260850152610280840187905282516102a0850152908201516102c084015260408201516102e0840152810151610300830152608081015161032083015260a081015182601a610368565b6040518061012001604052806009906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b604051806101600160405280600b906020820280368337509192915050565b604051806101800160405280600c906020820280368337509192915050565b604051806101a00160405280600d906020820280368337509192915050565b604051806102e001604052806017906020820280368337509192915050565b6040518061030001604052806018906020820280368337509192915050565b6040518061032001604052806019906020820280368337509192915050565b604051806103400160405280601a906020820280368337509192915050565b604051806103600160405280601b906020820280368337509192915050565b600082601f830112611cd357600080fd5b611cdb61228c565b808385604086011115611ced57600080fd5b60005b6002811015611d0f578135845260209384019390910190600101611cf0565b509095945050505050565b600082601f830112611d2b57600080fd5b8135602067ffffffffffffffff821115611d4757611d47612329565b8160051b611d568282016122af565b838152828101908684018388018501891015611d7157600080fd5b600093505b85841015611d94578035835260019390930192918401918401611d76565b50979650505050505050565b600082601f830112611db157600080fd5b813567ffffffffffffffff811115611dcb57611dcb612329565b611dde601f8201601f19166020016122af565b818152846020838601011115611df357600080fd5b816020850160208301376000918101602001919091529392505050565b803560ff81168114611e2157600080fd5b919050565b600060408284031215611e3857600080fd5b82601f830112611e4757600080fd5b611e4f61228c565b808385604086011115611e6157600080fd5b60005b6002811015611d0f578151845260209384019390910190600101611e64565b600060608284031215611e9557600080fd5b82601f830112611ea457600080fd5b6040516060810181811067ffffffffffffffff82111715611ec757611ec7612329565b604052808360608101861015611edc57600080fd5b60005b6003811015611efe578151835260209283019290910190600101611edf565b509195945050505050565b600060808284031215611f1b57600080fd5b82601f830112611f2a57600080fd5b6040516080810181811067ffffffffffffffff82111715611f4d57611f4d612329565b604052808360808101861015611f6257600080fd5b60005b6004811015611efe578151835260209283019290910190600101611f65565b600060a08284031215611f9657600080fd5b82601f830112611fa557600080fd5b60405160a0810181811067ffffffffffffffff82111715611fc857611fc8612329565b604052808360a08101861015611fdd57600080fd5b60005b6005811015611efe578151835260209283019290910190600101611fe0565b600060c0828403121561201157600080fd5b82601f83011261202057600080fd5b60405160c0810181811067ffffffffffffffff8211171561204357612043612329565b604052808360c0810186101561205857600080fd5b60005b6006811015611efe57815183526020928301929091019060010161205b565b6000806040838503121561208d57600080fd5b823567ffffffffffffffff808211156120a557600080fd5b9084019060e082870312156120b957600080fd5b6120c1612263565b8235828111156120d057600080fd5b6120dc88828601611da0565b8252506020830135828111156120f157600080fd5b6120fd88828601611da0565b60208301525060408301358281111561211557600080fd5b61212188828601611d1a565b6040830152506121348760608501611cc2565b606082015260a0830135608082015260c083013560a082015280945050505061215f60208401611e10565b90509250929050565b60008183825b601781101561218d57815183526020928301929091019060010161216e565b5050506102e08201905092915050565b60008183825b60098110156121c25781518352602092830192909101906001016121a3565b5050506101208201905092915050565b604081526000835180604084015260005b8181101561220057602081870181015160608684010152016121e3565b81811115612212576000606083860101525b50601f01601f1916820182810360609081016020808601919091528551918301829052858101926000926080909101905b80841015611d945784518252938201936001939093019290820190612243565b60405160c0810167ffffffffffffffff8111828210171561228657612286612329565b60405290565b6040805190810167ffffffffffffffff8111828210171561228657612286612329565b604051601f8201601f1916810167ffffffffffffffff811182821017156122d8576122d8612329565b604052919050565b600060ff821660ff84168060ff0382111561230b57634e487b7160e01b600052601160045260246000fd5b019392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea2646970667358221220f0365381b6a5e6ff4313349a67190566277496fc3490214e375daaec95db724b64736f6c63430008050033"; + "0x61247961003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100615760003560e01c80633408e47014610066578063416e8491146100795780634c830cbd1461009a5780637dc45e3f146100b95780638b7e8782146100cc575b600080fd5b6040514681526020015b60405180910390f35b61008c610087366004612147565b6100f0565b60405161007092919061229f565b6100a2610920565b60405165ffffffffffff9091168152602001610070565b61008c6100c7366004612147565b61096e565b6100d7600160f81b81565b6040516001600160f01b03199091168152602001610070565b60608060006100fd610920565b65ffffffffffff16905060006101148560016123ad565b60ff1667ffffffffffffffff81111561012f5761012f61242d565b604051908082528060200260200182016040528015610158578160200160208202803683370190505b50905060608560ff166001141561029557610171611c59565b6000886020015180602001905181019061018b9190611ef3565b90508060006020020151846000815181106101a8576101a8612417565b60209081029190910101528060016020020151846001815181106101ce576101ce612417565b60209081029190910181019190915260808a0151835260a08a0151908301526040890151805160009061020357610203612417565b6020908102919091010151826002602002015260408901518051600190811061022e5761022e612417565b6020908102919091018101516060808501919091528a0180515160808501525181015160a084015260c08301869052815160e08401528181015161010084015260405161027d9184910161226a565b60405160208183030381529060405292505050610915565b8560ff16600214156103e1576102a9611c78565b600088602001518060200190518101906102c39190611f50565b90508060006020020151846000815181106102e0576102e0612417565b602090810291909101015280600160200201518460018151811061030657610306612417565b602090810291909101015280600260200201518460028151811061032c5761032c612417565b60209081029190910181019190915260808a0151835260a08a0151908301526040890151805160009061036157610361612417565b6020908102919091010151826002602002015260408901518051600190811061038c5761038c612417565b6020908102919091018101516060808501919091528a0180515160808501525181015160a084015260c08301869052815160e084015281015161010083015260408101518260095b6020020152506109159050565b8560ff1660031415610555576103f5611c97565b6000886020015180602001905181019061040f9190611fd6565b905080600060200201518460008151811061042c5761042c612417565b602090810291909101015280600160200201518460018151811061045257610452612417565b602090810291909101015280600260200201518460028151811061047857610478612417565b602090810291909101015280600360200201518460038151811061049e5761049e612417565b60209081029190910181019190915260808a0151835260a08a015190830152604089015180516000906104d3576104d3612417565b602090810291909101015182600260200201526040890151805160019081106104fe576104fe612417565b6020908102919091018101516060808501919091528a810180515160808601525182015160a085015260c08401879052825160e085015290820151610100840152604082015161012084015281015182600a6103d4565b8560ff16600414156106fd57610569611cb6565b600088602001518060200190518101906105839190612051565b90508060006020020151846000815181106105a0576105a0612417565b60209081029190910101528060016020020151846001815181106105c6576105c6612417565b60209081029190910101528060026020020151846002815181106105ec576105ec612417565b602090810291909101015280600360200201518460038151811061061257610612612417565b602090810291909101015280600460200201518460048151811061063857610638612417565b60209081029190910181019190915260808a0151835260a08a0151908301526040890151805160009061066d5761066d612417565b6020908102919091010151826002602002015260408901518051600190811061069857610698612417565b6020908102919091018101516060808501919091528a8101805151608080870191909152905183015160a086015260c08501889052835160e086015291830151610100850152604083015161012085015282015161014084015281015182600b6103d4565b8560ff16600514156108d957610711611cd5565b6000886020015180602001905181019061072b91906120cc565b905080600060200201518460008151811061074857610748612417565b602090810291909101015280600160200201518460018151811061076e5761076e612417565b602090810291909101015280600260200201518460028151811061079457610794612417565b60209081029190910101528060036020020151846003815181106107ba576107ba612417565b60209081029190910101528060046020020151846004815181106107e0576107e0612417565b602090810291909101015280600560200201518460058151811061080657610806612417565b60209081029190910181019190915260808a0151835260a08a0151908301526040890151805160009061083b5761083b612417565b6020908102919091010151826002602002015260408901518051600190811061086657610866612417565b6020908102919091018101516060808501919091528a8101805151608080870191909152905183015160a08087019190915260c08601899052845160e08701529284015161010086015260408401516101208601529083015161014085015282015161016084015281015182600c6103d4565b60405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420656467657360981b604482015260640160405180910390fd5b969095509350505050565b60408051600160f81b602082018190524660e01b6001600160e01b03198116602284015283518084036006018152602690930190935260009291610963816123e0565b60d01c935050505090565b606080600061097b610920565b65ffffffffffff16905060006109928560016123ad565b60ff1667ffffffffffffffff8111156109ad576109ad61242d565b6040519080825280602002602001820160405280156109d6578160200160208202803683370190505b50905060608560ff1660011415610d37576109ef611cf4565b60008860200151806020019051810190610a099190611ef3565b9050806000602002015184600081518110610a2657610a26612417565b6020908102919091010152806001602002015184600181518110610a4c57610a4c612417565b60209081029190910181019190915260808a0151835260a08a01519083015260408901518051600090610a8157610a81612417565b60209081029190910101518260026020020152604089015180516001908110610aac57610aac612417565b60209081029190910101516060830152604089015180516002908110610ad457610ad4612417565b60209081029190910101516080830152604089015180516003908110610afc57610afc612417565b602090810291909101015160a0830152604089015180516004908110610b2457610b24612417565b602090810291909101015160c0830152604089015180516005908110610b4c57610b4c612417565b602090810291909101015160e0830152604089015180516006908110610b7457610b74612417565b6020908102919091010151610100830152604089015180516007908110610b9d57610b9d612417565b6020908102919091010151610120830152604089015180516008908110610bc657610bc6612417565b6020908102919091010151610140830152604089015180516009908110610bef57610bef612417565b602090810291909101015161016083015260408901518051600a908110610c1857610c18612417565b602090810291909101015161018083015260408901518051600b908110610c4157610c41612417565b60209081029190910101516101a083015260408901518051600c908110610c6a57610c6a612417565b60209081029190910101516101c083015260408901518051600d908110610c9357610c93612417565b60209081029190910101516101e083015260408901518051600e908110610cbc57610cbc612417565b602090810291909101015161020083015260408901518051600f908110610ce557610ce5612417565b60209081029190910181015161022084015260608a0180515161024085015251810151610260840152610280830186905281516102a0840152818101516102c084015260405161027d91849101612235565b8560ff16600214156110b657610d4b611d13565b60008860200151806020019051810190610d659190611f50565b9050806000602002015184600081518110610d8257610d82612417565b6020908102919091010152806001602002015184600181518110610da857610da8612417565b6020908102919091010152806002602002015184600281518110610dce57610dce612417565b60209081029190910181019190915260808a0151835260a08a01519083015260408901518051600090610e0357610e03612417565b60209081029190910101518260026020020152604089015180516001908110610e2e57610e2e612417565b60209081029190910101516060830152604089015180516002908110610e5657610e56612417565b60209081029190910101516080830152604089015180516003908110610e7e57610e7e612417565b602090810291909101015160a0830152604089015180516004908110610ea657610ea6612417565b602090810291909101015160c0830152604089015180516005908110610ece57610ece612417565b602090810291909101015160e0830152604089015180516006908110610ef657610ef6612417565b6020908102919091010151610100830152604089015180516007908110610f1f57610f1f612417565b6020908102919091010151610120830152604089015180516008908110610f4857610f48612417565b6020908102919091010151610140830152604089015180516009908110610f7157610f71612417565b602090810291909101015161016083015260408901518051600a908110610f9a57610f9a612417565b602090810291909101015161018083015260408901518051600b908110610fc357610fc3612417565b60209081029190910101516101a083015260408901518051600c908110610fec57610fec612417565b60209081029190910101516101c083015260408901518051600d90811061101557611015612417565b60209081029190910101516101e083015260408901518051600e90811061103e5761103e612417565b602090810291909101015161020083015260408901518051600f90811061106757611067612417565b60209081029190910181015161022084015260608a0180515161024085015251810151610260840152610280830186905281516102a08401528101516102c083015260408101518260176103d4565b8560ff1660031415611466576110ca611d32565b600088602001518060200190518101906110e49190611fd6565b905080600060200201518460008151811061110157611101612417565b602090810291909101015280600160200201518460018151811061112757611127612417565b602090810291909101015280600260200201518460028151811061114d5761114d612417565b602090810291909101015280600360200201518460038151811061117357611173612417565b60209081029190910181019190915260808a0151835260a08a015190830152604089015180516000906111a8576111a8612417565b602090810291909101015182600260200201526040890151805160019081106111d3576111d3612417565b602090810291909101015160608301526040890151805160029081106111fb576111fb612417565b6020908102919091010151608083015260408901518051600390811061122357611223612417565b602090810291909101015160a083015260408901518051600490811061124b5761124b612417565b602090810291909101015160c083015260408901518051600590811061127357611273612417565b602090810291909101015160e083015260408901518051600690811061129b5761129b612417565b60209081029190910101516101008301526040890151805160079081106112c4576112c4612417565b60209081029190910101516101208301526040890151805160089081106112ed576112ed612417565b602090810291909101015161014083015260408901518051600990811061131657611316612417565b602090810291909101015161016083015260408901518051600a90811061133f5761133f612417565b602090810291909101015161018083015260408901518051600b90811061136857611368612417565b60209081029190910101516101a083015260408901518051600c90811061139157611391612417565b60209081029190910101516101c083015260408901518051600d9081106113ba576113ba612417565b60209081029190910101516101e083015260408901518051600e9081106113e3576113e3612417565b602090810291909101015161020083015260408901518051600f90811061140c5761140c612417565b60209081029190910181015161022084015260608a810180515161024086015251820151610260850152610280840187905282516102a0850152908201516102c084015260408201516102e08401528101518260186103d4565b8560ff16600414156118475761147a611d51565b600088602001518060200190518101906114949190612051565b90508060006020020151846000815181106114b1576114b1612417565b60209081029190910101528060016020020151846001815181106114d7576114d7612417565b60209081029190910101528060026020020151846002815181106114fd576114fd612417565b602090810291909101015280600360200201518460038151811061152357611523612417565b602090810291909101015280600460200201518460048151811061154957611549612417565b60209081029190910181019190915260808a0151835260a08a0151908301526040890151805160009061157e5761157e612417565b602090810291909101015182600260200201526040890151805160019081106115a9576115a9612417565b602090810291909101015160608301526040890151805160029081106115d1576115d1612417565b602090810291909101015160808301526040890151805160039081106115f9576115f9612417565b602090810291909101015160a083015260408901518051600490811061162157611621612417565b602090810291909101015160c083015260408901518051600590811061164957611649612417565b602090810291909101015160e083015260408901518051600690811061167157611671612417565b602090810291909101015161010083015260408901518051600790811061169a5761169a612417565b60209081029190910101516101208301526040890151805160089081106116c3576116c3612417565b60209081029190910101516101408301526040890151805160099081106116ec576116ec612417565b602090810291909101015161016083015260408901518051600a90811061171557611715612417565b602090810291909101015161018083015260408901518051600b90811061173e5761173e612417565b60209081029190910101516101a083015260408901518051600c90811061176757611767612417565b60209081029190910101516101c083015260408901518051600d90811061179057611790612417565b60209081029190910101516101e083015260408901518051600e9081106117b9576117b9612417565b602090810291909101015161020083015260408901518051600f9081106117e2576117e2612417565b60209081029190910181015161022084015260608a810180515161024086015251820151610260850152610280840187905282516102a0850152908201516102c084015260408201516102e084015281015161030083015260808101518260196103d4565b8560ff16600514156108d95761185b611d70565b6000886020015180602001905181019061187591906120cc565b905080600060200201518460008151811061189257611892612417565b60209081029190910101528060016020020151846001815181106118b8576118b8612417565b60209081029190910101528060026020020151846002815181106118de576118de612417565b602090810291909101015280600360200201518460038151811061190457611904612417565b602090810291909101015280600460200201518460048151811061192a5761192a612417565b602090810291909101015280600560200201518460058151811061195057611950612417565b60209081029190910181019190915260808a0151835260a08a0151908301526040890151805160009061198557611985612417565b602090810291909101015182600260200201526040890151805160019081106119b0576119b0612417565b602090810291909101015160608301526040890151805160029081106119d8576119d8612417565b60209081029190910101516080830152604089015180516003908110611a0057611a00612417565b602090810291909101015160a0830152604089015180516004908110611a2857611a28612417565b602090810291909101015160c0830152604089015180516005908110611a5057611a50612417565b602090810291909101015160e0830152604089015180516006908110611a7857611a78612417565b6020908102919091010151610100830152604089015180516007908110611aa157611aa1612417565b6020908102919091010151610120830152604089015180516008908110611aca57611aca612417565b6020908102919091010151610140830152604089015180516009908110611af357611af3612417565b602090810291909101015161016083015260408901518051600a908110611b1c57611b1c612417565b602090810291909101015161018083015260408901518051600b908110611b4557611b45612417565b60209081029190910101516101a083015260408901518051600c908110611b6e57611b6e612417565b60209081029190910101516101c083015260408901518051600d908110611b9757611b97612417565b60209081029190910101516101e083015260408901518051600e908110611bc057611bc0612417565b602090810291909101015161020083015260408901518051600f908110611be957611be9612417565b60209081029190910181015161022084015260608a810180515161024086015251820151610260850152610280840187905282516102a0850152908201516102c084015260408201516102e0840152810151610300830152608081015161032083015260a081015182601a6103d4565b6040518061012001604052806009906020820280368337509192915050565b604051806101400160405280600a906020820280368337509192915050565b604051806101600160405280600b906020820280368337509192915050565b604051806101800160405280600c906020820280368337509192915050565b604051806101a00160405280600d906020820280368337509192915050565b604051806102e001604052806017906020820280368337509192915050565b6040518061030001604052806018906020820280368337509192915050565b6040518061032001604052806019906020820280368337509192915050565b604051806103400160405280601a906020820280368337509192915050565b604051806103600160405280601b906020820280368337509192915050565b600082601f830112611da057600080fd5b611da8612359565b808385604086011115611dba57600080fd5b60005b6002811015611ddc578135845260209384019390910190600101611dbd565b509095945050505050565b600082601f830112611df857600080fd5b8135602067ffffffffffffffff821115611e1457611e1461242d565b8160051b611e2382820161237c565b838152828101908684018388018501891015611e3e57600080fd5b600093505b85841015611e61578035835260019390930192918401918401611e43565b50979650505050505050565b600082601f830112611e7e57600080fd5b813567ffffffffffffffff811115611e9857611e9861242d565b611eab601f8201601f191660200161237c565b818152846020838601011115611ec057600080fd5b816020850160208301376000918101602001919091529392505050565b803560ff81168114611eee57600080fd5b919050565b600060408284031215611f0557600080fd5b82601f830112611f1457600080fd5b611f1c612359565b808385604086011115611f2e57600080fd5b60005b6002811015611ddc578151845260209384019390910190600101611f31565b600060608284031215611f6257600080fd5b82601f830112611f7157600080fd5b6040516060810181811067ffffffffffffffff82111715611f9457611f9461242d565b604052808360608101861015611fa957600080fd5b60005b6003811015611fcb578151835260209283019290910190600101611fac565b509195945050505050565b600060808284031215611fe857600080fd5b82601f830112611ff757600080fd5b6040516080810181811067ffffffffffffffff8211171561201a5761201a61242d565b60405280836080810186101561202f57600080fd5b60005b6004811015611fcb578151835260209283019290910190600101612032565b600060a0828403121561206357600080fd5b82601f83011261207257600080fd5b60405160a0810181811067ffffffffffffffff821117156120955761209561242d565b604052808360a081018610156120aa57600080fd5b60005b6005811015611fcb5781518352602092830192909101906001016120ad565b600060c082840312156120de57600080fd5b82601f8301126120ed57600080fd5b60405160c0810181811067ffffffffffffffff821117156121105761211061242d565b604052808360c0810186101561212557600080fd5b60005b6006811015611fcb578151835260209283019290910190600101612128565b6000806040838503121561215a57600080fd5b823567ffffffffffffffff8082111561217257600080fd5b9084019060e0828703121561218657600080fd5b61218e612330565b82358281111561219d57600080fd5b6121a988828601611e6d565b8252506020830135828111156121be57600080fd5b6121ca88828601611e6d565b6020830152506040830135828111156121e257600080fd5b6121ee88828601611de7565b6040830152506122018760608501611d8f565b606082015260a0830135608082015260c083013560a082015280945050505061222c60208401611edd565b90509250929050565b60008183825b601781101561225a57815183526020928301929091019060010161223b565b5050506102e08201905092915050565b60008183825b600981101561228f578151835260209283019290910190600101612270565b5050506101208201905092915050565b604081526000835180604084015260005b818110156122cd57602081870181015160608684010152016122b0565b818111156122df576000606083860101525b50601f01601f1916820182810360609081016020808601919091528551918301829052858101926000926080909101905b80841015611e615784518252938201936001939093019290820190612310565b60405160c0810167ffffffffffffffff811182821017156123535761235361242d565b60405290565b6040805190810167ffffffffffffffff811182821017156123535761235361242d565b604051601f8201601f1916810167ffffffffffffffff811182821017156123a5576123a561242d565b604052919050565b600060ff821660ff84168060ff038211156123d857634e487b7160e01b600052601160045260246000fd5b019392505050565b805160208201516001600160d01b0319808216929190600683101561240f5780818460060360031b1b83161693505b505050919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea264697066735822122096ba942d8903b0229881358e7cdc1132c6522694c9675431a2bd0106dbf03d8764736f6c63430008050033"; export class VAnchorEncodeInputs__factory extends ContractFactory { constructor( diff --git a/packages/contracts/src/factories/VAnchor__factory.ts b/packages/contracts/src/factories/VAnchor__factory.ts index 33fda4582..867b24008 100644 --- a/packages/contracts/src/factories/VAnchor__factory.ts +++ b/packages/contracts/src/factories/VAnchor__factory.ts @@ -1501,7 +1501,7 @@ const _abi = [ ]; const _bytecode = - "0x610100604052600380546001600160401b0319169055600b805463ffffffff60a01b191690553480156200003257600080fd5b5060405162005a5238038062005a528339810160408190526200005591620008da565b85858585848185848684848383838183818160008263ffffffff1611620000cf5760405162461bcd60e51b815260206004820152602360248201527f5f6c6576656c732073686f756c642062652067726561746572207468616e207a60448201526265726f60e81b60648201526084015b60405180910390fd5b60208263ffffffff1610620001275760405162461bcd60e51b815260206004820152601e60248201527f5f6c6576656c732073686f756c64206265206c657373207468616e20333200006044820152606401620000c6565b60e09190911b6001600160e01b03191660a05260601b6001600160601b03191660805260005b8263ffffffff168163ffffffff1610156200019e576200017363ffffffff821662000274565b63ffffffff8216600090815260016020526040902055806200019581620009a3565b9150506200014d565b50620001bc620001b06001846200097b565b63ffffffff1662000274565b6000805260026020527fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b5550506001600455600580546001600160a01b03199081166001600160a01b039687161790915560f89190911b7fff000000000000000000000000000000000000000000000000000000000000001660c052600b80549091169790931696909617909155505050505060609790971b6001600160601b03191660e05250620009f99950505050505050505050565b600081620002a357507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b8160011415620002d457507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156200030557507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b81600314156200033657507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b81600414156200036757507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b81600514156200039857507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b8160061415620003c957507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b8160071415620003fa57507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b81600814156200042b57507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b81600914156200045c57507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a14156200048d57507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b1415620004be57507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c1415620004ef57507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156200052057507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e14156200055157507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f14156200058257507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b8160101415620005b357507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b8160111415620005e357507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b81601214156200061457507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b81601314156200064557507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b81601414156200067657507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b8160151415620006a757507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b8160161415620006d857507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b81601714156200070957507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b81601814156200073a57507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b81601914156200076b57507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a14156200079c57507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b1415620007cd57507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c1415620007fe57507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d14156200082f57507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e14156200086057507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f14156200089157507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b815260206004820152601360248201527f496e646578206f7574206f6620626f756e6473000000000000000000000000006044820152606401620000c6565b60008060008060008060c08789031215620008f457600080fd5b86516200090181620009e0565b602088015190965063ffffffff811681146200091c57600080fd5b60408801519095506200092f81620009e0565b60608801519094506200094281620009e0565b60808801519093506200095581620009e0565b60a088015190925060ff811681146200096d57600080fd5b809150509295509295509295565b600063ffffffff838116908316818110156200099b576200099b620009ca565b039392505050565b600063ffffffff80831681811415620009c057620009c0620009ca565b6001019392505050565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0381168114620009f657600080fd5b50565b60805160601c60a05160e01c60c05160f81c60e05160601c614f4f62000b0360003960008181610b8301528181610e0101528181610e950152818161167e0152818161171c0152818161195001528181611f3201528181611ff301528181612e1a01528181612eb801528181612f05015281816130ba015261315201526000818161069b01528181610c6301528181610ccd015281816114cd015281816117cb01528181611bc001528181611c4c015281816131f3015281816133520152818161365c01526137860152600081816105cc01528181610d5601528181611d0b0152818161389c015261397c015260008181610ac30152818161394c0152613a150152614f4f6000f3fe6080604052600436106103815760003560e01c80638ea3099e116101d1578063c80916d411610102578063e8295588116100a0578063f5ab0dd61161006f578063f5ab0dd614610b12578063fa73168714610b41578063fc0c546a14610b71578063fc7e9c6f14610ba557600080fd5b8063e829558814610a5d578063ec73295914610a7d578063ed33639f14610ab1578063f178e47c14610ae557600080fd5b8063dbc916b8116100dc578063dbc916b8146109a5578063e4a30116146109e0578063e5285dcc14610a00578063e70ea87c14610a3057600080fd5b8063c80916d414610950578063c9be725014610970578063cd87a3b41461099057600080fd5b80639ff800631161016f578063b7566a6711610149578063b7566a67146108d9578063ba70f757146108f9578063bc063e1a14610705578063c2b40ae41461092357600080fd5b80639ff80063146105ee578063a0d192f514610899578063b2bc6e0f146108b957600080fd5b806392156311116101ab578063921563111461080957806395c87d1a146108395780639bbca3a91461084c5780639fa12d0b1461086c57600080fd5b80638ea3099e146107b65780638f1c56bd146107d657806390eeb02b146107ec57600080fd5b80634c830cbd116102b657806371523c3211610254578063839df94511610223578063839df9451461071d578063840b27911461074d5780638b7e8782146107635780638c0d34d81461079457600080fd5b806371523c321461068957806372c1ad03146106cf57806378abb49b146106ef5780637fe24ffe1461070557600080fd5b80635d2d766c116102905780635d2d766c1461060e578063616e0957146106415780636ad481f3146106615780636d9833e31461066957600080fd5b80634c830cbd1461058e5780634ecf518b146105ba5780634f401241146105ee57600080fd5b80633408e4701161032357806342d90711116102fd57806342d907111461050357806343e7119f1461052357806344347ba91461055b578063460b53e31461056e57600080fd5b80633408e470146104bb578063414a37ba146104ce5780634167bb1e146104f057600080fd5b80631e6276171161035f5780631e6276171461041e5780632063e3d3146104405780632570b7b4146104555780632b7ac3f31461048357600080fd5b80630b27fb9a1461038657806311e4dcb9146103be57806317cc915c146103ee575b600080fd5b34801561039257600080fd5b50600b54600160a01b900463ffffffff165b60405163ffffffff90911681526020015b60405180910390f35b3480156103ca57600080fd5b506103de6103d93660046142f9565b610bca565b60405190151581526020016103b5565b3480156103fa57600080fd5b506103de6104093660046141ad565b600c6020526000908152604090205460ff1681565b34801561042a57600080fd5b50610433610c5f565b6040516103b591906146b5565b61045361044e366004613fb6565b610db5565b005b34801561046157600080fd5b506104756104703660046142f9565b610ef6565b6040519081526020016103b5565b34801561048f57600080fd5b50600b546104a3906001600160a01b031681565b6040516001600160a01b0390911681526020016103b5565b3480156104c757600080fd5b5046610475565b3480156104da57600080fd5b50610475600080516020614efa83398151915281565b6104536104fe3660046144d3565b610fe4565b34801561050f57600080fd5b5061045361051e3660046142f9565b611104565b34801561052f57600080fd5b5061047561053e36600461458f565b600960209081526000928352604080842090915290825290205481565b610453610569366004614563565b611139565b34801561057a57600080fd5b50610453610589366004613fb6565b611667565b34801561059a57600080fd5b506105a36116b7565b60405165ffffffffffff90911681526020016103b5565b3480156105c657600080fd5b506103a47f000000000000000000000000000000000000000000000000000000000000000081565b3480156105fa57600080fd5b50610453610609366004613fb6565b611705565b34801561061a57600080fd5b506103a46106293660046141ad565b600a6020526000908152604090205463ffffffff1681565b34801561064d57600080fd5b506103de61065c36600461408b565b611755565b610453611939565b34801561067557600080fd5b506103de6106843660046141ad565b6119c0565b34801561069557600080fd5b506106bd7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016103b5565b3480156106db57600080fd5b506104536106ea366004613fe2565b611a3b565b3480156106fb57600080fd5b5061047560105481565b34801561071157600080fd5b50610475600160f81b81565b34801561072957600080fd5b506103de6107383660046141ad565b600d6020526000908152604090205460ff1681565b34801561075957600080fd5b50610475600f5481565b34801561076f57600080fd5b5061077b600160f81b81565b6040516001600160f01b031990911681526020016103b5565b3480156107a057600080fd5b506107a9611bbc565b6040516103b591906146ed565b3480156107c257600080fd5b506104756107d13660046142c4565b611d6f565b3480156107e257600080fd5b50610475600e5481565b3480156107f857600080fd5b506003546103a49063ffffffff1681565b34801561081557600080fd5b506103de6108243660046141ad565b60009081526007602052604090205460ff1690565b610453610847366004613f75565b611ed2565b34801561085857600080fd5b50610453610867366004614470565b611f98565b34801561087857600080fd5b5061088c610887366004614017565b612181565b6040516103b5919061466f565b3480156108a557600080fd5b506104536108b4366004613fe2565b612246565b3480156108c557600080fd5b506104536108d436600461431b565b6123b1565b3480156108e557600080fd5b506104536108f43660046143d6565b612416565b34801561090557600080fd5b5060035463ffffffff16600090815260026020526040902054610475565b34801561092f57600080fd5b5061047561093e3660046141ad565b60026020526000908152604090205481565b34801561095c57600080fd5b506005546104a3906001600160a01b031681565b34801561097c57600080fd5b5061045361098b36600461434f565b612430565b34801561099c57600080fd5b506103a4601e81565b3480156109b157600080fd5b506109c56109c03660046141ad565b612443565b604080519384526020840192909252908201526060016103b5565b3480156109ec57600080fd5b506104536109fb3660046142f9565b612476565b348015610a0c57600080fd5b506103de610a1b3660046141ad565b6000908152600c602052604090205460ff1690565b348015610a3c57600080fd5b50610475610a4b3660046141ad565b60066020526000908152604090205481565b348015610a6957600080fd5b50610475610a783660046141ad565b612534565b348015610a8957600080fd5b506104757f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c81565b348015610abd57600080fd5b506104a37f000000000000000000000000000000000000000000000000000000000000000081565b348015610af157600080fd5b50610475610b003660046141ad565b60016020526000908152604090205481565b348015610b1e57600080fd5b50610b32610b2d3660046140bf565b612b74565b6040516103b593929190614754565b348015610b4d57600080fd5b506103de610b5c3660046141ad565b60076020526000908152604090205460ff1681565b348015610b7d57600080fd5b506104a37f000000000000000000000000000000000000000000000000000000000000000081565b348015610bb157600080fd5b506003546103a490640100000000900463ffffffff1681565b600081610bd957506000610c59565b6000838152600a602052604090205463ffffffff16805b600085815260096020908152604080832063ffffffff85168452909152902054841415610c2257600192505050610c59565b63ffffffff8116610c315750601e5b80610c3b81614dd9565b9150508163ffffffff168163ffffffff161415610bf0576000925050505b92915050565b60607f000000000000000000000000000000000000000000000000000000000000000060ff166001600160401b03811115610c9c57610c9c614ece565b604051908082528060200260200182016040528015610cc5578160200160208202803683370190505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610db157610d01816001614b52565b60085410610d515760088181548110610d1c57610d1c614eb8565b906000526020600020906003020160010154828281518110610d4057610d40614eb8565b602002602001018181525050610d9f565b610d807f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612534565b828281518110610d9257610d92614eb8565b6020026020010181815250505b80610da981614df9565b915050610ccb565b5090565b6001600160a01b038216610e6357803414610dcf57600080fd5b604051633d97186b60e11b81523360048201526001600160a01b038381166024830152600060448301523060648301527f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d69034906084016000604051808303818588803b158015610e4657600080fd5b505af1158015610e5a573d6000803e3d6000fd5b50505050505050565b604051633d97186b60e11b81523360048201526001600160a01b038381166024830152604482018390523060648301527f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d6906084015b600060405180830381600087803b158015610eda57600080fd5b505af1158015610eee573d6000803e3d6000fd5b505050505050565b6000600160f81b8210610f3e5760405162461bcd60e51b815260206004820152600b60248201526a496e76616c69642066656560a81b60448201526064015b60405180910390fd5b610f4b600160f81b614e6f565b83138015610f5c5750600160f81b83125b610f9d5760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a5908195e1d08185b5bdd5b9d60721b6044820152606401610f35565b6000610fa98385614cfb565b90506000811215610fda57610fbd81614e6f565b610fd590600080516020614efa833981519152614d3a565b610fdc565b805b949350505050565b610fee8383612bfd565b60008260200151131561102f57601054826020015111156110215760405162461bcd60e51b8152600401610f35906148dd565b61102f818360200151610db5565b6000826020015112156110d95781516001600160a01b03166110935760405162461bcd60e51b815260206004820152601e60248201527f43616e277420776974686472617720746f207a65726f206164647265737300006044820152606401610f35565b600f5482602001516110a490614e6f565b10156110c25760405162461bcd60e51b8152600401610f359061481a565b6110d9818360000151846020015161084790614e6f565b6060820151156110f5576110f582604001518360600151612e02565b6110ff8383612f49565b505050565b6005546001600160a01b0316331461112e5760405162461bcd60e51b8152600401610f3590614927565b600f91909155601055565b6005546001600160a01b031633146111635760405162461bcd60e51b8152600401610f3590614927565b600260045414156111865760405162461bcd60e51b8152600401610f35906148a6565b60026004908155604051639215631160e01b8152908101849052309063921563119060240160206040518083038186803b1580156111c357600080fd5b505afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb919061418b565b156114c65760008381526007602052604090205460ff166112845760405162461bcd60e51b815260206004820152603760248201527f436861696e206d75737420626520696e74656772617465642066726f6d20746860448201527f6520627269646765206265666f726520757064617465730000000000000000006064820152608401610f35565b6000838152600660205260409020546008805483929081106112a8576112a8614eb8565b906000526020600020906003020160020154106113075760405162461bcd60e51b815260206004820152601e60248201527f4e6577206c65616620696e646578206d757374206265206772656174657200006044820152606401610f35565b60008381526006602052604090205460088054909190811061132b5761132b614eb8565b9060005260206000209060030201600201546201000061134b9190614b52565b81106113a95760405162461bcd60e51b815260206004820152602760248201527f4e6577206c65616620696e646578206d7573742077697468696e20325e3136206044820152667570646174657360c81b6064820152608401610f35565b60008381526006602090815260409182902054825160608101845286815291820185905291810183905260088054839081106113e7576113e7614eb8565b60009182526020808320845160039093020191825583810151600180840191909155604094850151600290930192909255878352600a9052918120549091601e9161143a9163ffffffff90911690614b6a565b6114449190614e4c565b6000868152600a60209081526040808320805463ffffffff191663ffffffff86169081179091556009835281842090845282529182902087905581518881529081018690529081018690529091507f675e61f04bcf314a9c310a93f2346f417a03d704c1caf9c6af8a65ad8addfa3f9060600160405180910390a1505061165d565b60085460ff7f0000000000000000000000000000000000000000000000000000000000000000161161153a5760405162461bcd60e51b815260206004820152601a60248201527f5468697320416e63686f722069732061742063617061636974790000000000006044820152606401610f35565b6000838152600760209081526040808320805460ff19166001908117909155600880548351606080820186528a82528187018a81528287018a815295840185559388528151600384027ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee381019190915593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee485015593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee590930192909255888652600685528386208190556009855283862086805285528386208890558351898152948501879052928401879052919391927fcf4749969bace1552af6a97fe7e4affedf68875511f9746c6332eb40647b3054910160405180910390a15050505b5050600160045550565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca6938890610ec09033908690869060040161464b565b60408051600160f81b602082018190524660e01b6001600160e01b031981166022840152835180840360060181526026909301909352600092916116fa81614d76565b60d01c935050505090565b60405163130e405b60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063261c80b690610ec09033908690869060040161464b565b600061177a8260008151811061176d5761176d614eb8565b60200260200101516119c0565b6117c65760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f742066696e6420796f7572206d65726b6c6520726f6f74000000006044820152606401610f35565b6117f17f00000000000000000000000000000000000000000000000000000000000000006001614b92565b60ff168251146118435760405162461bcd60e51b815260206004820152601b60248201527f496e636f727265637420726f6f74206172726179206c656e67746800000000006044820152606401610f35565b60005b6008548110156119305760006008828154811061186557611865614eb8565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505090506118d18160000151858460016118b49190614b52565b815181106118c4576118c4614eb8565b6020026020010151610bca565b61191d5760405162461bcd60e51b815260206004820152601760248201527f4e65696768626f7220726f6f74206e6f7420666f756e640000000000000000006044820152606401610f35565b508061192881614df9565b915050611846565b50600192915050565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca6938890349061198c903390600090819060040161464b565b6000604051808303818588803b1580156119a557600080fd5b505af11580156119b9573d6000803e3d6000fd5b5050505050565b6000816119cf57506000919050565b60035463ffffffff16805b63ffffffff8116600090815260026020526040902054841415611a01575060019392505050565b63ffffffff8116611a105750601e5b80611a1a81614dd9565b9150508163ffffffff168163ffffffff1614156119da575060009392505050565b6005546001600160a01b03163314611a655760405162461bcd60e51b8152600401610f3590614927565b6001600160a01b038216611ab15760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610f35565b600b5463ffffffff808316600160a01b9092041610611b025760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610f35565b600b54611b1d90600160a01b900463ffffffff166001614b6a565b63ffffffff168163ffffffff161115611b745760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610f35565b600580546001600160a01b039093166001600160a01b031990931692909217909155600b805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b60607f000000000000000000000000000000000000000000000000000000000000000060ff166001600160401b03811115611bf957611bf9614ece565b604051908082528060200260200182016040528015611c4457816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181611c175790505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610db157611c80816001614b52565b60085410611cf45760088181548110611c9b57611c9b614eb8565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050828281518110611ce457611ce4614eb8565b6020026020010181905250611d5d565b604051806060016040528060008152602001611d357f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612534565b81526020016000815250828281518110611d5157611d51614eb8565b60200260200101819052505b80611d6781614df9565b915050611c4a565b6000600080516020614efa8339815191528310611dce5760405162461bcd60e51b815260206004820181905260248201527f5f6c6566742073686f756c6420626520696e7369646520746865206669656c646044820152606401610f35565b600080516020614efa8339815191528210611e355760405162461bcd60e51b815260206004820152602160248201527f5f72696768742073686f756c6420626520696e7369646520746865206669656c6044820152601960fa1b6064820152608401610f35565b6040805180820182528481526020810184905290516314d2f97b60e11b8152849184916001600160a01b038816916329a5f2f691611e769190600401614746565b60206040518083038186803b158015611e8e57600080fd5b505afa158015611ea2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec6919061454a565b925050505b9392505050565b60026004541415611ef55760405162461bcd60e51b8152600401610f35906148a6565b6002600455611f0430826130a2565b604051632404142f60e11b81526001600160a01b0384811660048301526024820183905283811660448301527f00000000000000000000000000000000000000000000000000000000000000001690634808285e90606401600060405180830381600087803b158015611f7657600080fd5b505af1158015611f8a573d6000803e3d6000fd5b505060016004555050505050565b60026004541415611fbb5760405162461bcd60e51b8152600401610f35906148a6565b6002600455611fca8282612bfd565b6000816020015113156120a45760208101516040516323b872dd60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916323b872dd9161202b91339130919060040161464b565b602060405180830381600087803b15801561204557600080fd5b505af1158015612059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207d919061418b565b50601054816020015111156120a45760405162461bcd60e51b8152600401610f35906148dd565b6000816020015112156121525780516001600160a01b03166121085760405162461bcd60e51b815260206004820152601e60248201527f43616e277420776974686472617720746f207a65726f206164647265737300006044820152606401610f35565b600f54816020015161211990614e6f565b10156121375760405162461bcd60e51b8152600401610f359061481a565b6121528160000151826020015161214d90614e6f565b6130a2565b60608101511561216e5761216e81604001518260600151612e02565b6121788282612f49565b50506001600455565b6060816001600160401b0381111561219b5761219b614ece565b6040519080825280602002602001820160405280156121c4578160200160208202803683370190505b50905060005b8281101561223f576122038484838181106121e7576121e7614eb8565b905060200201356000908152600c602052604090205460ff1690565b1561222d57600182828151811061221c5761221c614eb8565b911515602092830291909101909101525b8061223781614df9565b9150506121ca565b5092915050565b6005546001600160a01b031633146122705760405162461bcd60e51b8152600401610f3590614927565b6001600160a01b0382166122bc5760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610f35565b600b5463ffffffff808316600160a01b909204161061230d5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610f35565b600b5461232890600160a01b900463ffffffff166001614b6a565b63ffffffff168163ffffffff16111561237f5760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610f35565b600b805463ffffffff909216600160a01b026001600160c01b03199092166001600160a01b0390931692909217179055565b80516001600160a01b0316331461240a5760405162461bcd60e51b815260206004820152601c60248201527f6f6e6c79206f776e65722063616e2062652072656769737465726564000000006044820152606401610f35565b61241381613179565b50565b61241f846123b1565b61242a838383610fe4565b50505050565b612439836123b1565b6110ff8282611f98565b6008818154811061245357600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b600054610100900460ff168061248f575060005460ff16155b6124f25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610f35565b600054610100900460ff16158015612514576000805461ffff19166101011790555b600f839055601082905580156110ff576000805461ff0019169055505050565b60008161256257507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b816001141561259257507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156125c257507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b81600314156125f257507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b816004141561262257507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b816005141561265257507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b816006141561268257507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b81600714156126b257507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b81600814156126e257507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b816009141561271257507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a141561274257507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b141561277257507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c14156127a257507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156127d257507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e141561280257507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f141561283257507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b816010141561286257507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b816011141561289157507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b81601214156128c157507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b81601314156128f157507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b816014141561292157507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b816015141561295157507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b816016141561298157507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b81601714156129b157507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b81601814156129e157507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b8160191415612a1157507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a1415612a4157507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b1415612a7157507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c1415612aa157507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d1415612ad157507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e1415612b0157507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f1415612b3157507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b6044820152606401610f35565b919050565b612b7c613bfb565b612b84613c19565b612b8c613bfb565b50506040805180820182528351815260208085015181830152825160808082018552868501518286019081526060808901519084015282528451808601865290870151815260a08701518184015281830152835180850190945260c0860151845260e0909501519083015293909150565b60005b826040015151811015612c9b57612c4383604001518281518110612c2657612c26614eb8565b60200260200101516000908152600c602052604090205460ff1690565b15612c895760405162461bcd60e51b8152602060048201526016602482015275125b9c1d5d081a5cc8185b1c9958591e481cdc195b9d60521b6044820152606401610f35565b80612c9381614df9565b915050612c00565b50600080516020614efa83398151915281604051602001612cbc919061495e565b6040516020818303038152906040528051906020012060001c612cdf9190614e38565b60a083015114612d315760405162461bcd60e51b815260206004820152601c60248201527f496e636f72726563742065787465726e616c20646174612068617368000000006044820152606401610f35565b612d4381602001518260600151610ef6565b826080015114612d8d5760405162461bcd60e51b8152602060048201526015602482015274125b9d985b1a59081c1d589b1a58c8185b5bdd5b9d605a1b6044820152606401610f35565b612d96826131c5565b60005b8260400151518110156110ff576001600c600085604001518481518110612dc257612dc2614eb8565b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080612dfa90614df9565b915050612d99565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015612e6457600080fd5b505afa158015612e78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9c919061454a565b905081156110ff57818110612edf576110ff6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016848461347f565b6040516340c10f1960e01b81526001600160a01b038481166004830152602482018490527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b158015610e4657600080fd5b60608201518051602090910151612f6091906134d1565b506060820151516003547ff3843eddcfcac65d12d9f26261dab50671fdbf5dc44441816c8bbdace2411afd9190612fa790600290640100000000900463ffffffff16614d51565b8360800151604051612fbb939291906147d9565b60405180910390a160608201517ff3843eddcfcac65d12d9f26261dab50671fdbf5dc44441816c8bbdace2411afd906001602002015160035461300e90600190640100000000900463ffffffff16614d51565b8360a00151604051613022939291906147d9565b60405180910390a160005b8260400151518110156110ff577f5e58f77bbf94b46d8d896e29753e4458c6e59b48581e20ed58c9558e96f297ce8360400151828151811061307157613071614eb8565b602002602001015160405161308891815260200190565b60405180910390a18061309a81614df9565b91505061302d565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561310457600080fd5b505afa158015613118573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061313c919061454a565b9050818110612edf576110ff6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016848461347f565b80600001516001600160a01b03167f2c1ca5c14df2aba59d26842c5ff53f6817052ef34f6f7537f8b4c9e3805a5e5082602001516040516131ba9190614807565b60405180910390a250565b806040015151600214156133245760008073__$c855d983235a063579a323068f4c8734f9$__63416e8491847f00000000000000000000000000000000000000000000000000000000000000006040518363ffffffff1660e01b815260040161322f9291906149cb565b60006040518083038186803b15801561324757600080fd5b505af415801561325b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261328391908101906141c6565b9150915061329081611755565b6132cc5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610f35565b82516132d890836135ff565b6110ff5760405162461bcd60e51b815260206004820152601960248201527f496e76616c6964207472616e73616374696f6e2070726f6f66000000000000006044820152606401610f35565b806040015151601014156134375760008073__$c855d983235a063579a323068f4c8734f9$__637dc45e3f847f00000000000000000000000000000000000000000000000000000000000000006040518363ffffffff1660e01b815260040161338e9291906149cb565b60006040518083038186803b1580156133a657600080fd5b505af41580156133ba573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526133e291908101906141c6565b915091506133ef81611755565b61342b5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610f35565b82516132d89083613729565b60405162461bcd60e51b815260206004820152601760248201527f756e737570706f7274656420696e70757420636f756e740000000000000000006044820152606401610f35565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526110ff9084906137b1565b6000828152600d602052604081205460ff16156135005760405162461bcd60e51b8152600401610f3590614865565b6000828152600d602052604090205460ff161561352f5760405162461bcd60e51b8152600401610f3590614865565b600061353b8484613883565b6000858152600d602090815260408083208054600160ff19918216811790925588855293829020805490941617909255815163ffffffff84168152429181019190915291925085917fe77f587aa74084fff834b53ccbab07695ee4594b9c9d5bfd8a7dd80c556124b5910160405180910390a2827fe77f587aa74084fff834b53ccbab07695ee4594b9c9d5bfd8a7dd80c556124b56135db836001614b6a565b6040805163ffffffff90921682524260208301520160405180910390a29392505050565b60008083806020019051810190613616919061412a565b9050600080600061362684612b74565b600b54604051638041ca5360e01b815293965091945092506001600160a01b031690638041ca5390613687908690869086908c907f00000000000000000000000000000000000000000000000000000000000000009060019060040161477d565b60206040518083038186803b15801561369f57600080fd5b505afa1580156136b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d7919061418b565b94508461371f5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b6044820152606401610f35565b5050505092915050565b60008083806020019051810190613740919061412a565b9050600080600061375084612b74565b600b54604051638041ca5360e01b815293965091945092506001600160a01b031690638041ca5390613687908690869086908c907f00000000000000000000000000000000000000000000000000000000000000009060009060040161477d565b6000613806826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613af09092919063ffffffff16565b8051909150156110ff5780806020019051810190613824919061418b565b6110ff5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610f35565b600354600090640100000000900463ffffffff166138c27f00000000000000000000000000000000000000000000000000000000000000006002614c1f565b63ffffffff168163ffffffff1614156139365760405162461bcd60e51b815260206004820152603060248201527f4d65726b6c6520747265652069732066756c6c2e204e6f206d6f7265206c656160448201526f1d995cc818d85b88189948185919195960821b6064820152608401610f35565b6000613943600283614bb7565b905060006139727f00000000000000000000000000000000000000000000000000000000000000008787611d6f565b905060008060015b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff161015613a5c576139b9600286614e4c565b63ffffffff166139f4578392506139d58163ffffffff16612534565b63ffffffff821660009081526001602052604090208590559150613a10565b63ffffffff811660009081526001602052604090205492508391505b613a3b7f00000000000000000000000000000000000000000000000000000000000000008484611d6f565b9350613a48600286614bb7565b945080613a5481614e14565b91505061397a565b50600354600090601e90613a779063ffffffff166001614b6a565b613a819190614e4c565b6003805463ffffffff191663ffffffff83169081179091556000908152600260208190526040909120869055909150613abb908790614b6a565b6003805463ffffffff929092166401000000000267ffffffff0000000019909216919091179055509394505050505092915050565b6060610fdc848460008585843b613b495760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610f35565b600080866001600160a01b03168587604051613b65919061462f565b60006040518083038185875af1925050503d8060008114613ba2576040519150601f19603f3d011682016040523d82523d6000602084013e613ba7565b606091505b5091509150613bb7828286613bc2565b979650505050505050565b60608315613bd1575081611ecb565b825115613be15782518084602001fd5b8160405162461bcd60e51b8152600401610f359190614807565b60405180604001604052806002906020820280368337509192915050565b60405180604001604052806002905b613c30613bfb565b815260200190600190039081613c285790505090565b8035612b6f81614ee4565b600082601f830112613c6257600080fd5b604051604081018181106001600160401b0382111715613c8457613c84614ece565b8060405250808385604086011115613c9b57600080fd5b60005b6002811015613cbd578135835260209283019290910190600101613c9e565b509195945050505050565b600082601f830112613cd957600080fd5b81356020613cee613ce983614b08565b614ad8565b80838252828201915082860187848660051b8901011115613d0e57600080fd5b60005b85811015613d2d57813584529284019290840190600101613d11565b5090979650505050505050565b600082601f830112613d4b57600080fd5b8135613d59613ce982614b2b565b818152846020838601011115613d6e57600080fd5b816020850160208301376000918101602001919091529392505050565b600060408284031215613d9d57600080fd5b604051604081016001600160401b038282108183111715613dc057613dc0614ece565b8160405282935084359150613dd482614ee4565b90825260208401359080821115613dea57600080fd5b50613df785828601613d3a565b6020830152505092915050565b600060c08284031215613e1657600080fd5b613e1e614a8d565b9050613e2982613c46565b815260208201356020820152613e4160408301613c46565b60408201526060820135606082015260808201356001600160401b0380821115613e6a57600080fd5b613e7685838601613d3a565b608084015260a0840135915080821115613e8f57600080fd5b50613e9c84828501613d3a565b60a08301525092915050565b600060e08284031215613eba57600080fd5b613ec2614a8d565b905081356001600160401b0380821115613edb57600080fd5b613ee785838601613d3a565b83526020840135915080821115613efd57600080fd5b613f0985838601613d3a565b60208401526040840135915080821115613f2257600080fd5b50613f2f84828501613cc8565b604083015250613f428360608401613c51565b606082015260a0820135608082015260c082013560a082015292915050565b803563ffffffff81168114612b6f57600080fd5b600080600060608486031215613f8a57600080fd5b8335613f9581614ee4565b92506020840135613fa581614ee4565b929592945050506040919091013590565b60008060408385031215613fc957600080fd5b8235613fd481614ee4565b946020939093013593505050565b60008060408385031215613ff557600080fd5b823561400081614ee4565b915061400e60208401613f61565b90509250929050565b6000806020838503121561402a57600080fd5b82356001600160401b038082111561404157600080fd5b818501915085601f83011261405557600080fd5b81358181111561406457600080fd5b8660208260051b850101111561407957600080fd5b60209290920196919550909350505050565b60006020828403121561409d57600080fd5b81356001600160401b038111156140b357600080fd5b610fdc84828501613cc8565b60006101008083850312156140d357600080fd5b83601f8401126140e257600080fd5b6140ea614ab5565b80848684870111156140fb57600080fd5b600093505b600884101561412057803583526001939093019260209283019201614100565b5095945050505050565b600061010080838503121561413e57600080fd5b83601f84011261414d57600080fd5b614155614ab5565b808486848701111561416657600080fd5b600093505b60088410156141205780518352600193909301926020928301920161416b565b60006020828403121561419d57600080fd5b81518015158114610fda57600080fd5b6000602082840312156141bf57600080fd5b5035919050565b600080604083850312156141d957600080fd5b82516001600160401b03808211156141f057600080fd5b818501915085601f83011261420457600080fd5b81516020614214613ce983614b2b565b828152888284870101111561422857600080fd5b61423783838301848801614dad565b8782015190965093508284111561424d57600080fd5b838701935087601f85011261426157600080fd5b83519250614271613ce984614b08565b8381528181019250848201600585901b860183018a101561429157600080fd5b600095505b848610156142b4578051845260019590950194928201928201614296565b5080955050505050509250929050565b6000806000606084860312156142d957600080fd5b83356142e481614ee4565b95602085013595506040909401359392505050565b6000806040838503121561430c57600080fd5b50508035926020909101359150565b60006020828403121561432d57600080fd5b81356001600160401b0381111561434357600080fd5b610fdc84828501613d8b565b60008060006060848603121561436457600080fd5b83356001600160401b038082111561437b57600080fd5b61438787838801613d8b565b9450602086013591508082111561439d57600080fd5b6143a987838801613ea8565b935060408601359150808211156143bf57600080fd5b506143cc86828701613e04565b9150509250925092565b600080600080608085870312156143ec57600080fd5b84356001600160401b038082111561440357600080fd5b61440f88838901613d8b565b9550602087013591508082111561442557600080fd5b61443188838901613ea8565b9450604087013591508082111561444757600080fd5b5061445487828801613e04565b925050606085013561446581614ee4565b939692955090935050565b6000806040838503121561448357600080fd5b82356001600160401b038082111561449a57600080fd5b6144a686838701613ea8565b935060208501359150808211156144bc57600080fd5b506144c985828601613e04565b9150509250929050565b6000806000606084860312156144e857600080fd5b83356001600160401b03808211156144ff57600080fd5b61450b87838801613ea8565b9450602086013591508082111561452157600080fd5b5061452e86828701613e04565b925050604084013561453f81614ee4565b809150509250925092565b60006020828403121561455c57600080fd5b5051919050565b60008060006060848603121561457857600080fd5b505081359360208301359350604090920135919050565b600080604083850312156145a257600080fd5b8235915061400e60208401613f61565b8060005b600281101561242a576145ca8483516145e0565b60409390930192602091909101906001016145b6565b8060005b600281101561242a5781518452602093840193909101906001016145e4565b6000815180845261461b816020860160208601614dad565b601f01601f19169290920160200192915050565b60008251614641818460208701614dad565b9190910192915050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6020808252825182820181905260009190848201906040850190845b818110156146a957835115158352928401929184019160010161468b565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156146a9578351835292840192918401916001016146d1565b602080825282518282018190526000919060409081850190868401855b82811015614739578151805185528681015187860152850151858501526060909301929085019060010161470a565b5091979650505050505050565b60408101610c5982846145e0565b610100810161476382866145e0565b61477060408301856145b2565b610fdc60c08301846145e0565b600061016061478c838a6145e0565b61479960408401896145b2565b6147a660c08401886145e0565b806101008401526147b981840187614603565b60ff95909516610120840152505090151561014090910152949350505050565b83815263ffffffff831660208201526060604082015260006147fe6060830184614603565b95945050505050565b602081526000611ecb6020830184614603565b6020808252602b908201527f616d6f756e74206973206c657373207468616e206d696e696d616c576974686460408201526a1c985dd85b105b5bdd5b9d60aa1b606082015260800190565b60208082526021908201527f54686520636f6d6d69746d656e7420686173206265656e207375626d697474656040820152601960fa1b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252602a908201527f616d6f756e74206973206c6172676572207468616e206d6178696d756d4465706040820152691bdcda5d105b5bdd5b9d60b21b606082015260800190565b60208082526019908201527f73656e646572206973206e6f74207468652068616e646c657200000000000000604082015260600190565b60208152600060018060a01b03808451166020840152602084015160408401528060408501511660608401525060608301516080830152608083015160c060a08401526149ae60e0840182614603565b905060a0840151601f198483030160c08501526147fe8282614603565b604081526000835160e060408401526149e8610120840182614603565b9050602080860151603f1980868503016060870152614a078483614603565b6040890151878203909201608088015281518082529184019450600092508301905b80831015614a495784518252938301936001929092019190830190614a29565b5060608801519350614a5e60a08701856145e0565b608088015160e087015260a088015161010087015260ff8716838701529350614a849050565b50509392505050565b60405160c081016001600160401b0381118282101715614aaf57614aaf614ece565b60405290565b60405161010081016001600160401b0381118282101715614aaf57614aaf614ece565b604051601f8201601f191681016001600160401b0381118282101715614b0057614b00614ece565b604052919050565b60006001600160401b03821115614b2157614b21614ece565b5060051b60200190565b60006001600160401b03821115614b4457614b44614ece565b50601f01601f191660200190565b60008219821115614b6557614b65614e8c565b500190565b600063ffffffff808316818516808303821115614b8957614b89614e8c565b01949350505050565b600060ff821660ff84168060ff03821115614baf57614baf614e8c565b019392505050565b600063ffffffff80841680614bce57614bce614ea2565b92169190910492915050565b600181815b80851115614c17578163ffffffff04821115614bfd57614bfd614e8c565b80851615614c0a57918102915b93841c9390800290614bdf565b509250929050565b600063ffffffff610fdc818516828516600082614c3e57506001610c59565b81614c4b57506000610c59565b8160018114614c615760028114614c6b57614c9c565b6001915050610c59565b60ff841115614c7c57614c7c614e8c565b6001841b915063ffffffff821115614c9657614c96614e8c565b50610c59565b5060208310610133831016604e8410600b8410161715614cd3575081810a63ffffffff811115614cce57614cce614e8c565b610c59565b614cdd8383614bda565b8063ffffffff04821115614cf357614cf3614e8c565b029392505050565b60008083128015600160ff1b850184121615614d1957614d19614e8c565b6001600160ff1b0384018313811615614d3457614d34614e8c565b50500390565b600082821015614d4c57614d4c614e8c565b500390565b600063ffffffff83811690831681811015614d6e57614d6e614e8c565b039392505050565b805160208201516001600160d01b03198082169291906006831015614da55780818460060360031b1b83161693505b505050919050565b60005b83811015614dc8578181015183820152602001614db0565b8381111561242a5750506000910152565b600063ffffffff821680614def57614def614e8c565b6000190192915050565b6000600019821415614e0d57614e0d614e8c565b5060010190565b600063ffffffff80831681811415614e2e57614e2e614e8c565b6001019392505050565b600082614e4757614e47614ea2565b500690565b600063ffffffff80841680614e6357614e63614ea2565b92169190910692915050565b6000600160ff1b821415614e8557614e85614e8c565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461241357600080fdfe30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a26469706673582212204fc8bb8fbe4a6180511c555fb50945c51d46905392782489123980074f5f213364736f6c63430008050033"; + "0x610100604052600380546001600160401b0319169055600b805463ffffffff60a01b191690553480156200003257600080fd5b5060405162005a5238038062005a528339810160408190526200005591620008da565b85858585848185848684848383838183818160008263ffffffff1611620000cf5760405162461bcd60e51b815260206004820152602360248201527f5f6c6576656c732073686f756c642062652067726561746572207468616e207a60448201526265726f60e81b60648201526084015b60405180910390fd5b60208263ffffffff1610620001275760405162461bcd60e51b815260206004820152601e60248201527f5f6c6576656c732073686f756c64206265206c657373207468616e20333200006044820152606401620000c6565b60e09190911b6001600160e01b03191660a05260601b6001600160601b03191660805260005b8263ffffffff168163ffffffff1610156200019e576200017363ffffffff821662000274565b63ffffffff8216600090815260016020526040902055806200019581620009a3565b9150506200014d565b50620001bc620001b06001846200097b565b63ffffffff1662000274565b6000805260026020527fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b5550506001600455600580546001600160a01b03199081166001600160a01b039687161790915560f89190911b7fff000000000000000000000000000000000000000000000000000000000000001660c052600b80549091169790931696909617909155505050505060609790971b6001600160601b03191660e05250620009f99950505050505050505050565b600081620002a357507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b8160011415620002d457507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156200030557507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b81600314156200033657507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b81600414156200036757507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b81600514156200039857507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b8160061415620003c957507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b8160071415620003fa57507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b81600814156200042b57507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b81600914156200045c57507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a14156200048d57507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b1415620004be57507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c1415620004ef57507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156200052057507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e14156200055157507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f14156200058257507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b8160101415620005b357507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b8160111415620005e357507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b81601214156200061457507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b81601314156200064557507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b81601414156200067657507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b8160151415620006a757507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b8160161415620006d857507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b81601714156200070957507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b81601814156200073a57507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b81601914156200076b57507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a14156200079c57507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b1415620007cd57507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c1415620007fe57507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d14156200082f57507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e14156200086057507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f14156200089157507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b815260206004820152601360248201527f496e646578206f7574206f6620626f756e6473000000000000000000000000006044820152606401620000c6565b60008060008060008060c08789031215620008f457600080fd5b86516200090181620009e0565b602088015190965063ffffffff811681146200091c57600080fd5b60408801519095506200092f81620009e0565b60608801519094506200094281620009e0565b60808801519093506200095581620009e0565b60a088015190925060ff811681146200096d57600080fd5b809150509295509295509295565b600063ffffffff838116908316818110156200099b576200099b620009ca565b039392505050565b600063ffffffff80831681811415620009c057620009c0620009ca565b6001019392505050565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0381168114620009f657600080fd5b50565b60805160601c60a05160e01c60c05160f81c60e05160601c614f4f62000b0360003960008181610b8301528181610e0101528181610e950152818161167e0152818161171c0152818161195001528181611f3201528181611ff301528181612e1a01528181612eb801528181612f05015281816130ba015261315201526000818161069b01528181610c6301528181610ccd015281816114cd015281816117cb01528181611bc001528181611c4c015281816131f3015281816133520152818161365c01526137860152600081816105cc01528181610d5601528181611d0b0152818161389c015261397c015260008181610ac30152818161394c0152613a150152614f4f6000f3fe6080604052600436106103815760003560e01c80638ea3099e116101d1578063c80916d411610102578063e8295588116100a0578063f5ab0dd61161006f578063f5ab0dd614610b12578063fa73168714610b41578063fc0c546a14610b71578063fc7e9c6f14610ba557600080fd5b8063e829558814610a5d578063ec73295914610a7d578063ed33639f14610ab1578063f178e47c14610ae557600080fd5b8063dbc916b8116100dc578063dbc916b8146109a5578063e4a30116146109e0578063e5285dcc14610a00578063e70ea87c14610a3057600080fd5b8063c80916d414610950578063c9be725014610970578063cd87a3b41461099057600080fd5b80639ff800631161016f578063b7566a6711610149578063b7566a67146108d9578063ba70f757146108f9578063bc063e1a14610705578063c2b40ae41461092357600080fd5b80639ff80063146105ee578063a0d192f514610899578063b2bc6e0f146108b957600080fd5b806392156311116101ab578063921563111461080957806395c87d1a146108395780639bbca3a91461084c5780639fa12d0b1461086c57600080fd5b80638ea3099e146107b65780638f1c56bd146107d657806390eeb02b146107ec57600080fd5b80634c830cbd116102b657806371523c3211610254578063839df94511610223578063839df9451461071d578063840b27911461074d5780638b7e8782146107635780638c0d34d81461079457600080fd5b806371523c321461068957806372c1ad03146106cf57806378abb49b146106ef5780637fe24ffe1461070557600080fd5b80635d2d766c116102905780635d2d766c1461060e578063616e0957146106415780636ad481f3146106615780636d9833e31461066957600080fd5b80634c830cbd1461058e5780634ecf518b146105ba5780634f401241146105ee57600080fd5b80633408e4701161032357806342d90711116102fd57806342d907111461050357806343e7119f1461052357806344347ba91461055b578063460b53e31461056e57600080fd5b80633408e470146104bb578063414a37ba146104ce5780634167bb1e146104f057600080fd5b80631e6276171161035f5780631e6276171461041e5780632063e3d3146104405780632570b7b4146104555780632b7ac3f31461048357600080fd5b80630b27fb9a1461038657806311e4dcb9146103be57806317cc915c146103ee575b600080fd5b34801561039257600080fd5b50600b54600160a01b900463ffffffff165b60405163ffffffff90911681526020015b60405180910390f35b3480156103ca57600080fd5b506103de6103d93660046142f9565b610bca565b60405190151581526020016103b5565b3480156103fa57600080fd5b506103de6104093660046141ad565b600c6020526000908152604090205460ff1681565b34801561042a57600080fd5b50610433610c5f565b6040516103b591906146b5565b61045361044e366004613fb6565b610db5565b005b34801561046157600080fd5b506104756104703660046142f9565b610ef6565b6040519081526020016103b5565b34801561048f57600080fd5b50600b546104a3906001600160a01b031681565b6040516001600160a01b0390911681526020016103b5565b3480156104c757600080fd5b5046610475565b3480156104da57600080fd5b50610475600080516020614efa83398151915281565b6104536104fe3660046144d3565b610fe4565b34801561050f57600080fd5b5061045361051e3660046142f9565b611104565b34801561052f57600080fd5b5061047561053e36600461458f565b600960209081526000928352604080842090915290825290205481565b610453610569366004614563565b611139565b34801561057a57600080fd5b50610453610589366004613fb6565b611667565b34801561059a57600080fd5b506105a36116b7565b60405165ffffffffffff90911681526020016103b5565b3480156105c657600080fd5b506103a47f000000000000000000000000000000000000000000000000000000000000000081565b3480156105fa57600080fd5b50610453610609366004613fb6565b611705565b34801561061a57600080fd5b506103a46106293660046141ad565b600a6020526000908152604090205463ffffffff1681565b34801561064d57600080fd5b506103de61065c36600461408b565b611755565b610453611939565b34801561067557600080fd5b506103de6106843660046141ad565b6119c0565b34801561069557600080fd5b506106bd7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016103b5565b3480156106db57600080fd5b506104536106ea366004613fe2565b611a3b565b3480156106fb57600080fd5b5061047560105481565b34801561071157600080fd5b50610475600160f81b81565b34801561072957600080fd5b506103de6107383660046141ad565b600d6020526000908152604090205460ff1681565b34801561075957600080fd5b50610475600f5481565b34801561076f57600080fd5b5061077b600160f81b81565b6040516001600160f01b031990911681526020016103b5565b3480156107a057600080fd5b506107a9611bbc565b6040516103b591906146ed565b3480156107c257600080fd5b506104756107d13660046142c4565b611d6f565b3480156107e257600080fd5b50610475600e5481565b3480156107f857600080fd5b506003546103a49063ffffffff1681565b34801561081557600080fd5b506103de6108243660046141ad565b60009081526007602052604090205460ff1690565b610453610847366004613f75565b611ed2565b34801561085857600080fd5b50610453610867366004614470565b611f98565b34801561087857600080fd5b5061088c610887366004614017565b612181565b6040516103b5919061466f565b3480156108a557600080fd5b506104536108b4366004613fe2565b612246565b3480156108c557600080fd5b506104536108d436600461431b565b6123b1565b3480156108e557600080fd5b506104536108f43660046143d6565b612416565b34801561090557600080fd5b5060035463ffffffff16600090815260026020526040902054610475565b34801561092f57600080fd5b5061047561093e3660046141ad565b60026020526000908152604090205481565b34801561095c57600080fd5b506005546104a3906001600160a01b031681565b34801561097c57600080fd5b5061045361098b36600461434f565b612430565b34801561099c57600080fd5b506103a4601e81565b3480156109b157600080fd5b506109c56109c03660046141ad565b612443565b604080519384526020840192909252908201526060016103b5565b3480156109ec57600080fd5b506104536109fb3660046142f9565b612476565b348015610a0c57600080fd5b506103de610a1b3660046141ad565b6000908152600c602052604090205460ff1690565b348015610a3c57600080fd5b50610475610a4b3660046141ad565b60066020526000908152604090205481565b348015610a6957600080fd5b50610475610a783660046141ad565b612534565b348015610a8957600080fd5b506104757f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c81565b348015610abd57600080fd5b506104a37f000000000000000000000000000000000000000000000000000000000000000081565b348015610af157600080fd5b50610475610b003660046141ad565b60016020526000908152604090205481565b348015610b1e57600080fd5b50610b32610b2d3660046140bf565b612b74565b6040516103b593929190614754565b348015610b4d57600080fd5b506103de610b5c3660046141ad565b60076020526000908152604090205460ff1681565b348015610b7d57600080fd5b506104a37f000000000000000000000000000000000000000000000000000000000000000081565b348015610bb157600080fd5b506003546103a490640100000000900463ffffffff1681565b600081610bd957506000610c59565b6000838152600a602052604090205463ffffffff16805b600085815260096020908152604080832063ffffffff85168452909152902054841415610c2257600192505050610c59565b63ffffffff8116610c315750601e5b80610c3b81614dd9565b9150508163ffffffff168163ffffffff161415610bf0576000925050505b92915050565b60607f000000000000000000000000000000000000000000000000000000000000000060ff166001600160401b03811115610c9c57610c9c614ece565b604051908082528060200260200182016040528015610cc5578160200160208202803683370190505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610db157610d01816001614b52565b60085410610d515760088181548110610d1c57610d1c614eb8565b906000526020600020906003020160010154828281518110610d4057610d40614eb8565b602002602001018181525050610d9f565b610d807f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612534565b828281518110610d9257610d92614eb8565b6020026020010181815250505b80610da981614df9565b915050610ccb565b5090565b6001600160a01b038216610e6357803414610dcf57600080fd5b604051633d97186b60e11b81523360048201526001600160a01b038381166024830152600060448301523060648301527f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d69034906084016000604051808303818588803b158015610e4657600080fd5b505af1158015610e5a573d6000803e3d6000fd5b50505050505050565b604051633d97186b60e11b81523360048201526001600160a01b038381166024830152604482018390523060648301527f00000000000000000000000000000000000000000000000000000000000000001690637b2e30d6906084015b600060405180830381600087803b158015610eda57600080fd5b505af1158015610eee573d6000803e3d6000fd5b505050505050565b6000600160f81b8210610f3e5760405162461bcd60e51b815260206004820152600b60248201526a496e76616c69642066656560a81b60448201526064015b60405180910390fd5b610f4b600160f81b614e6f565b83138015610f5c5750600160f81b83125b610f9d5760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a5908195e1d08185b5bdd5b9d60721b6044820152606401610f35565b6000610fa98385614cfb565b90506000811215610fda57610fbd81614e6f565b610fd590600080516020614efa833981519152614d3a565b610fdc565b805b949350505050565b610fee8383612bfd565b60008260200151131561102f57601054826020015111156110215760405162461bcd60e51b8152600401610f35906148dd565b61102f818360200151610db5565b6000826020015112156110d95781516001600160a01b03166110935760405162461bcd60e51b815260206004820152601e60248201527f43616e277420776974686472617720746f207a65726f206164647265737300006044820152606401610f35565b600f5482602001516110a490614e6f565b10156110c25760405162461bcd60e51b8152600401610f359061481a565b6110d9818360000151846020015161084790614e6f565b6060820151156110f5576110f582604001518360600151612e02565b6110ff8383612f49565b505050565b6005546001600160a01b0316331461112e5760405162461bcd60e51b8152600401610f3590614927565b600f91909155601055565b6005546001600160a01b031633146111635760405162461bcd60e51b8152600401610f3590614927565b600260045414156111865760405162461bcd60e51b8152600401610f35906148a6565b60026004908155604051639215631160e01b8152908101849052309063921563119060240160206040518083038186803b1580156111c357600080fd5b505afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb919061418b565b156114c65760008381526007602052604090205460ff166112845760405162461bcd60e51b815260206004820152603760248201527f436861696e206d75737420626520696e74656772617465642066726f6d20746860448201527f6520627269646765206265666f726520757064617465730000000000000000006064820152608401610f35565b6000838152600660205260409020546008805483929081106112a8576112a8614eb8565b906000526020600020906003020160020154106113075760405162461bcd60e51b815260206004820152601e60248201527f4e6577206c65616620696e646578206d757374206265206772656174657200006044820152606401610f35565b60008381526006602052604090205460088054909190811061132b5761132b614eb8565b9060005260206000209060030201600201546201000061134b9190614b52565b81106113a95760405162461bcd60e51b815260206004820152602760248201527f4e6577206c65616620696e646578206d7573742077697468696e20325e3136206044820152667570646174657360c81b6064820152608401610f35565b60008381526006602090815260409182902054825160608101845286815291820185905291810183905260088054839081106113e7576113e7614eb8565b60009182526020808320845160039093020191825583810151600180840191909155604094850151600290930192909255878352600a9052918120549091601e9161143a9163ffffffff90911690614b6a565b6114449190614e4c565b6000868152600a60209081526040808320805463ffffffff191663ffffffff86169081179091556009835281842090845282529182902087905581518881529081018690529081018690529091507f675e61f04bcf314a9c310a93f2346f417a03d704c1caf9c6af8a65ad8addfa3f9060600160405180910390a1505061165d565b60085460ff7f0000000000000000000000000000000000000000000000000000000000000000161161153a5760405162461bcd60e51b815260206004820152601a60248201527f5468697320416e63686f722069732061742063617061636974790000000000006044820152606401610f35565b6000838152600760209081526040808320805460ff19166001908117909155600880548351606080820186528a82528187018a81528287018a815295840185559388528151600384027ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee381019190915593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee485015593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee590930192909255888652600685528386208190556009855283862086805285528386208890558351898152948501879052928401879052919391927fcf4749969bace1552af6a97fe7e4affedf68875511f9746c6332eb40647b3054910160405180910390a15050505b5050600160045550565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca6938890610ec09033908690869060040161464b565b60408051600160f81b602082018190524660e01b6001600160e01b031981166022840152835180840360060181526026909301909352600092916116fa81614d76565b60d01c935050505090565b60405163130e405b60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063261c80b690610ec09033908690869060040161464b565b600061177a8260008151811061176d5761176d614eb8565b60200260200101516119c0565b6117c65760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f742066696e6420796f7572206d65726b6c6520726f6f74000000006044820152606401610f35565b6117f17f00000000000000000000000000000000000000000000000000000000000000006001614b92565b60ff168251146118435760405162461bcd60e51b815260206004820152601b60248201527f496e636f727265637420726f6f74206172726179206c656e67746800000000006044820152606401610f35565b60005b6008548110156119305760006008828154811061186557611865614eb8565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505090506118d18160000151858460016118b49190614b52565b815181106118c4576118c4614eb8565b6020026020010151610bca565b61191d5760405162461bcd60e51b815260206004820152601760248201527f4e65696768626f7220726f6f74206e6f7420666f756e640000000000000000006044820152606401610f35565b508061192881614df9565b915050611846565b50600192915050565b604051630594d27160e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ca6938890349061198c903390600090819060040161464b565b6000604051808303818588803b1580156119a557600080fd5b505af11580156119b9573d6000803e3d6000fd5b5050505050565b6000816119cf57506000919050565b60035463ffffffff16805b63ffffffff8116600090815260026020526040902054841415611a01575060019392505050565b63ffffffff8116611a105750601e5b80611a1a81614dd9565b9150508163ffffffff168163ffffffff1614156119da575060009392505050565b6005546001600160a01b03163314611a655760405162461bcd60e51b8152600401610f3590614927565b6001600160a01b038216611ab15760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610f35565b600b5463ffffffff808316600160a01b9092041610611b025760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610f35565b600b54611b1d90600160a01b900463ffffffff166001614b6a565b63ffffffff168163ffffffff161115611b745760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610f35565b600580546001600160a01b039093166001600160a01b031990931692909217909155600b805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b60607f000000000000000000000000000000000000000000000000000000000000000060ff166001600160401b03811115611bf957611bf9614ece565b604051908082528060200260200182016040528015611c4457816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181611c175790505b50905060005b7f000000000000000000000000000000000000000000000000000000000000000060ff16811015610db157611c80816001614b52565b60085410611cf45760088181548110611c9b57611c9b614eb8565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050828281518110611ce457611ce4614eb8565b6020026020010181905250611d5d565b604051806060016040528060008152602001611d357f000000000000000000000000000000000000000000000000000000000000000063ffffffff16612534565b81526020016000815250828281518110611d5157611d51614eb8565b60200260200101819052505b80611d6781614df9565b915050611c4a565b6000600080516020614efa8339815191528310611dce5760405162461bcd60e51b815260206004820181905260248201527f5f6c6566742073686f756c6420626520696e7369646520746865206669656c646044820152606401610f35565b600080516020614efa8339815191528210611e355760405162461bcd60e51b815260206004820152602160248201527f5f72696768742073686f756c6420626520696e7369646520746865206669656c6044820152601960fa1b6064820152608401610f35565b6040805180820182528481526020810184905290516314d2f97b60e11b8152849184916001600160a01b038816916329a5f2f691611e769190600401614746565b60206040518083038186803b158015611e8e57600080fd5b505afa158015611ea2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec6919061454a565b925050505b9392505050565b60026004541415611ef55760405162461bcd60e51b8152600401610f35906148a6565b6002600455611f0430826130a2565b604051632404142f60e11b81526001600160a01b0384811660048301526024820183905283811660448301527f00000000000000000000000000000000000000000000000000000000000000001690634808285e90606401600060405180830381600087803b158015611f7657600080fd5b505af1158015611f8a573d6000803e3d6000fd5b505060016004555050505050565b60026004541415611fbb5760405162461bcd60e51b8152600401610f35906148a6565b6002600455611fca8282612bfd565b6000816020015113156120a45760208101516040516323b872dd60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916323b872dd9161202b91339130919060040161464b565b602060405180830381600087803b15801561204557600080fd5b505af1158015612059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207d919061418b565b50601054816020015111156120a45760405162461bcd60e51b8152600401610f35906148dd565b6000816020015112156121525780516001600160a01b03166121085760405162461bcd60e51b815260206004820152601e60248201527f43616e277420776974686472617720746f207a65726f206164647265737300006044820152606401610f35565b600f54816020015161211990614e6f565b10156121375760405162461bcd60e51b8152600401610f359061481a565b6121528160000151826020015161214d90614e6f565b6130a2565b60608101511561216e5761216e81604001518260600151612e02565b6121788282612f49565b50506001600455565b6060816001600160401b0381111561219b5761219b614ece565b6040519080825280602002602001820160405280156121c4578160200160208202803683370190505b50905060005b8281101561223f576122038484838181106121e7576121e7614eb8565b905060200201356000908152600c602052604090205460ff1690565b1561222d57600182828151811061221c5761221c614eb8565b911515602092830291909101909101525b8061223781614df9565b9150506121ca565b5092915050565b6005546001600160a01b031633146122705760405162461bcd60e51b8152600401610f3590614927565b6001600160a01b0382166122bc5760405162461bcd60e51b8152602060048201526013602482015272048616e646c65722063616e6e6f74206265203606c1b6044820152606401610f35565b600b5463ffffffff808316600160a01b909204161061230d5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964206e6f6e636560981b6044820152606401610f35565b600b5461232890600160a01b900463ffffffff166001614b6a565b63ffffffff168163ffffffff16111561237f5760405162461bcd60e51b81526020600482015260196024820152784e6f6e6365206d75737420696e6372656d656e74206279203160381b6044820152606401610f35565b600b805463ffffffff909216600160a01b026001600160c01b03199092166001600160a01b0390931692909217179055565b80516001600160a01b0316331461240a5760405162461bcd60e51b815260206004820152601c60248201527f6f6e6c79206f776e65722063616e2062652072656769737465726564000000006044820152606401610f35565b61241381613179565b50565b61241f846123b1565b61242a838383610fe4565b50505050565b612439836123b1565b6110ff8282611f98565b6008818154811061245357600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b600054610100900460ff168061248f575060005460ff16155b6124f25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610f35565b600054610100900460ff16158015612514576000805461ffff19166101011790555b600f839055601082905580156110ff576000805461ff0019169055505050565b60008161256257507f2fe54c60d3acabf3343a35b6eba15db4821b340f76e741e2249685ed4899af6c919050565b816001141561259257507f13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8919050565b81600214156125c257507f217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765919050565b81600314156125f257507f0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee919050565b816004141561262257507f27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587919050565b816005141561265257507f194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc919050565b816006141561268257507f1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f919050565b81600714156126b257507f267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219919050565b81600814156126e257507f1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d919050565b816009141561271257507f0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce919050565b81600a141561274257507f2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7919050565b81600b141561277257507f280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47919050565b81600c14156127a257507f045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b919050565b81600d14156127d257507f27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366919050565b81600e141561280257507f1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef919050565b81600f141561283257507f20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca919050565b816010141561286257507f09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec919050565b816011141561289157507e64b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b919050565b81601214156128c157507f095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f919050565b81601314156128f157507f11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63919050565b816014141561292157507f2b0f6fc0179fa65b6f73627c0e1e84c7374d2eaec44c9a48f2571393ea77bcbb919050565b816015141561295157507f16fdb637c2abf9c0f988dbf2fd64258c46fb6a273d537b2cf1603ea460b13279919050565b816016141561298157507f21bbd7e944f6124dad4c376df9cc12e7ca66e47dff703ff7cedb1a454edcf0ff919050565b81601714156129b157507f2784f8220b1c963e468f590f137baaa1625b3b92a27ad9b6e84eb0d3454d9962919050565b81601814156129e157507f16ace1a65b7534142f8cc1aad810b3d6a7a74ca905d9c275cb98ba57e509fc10919050565b8160191415612a1157507f2328068c6a8c24265124debd8fe10d3f29f0665ea725a65e3638f6192a96a013919050565b81601a1415612a4157507f2ddb991be1f028022411b4c4d2c22043e5e751c120736f00adf54acab1c9ac14919050565b81601b1415612a7157507f0113798410eaeb95056a464f70521eb58377c0155f2fe518a5594d38cc209cc0919050565b81601c1415612aa157507f202d1ae61526f0d0d01ef80fb5d4055a7af45721024c2c24cffd6a3798f54d50919050565b81601d1415612ad157507f23ab323453748129f2765f79615022f5bebd6f4096a796300aab049a60b0f187919050565b81601e1415612b0157507f1f15585f8947e378bcf8bd918716799da909acdb944c57150b1eb4565fda8aa0919050565b81601f1415612b3157507f1eb064b21055ac6a350cf41eb30e4ce2cb19680217df3a243617c2838185ad06919050565b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b6044820152606401610f35565b919050565b612b7c613bfb565b612b84613c19565b612b8c613bfb565b50506040805180820182528351815260208085015181830152825160808082018552868501518286019081526060808901519084015282528451808601865290870151815260a08701518184015281830152835180850190945260c0860151845260e0909501519083015293909150565b60005b826040015151811015612c9b57612c4383604001518281518110612c2657612c26614eb8565b60200260200101516000908152600c602052604090205460ff1690565b15612c895760405162461bcd60e51b8152602060048201526016602482015275125b9c1d5d081a5cc8185b1c9958591e481cdc195b9d60521b6044820152606401610f35565b80612c9381614df9565b915050612c00565b50600080516020614efa83398151915281604051602001612cbc919061495e565b6040516020818303038152906040528051906020012060001c612cdf9190614e38565b60a083015114612d315760405162461bcd60e51b815260206004820152601c60248201527f496e636f72726563742065787465726e616c20646174612068617368000000006044820152606401610f35565b612d4381602001518260600151610ef6565b826080015114612d8d5760405162461bcd60e51b8152602060048201526015602482015274125b9d985b1a59081c1d589b1a58c8185b5bdd5b9d605a1b6044820152606401610f35565b612d96826131c5565b60005b8260400151518110156110ff576001600c600085604001518481518110612dc257612dc2614eb8565b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055508080612dfa90614df9565b915050612d99565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015612e6457600080fd5b505afa158015612e78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9c919061454a565b905081156110ff57818110612edf576110ff6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016848461347f565b6040516340c10f1960e01b81526001600160a01b038481166004830152602482018490527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b158015610e4657600080fd5b60608201518051602090910151612f6091906134d1565b506060820151516003547ff3843eddcfcac65d12d9f26261dab50671fdbf5dc44441816c8bbdace2411afd9190612fa790600290640100000000900463ffffffff16614d51565b8360800151604051612fbb939291906147d9565b60405180910390a160608201517ff3843eddcfcac65d12d9f26261dab50671fdbf5dc44441816c8bbdace2411afd906001602002015160035461300e90600190640100000000900463ffffffff16614d51565b8360a00151604051613022939291906147d9565b60405180910390a160005b8260400151518110156110ff577f5e58f77bbf94b46d8d896e29753e4458c6e59b48581e20ed58c9558e96f297ce8360400151828151811061307157613071614eb8565b602002602001015160405161308891815260200190565b60405180910390a18061309a81614df9565b91505061302d565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561310457600080fd5b505afa158015613118573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061313c919061454a565b9050818110612edf576110ff6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016848461347f565b80600001516001600160a01b03167f2c1ca5c14df2aba59d26842c5ff53f6817052ef34f6f7537f8b4c9e3805a5e5082602001516040516131ba9190614807565b60405180910390a250565b806040015151600214156133245760008073__$c855d983235a063579a323068f4c8734f9$__63416e8491847f00000000000000000000000000000000000000000000000000000000000000006040518363ffffffff1660e01b815260040161322f9291906149cb565b60006040518083038186803b15801561324757600080fd5b505af415801561325b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261328391908101906141c6565b9150915061329081611755565b6132cc5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610f35565b82516132d890836135ff565b6110ff5760405162461bcd60e51b815260206004820152601960248201527f496e76616c6964207472616e73616374696f6e2070726f6f66000000000000006044820152606401610f35565b806040015151601014156134375760008073__$c855d983235a063579a323068f4c8734f9$__637dc45e3f847f00000000000000000000000000000000000000000000000000000000000000006040518363ffffffff1660e01b815260040161338e9291906149cb565b60006040518083038186803b1580156133a657600080fd5b505af41580156133ba573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526133e291908101906141c6565b915091506133ef81611755565b61342b5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726f6f747360981b6044820152606401610f35565b82516132d89083613729565b60405162461bcd60e51b815260206004820152601760248201527f756e737570706f7274656420696e70757420636f756e740000000000000000006044820152606401610f35565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526110ff9084906137b1565b6000828152600d602052604081205460ff16156135005760405162461bcd60e51b8152600401610f3590614865565b6000828152600d602052604090205460ff161561352f5760405162461bcd60e51b8152600401610f3590614865565b600061353b8484613883565b6000858152600d602090815260408083208054600160ff19918216811790925588855293829020805490941617909255815163ffffffff84168152429181019190915291925085917fe77f587aa74084fff834b53ccbab07695ee4594b9c9d5bfd8a7dd80c556124b5910160405180910390a2827fe77f587aa74084fff834b53ccbab07695ee4594b9c9d5bfd8a7dd80c556124b56135db836001614b6a565b6040805163ffffffff90921682524260208301520160405180910390a29392505050565b60008083806020019051810190613616919061412a565b9050600080600061362684612b74565b600b54604051638041ca5360e01b815293965091945092506001600160a01b031690638041ca5390613687908690869086908c907f00000000000000000000000000000000000000000000000000000000000000009060019060040161477d565b60206040518083038186803b15801561369f57600080fd5b505afa1580156136b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d7919061418b565b94508461371f5760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103bb4ba34323930bb90383937b7b360511b6044820152606401610f35565b5050505092915050565b60008083806020019051810190613740919061412a565b9050600080600061375084612b74565b600b54604051638041ca5360e01b815293965091945092506001600160a01b031690638041ca5390613687908690869086908c907f00000000000000000000000000000000000000000000000000000000000000009060009060040161477d565b6000613806826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613af09092919063ffffffff16565b8051909150156110ff5780806020019051810190613824919061418b565b6110ff5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610f35565b600354600090640100000000900463ffffffff166138c27f00000000000000000000000000000000000000000000000000000000000000006002614c1f565b63ffffffff168163ffffffff1614156139365760405162461bcd60e51b815260206004820152603060248201527f4d65726b6c6520747265652069732066756c6c2e204e6f206d6f7265206c656160448201526f1d995cc818d85b88189948185919195960821b6064820152608401610f35565b6000613943600283614bb7565b905060006139727f00000000000000000000000000000000000000000000000000000000000000008787611d6f565b905060008060015b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff161015613a5c576139b9600286614e4c565b63ffffffff166139f4578392506139d58163ffffffff16612534565b63ffffffff821660009081526001602052604090208590559150613a10565b63ffffffff811660009081526001602052604090205492508391505b613a3b7f00000000000000000000000000000000000000000000000000000000000000008484611d6f565b9350613a48600286614bb7565b945080613a5481614e14565b91505061397a565b50600354600090601e90613a779063ffffffff166001614b6a565b613a819190614e4c565b6003805463ffffffff191663ffffffff83169081179091556000908152600260208190526040909120869055909150613abb908790614b6a565b6003805463ffffffff929092166401000000000267ffffffff0000000019909216919091179055509394505050505092915050565b6060610fdc848460008585843b613b495760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610f35565b600080866001600160a01b03168587604051613b65919061462f565b60006040518083038185875af1925050503d8060008114613ba2576040519150601f19603f3d011682016040523d82523d6000602084013e613ba7565b606091505b5091509150613bb7828286613bc2565b979650505050505050565b60608315613bd1575081611ecb565b825115613be15782518084602001fd5b8160405162461bcd60e51b8152600401610f359190614807565b60405180604001604052806002906020820280368337509192915050565b60405180604001604052806002905b613c30613bfb565b815260200190600190039081613c285790505090565b8035612b6f81614ee4565b600082601f830112613c6257600080fd5b604051604081018181106001600160401b0382111715613c8457613c84614ece565b8060405250808385604086011115613c9b57600080fd5b60005b6002811015613cbd578135835260209283019290910190600101613c9e565b509195945050505050565b600082601f830112613cd957600080fd5b81356020613cee613ce983614b08565b614ad8565b80838252828201915082860187848660051b8901011115613d0e57600080fd5b60005b85811015613d2d57813584529284019290840190600101613d11565b5090979650505050505050565b600082601f830112613d4b57600080fd5b8135613d59613ce982614b2b565b818152846020838601011115613d6e57600080fd5b816020850160208301376000918101602001919091529392505050565b600060408284031215613d9d57600080fd5b604051604081016001600160401b038282108183111715613dc057613dc0614ece565b8160405282935084359150613dd482614ee4565b90825260208401359080821115613dea57600080fd5b50613df785828601613d3a565b6020830152505092915050565b600060c08284031215613e1657600080fd5b613e1e614a8d565b9050613e2982613c46565b815260208201356020820152613e4160408301613c46565b60408201526060820135606082015260808201356001600160401b0380821115613e6a57600080fd5b613e7685838601613d3a565b608084015260a0840135915080821115613e8f57600080fd5b50613e9c84828501613d3a565b60a08301525092915050565b600060e08284031215613eba57600080fd5b613ec2614a8d565b905081356001600160401b0380821115613edb57600080fd5b613ee785838601613d3a565b83526020840135915080821115613efd57600080fd5b613f0985838601613d3a565b60208401526040840135915080821115613f2257600080fd5b50613f2f84828501613cc8565b604083015250613f428360608401613c51565b606082015260a0820135608082015260c082013560a082015292915050565b803563ffffffff81168114612b6f57600080fd5b600080600060608486031215613f8a57600080fd5b8335613f9581614ee4565b92506020840135613fa581614ee4565b929592945050506040919091013590565b60008060408385031215613fc957600080fd5b8235613fd481614ee4565b946020939093013593505050565b60008060408385031215613ff557600080fd5b823561400081614ee4565b915061400e60208401613f61565b90509250929050565b6000806020838503121561402a57600080fd5b82356001600160401b038082111561404157600080fd5b818501915085601f83011261405557600080fd5b81358181111561406457600080fd5b8660208260051b850101111561407957600080fd5b60209290920196919550909350505050565b60006020828403121561409d57600080fd5b81356001600160401b038111156140b357600080fd5b610fdc84828501613cc8565b60006101008083850312156140d357600080fd5b83601f8401126140e257600080fd5b6140ea614ab5565b80848684870111156140fb57600080fd5b600093505b600884101561412057803583526001939093019260209283019201614100565b5095945050505050565b600061010080838503121561413e57600080fd5b83601f84011261414d57600080fd5b614155614ab5565b808486848701111561416657600080fd5b600093505b60088410156141205780518352600193909301926020928301920161416b565b60006020828403121561419d57600080fd5b81518015158114610fda57600080fd5b6000602082840312156141bf57600080fd5b5035919050565b600080604083850312156141d957600080fd5b82516001600160401b03808211156141f057600080fd5b818501915085601f83011261420457600080fd5b81516020614214613ce983614b2b565b828152888284870101111561422857600080fd5b61423783838301848801614dad565b8782015190965093508284111561424d57600080fd5b838701935087601f85011261426157600080fd5b83519250614271613ce984614b08565b8381528181019250848201600585901b860183018a101561429157600080fd5b600095505b848610156142b4578051845260019590950194928201928201614296565b5080955050505050509250929050565b6000806000606084860312156142d957600080fd5b83356142e481614ee4565b95602085013595506040909401359392505050565b6000806040838503121561430c57600080fd5b50508035926020909101359150565b60006020828403121561432d57600080fd5b81356001600160401b0381111561434357600080fd5b610fdc84828501613d8b565b60008060006060848603121561436457600080fd5b83356001600160401b038082111561437b57600080fd5b61438787838801613d8b565b9450602086013591508082111561439d57600080fd5b6143a987838801613ea8565b935060408601359150808211156143bf57600080fd5b506143cc86828701613e04565b9150509250925092565b600080600080608085870312156143ec57600080fd5b84356001600160401b038082111561440357600080fd5b61440f88838901613d8b565b9550602087013591508082111561442557600080fd5b61443188838901613ea8565b9450604087013591508082111561444757600080fd5b5061445487828801613e04565b925050606085013561446581614ee4565b939692955090935050565b6000806040838503121561448357600080fd5b82356001600160401b038082111561449a57600080fd5b6144a686838701613ea8565b935060208501359150808211156144bc57600080fd5b506144c985828601613e04565b9150509250929050565b6000806000606084860312156144e857600080fd5b83356001600160401b03808211156144ff57600080fd5b61450b87838801613ea8565b9450602086013591508082111561452157600080fd5b5061452e86828701613e04565b925050604084013561453f81614ee4565b809150509250925092565b60006020828403121561455c57600080fd5b5051919050565b60008060006060848603121561457857600080fd5b505081359360208301359350604090920135919050565b600080604083850312156145a257600080fd5b8235915061400e60208401613f61565b8060005b600281101561242a576145ca8483516145e0565b60409390930192602091909101906001016145b6565b8060005b600281101561242a5781518452602093840193909101906001016145e4565b6000815180845261461b816020860160208601614dad565b601f01601f19169290920160200192915050565b60008251614641818460208701614dad565b9190910192915050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6020808252825182820181905260009190848201906040850190845b818110156146a957835115158352928401929184019160010161468b565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156146a9578351835292840192918401916001016146d1565b602080825282518282018190526000919060409081850190868401855b82811015614739578151805185528681015187860152850151858501526060909301929085019060010161470a565b5091979650505050505050565b60408101610c5982846145e0565b610100810161476382866145e0565b61477060408301856145b2565b610fdc60c08301846145e0565b600061016061478c838a6145e0565b61479960408401896145b2565b6147a660c08401886145e0565b806101008401526147b981840187614603565b60ff95909516610120840152505090151561014090910152949350505050565b83815263ffffffff831660208201526060604082015260006147fe6060830184614603565b95945050505050565b602081526000611ecb6020830184614603565b6020808252602b908201527f616d6f756e74206973206c657373207468616e206d696e696d616c576974686460408201526a1c985dd85b105b5bdd5b9d60aa1b606082015260800190565b60208082526021908201527f54686520636f6d6d69746d656e7420686173206265656e207375626d697474656040820152601960fa1b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252602a908201527f616d6f756e74206973206c6172676572207468616e206d6178696d756d4465706040820152691bdcda5d105b5bdd5b9d60b21b606082015260800190565b60208082526019908201527f73656e646572206973206e6f74207468652068616e646c657200000000000000604082015260600190565b60208152600060018060a01b03808451166020840152602084015160408401528060408501511660608401525060608301516080830152608083015160c060a08401526149ae60e0840182614603565b905060a0840151601f198483030160c08501526147fe8282614603565b604081526000835160e060408401526149e8610120840182614603565b9050602080860151603f1980868503016060870152614a078483614603565b6040890151878203909201608088015281518082529184019450600092508301905b80831015614a495784518252938301936001929092019190830190614a29565b5060608801519350614a5e60a08701856145e0565b608088015160e087015260a088015161010087015260ff8716838701529350614a849050565b50509392505050565b60405160c081016001600160401b0381118282101715614aaf57614aaf614ece565b60405290565b60405161010081016001600160401b0381118282101715614aaf57614aaf614ece565b604051601f8201601f191681016001600160401b0381118282101715614b0057614b00614ece565b604052919050565b60006001600160401b03821115614b2157614b21614ece565b5060051b60200190565b60006001600160401b03821115614b4457614b44614ece565b50601f01601f191660200190565b60008219821115614b6557614b65614e8c565b500190565b600063ffffffff808316818516808303821115614b8957614b89614e8c565b01949350505050565b600060ff821660ff84168060ff03821115614baf57614baf614e8c565b019392505050565b600063ffffffff80841680614bce57614bce614ea2565b92169190910492915050565b600181815b80851115614c17578163ffffffff04821115614bfd57614bfd614e8c565b80851615614c0a57918102915b93841c9390800290614bdf565b509250929050565b600063ffffffff610fdc818516828516600082614c3e57506001610c59565b81614c4b57506000610c59565b8160018114614c615760028114614c6b57614c9c565b6001915050610c59565b60ff841115614c7c57614c7c614e8c565b6001841b915063ffffffff821115614c9657614c96614e8c565b50610c59565b5060208310610133831016604e8410600b8410161715614cd3575081810a63ffffffff811115614cce57614cce614e8c565b610c59565b614cdd8383614bda565b8063ffffffff04821115614cf357614cf3614e8c565b029392505050565b60008083128015600160ff1b850184121615614d1957614d19614e8c565b6001600160ff1b0384018313811615614d3457614d34614e8c565b50500390565b600082821015614d4c57614d4c614e8c565b500390565b600063ffffffff83811690831681811015614d6e57614d6e614e8c565b039392505050565b805160208201516001600160d01b03198082169291906006831015614da55780818460060360031b1b83161693505b505050919050565b60005b83811015614dc8578181015183820152602001614db0565b8381111561242a5750506000910152565b600063ffffffff821680614def57614def614e8c565b6000190192915050565b6000600019821415614e0d57614e0d614e8c565b5060010190565b600063ffffffff80831681811415614e2e57614e2e614e8c565b6001019392505050565b600082614e4757614e47614ea2565b500690565b600063ffffffff80841680614e6357614e63614ea2565b92169190910692915050565b6000600160ff1b821415614e8557614e85614e8c565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461241357600080fdfe30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a2646970667358221220ca16b4b0f73f59557ba54526ee3688b7a32655ff98c4bdba8f121198220f8ceb64736f6c63430008050033"; type VAnchorConstructorParams = | [linkLibraryAddresses: VAnchorLibraryAddresses, signer?: Signer] diff --git a/packages/utils/src/Utxo.ts b/packages/utils/src/Utxo.ts index 7d011aab5..3fdbc16fe 100644 --- a/packages/utils/src/Utxo.ts +++ b/packages/utils/src/Utxo.ts @@ -2,6 +2,7 @@ import { BigNumberish, ethers } from 'ethers'; import { randomBN, poseidonHash, toBuffer } from './utils'; import { Keypair } from './Keypair'; import { RootInfo } from './types'; +import { getChainIdType } from '.'; const { BigNumber } = ethers const F = require('circomlibjs').babyjub.F; @@ -30,7 +31,7 @@ export class Utxo { amount = BigNumber.from(0), keypair = new Keypair(), blinding = randomBN(), - originChainId = BigNumber.from(31337), + originChainId = BigNumber.from(getChainIdType(31337)), index = null } = {}) { this.chainId = BigNumber.from(chainId); diff --git a/packages/vbridge/src/VBridge.ts b/packages/vbridge/src/VBridge.ts index 0c9b1e0c6..6069c229d 100644 --- a/packages/vbridge/src/VBridge.ts +++ b/packages/vbridge/src/VBridge.ts @@ -5,7 +5,7 @@ import { PoseidonT3__factory } from "@webb-tools/contracts"; import Verifier from "./Verifier"; import { AnchorIdentifier, IAnchor } from "@webb-tools/interfaces"; import { AnchorHandler, VAnchor } from "@webb-tools/anchors"; -import { Utxo } from "@webb-tools/utils"; +import { getChainIdType, Utxo } from "@webb-tools/utils"; // Deployer config matches the chainId to the signer for that chain export type DeployerConfig = Record; @@ -72,10 +72,6 @@ export class VBridge { } public static createVAnchorIdentifier(vAnchorString: string): AnchorIdentifier | null { - // const identifyingInfo = anchorString.split('-'); - // if (identifyingInfo.length != 2) { - // return null; - // } return { chainId: Number(vAnchorString) } @@ -117,8 +113,6 @@ export class VBridge { // Create the bridgeSide vBridgeInstance = await SignatureBridgeSide.createBridgeSide( adminAddress, - 0, - 100, deployers[chainID], ); @@ -198,7 +192,7 @@ export class VBridge { chainGroupedVAnchors.push(vAnchorInstance); vAnchors.set( - VBridge.createVAnchorIdString({chainId: chainID}), + VBridge.createVAnchorIdString({ chainId: chainID }), vAnchorInstance ); @@ -256,7 +250,7 @@ export class VBridge { // update the sides for (let vAnchor of vAnchorsToUpdate) { // get the bridge side which corresponds to this anchor - const chainId = await vAnchor.signer.getChainId(); + const chainId = getChainIdType(await vAnchor.signer.getChainId()); const resourceID = await vAnchor.createResourceId(); const vBridgeSide = this.vBridgeSides.get(chainId); await vBridgeSide!.executeAnchorProposalWithSig(srcAnchor, resourceID); @@ -276,8 +270,8 @@ export class VBridge { } public getVAnchor(chainId: number) { - let intendedAnchor: IAnchor | undefined = undefined; - intendedAnchor = this.vAnchors.get(VBridge.createVAnchorIdString({chainId})); + let intendedAnchor: IAnchor = undefined; + intendedAnchor = this.vAnchors.get(VBridge.createVAnchorIdString({ chainId })); return intendedAnchor; } @@ -295,14 +289,14 @@ export class VBridge { } public async transact( - inputs:Utxo[], - outputs:Utxo[], + inputs: Utxo[], + outputs: Utxo[], fee: BigNumberish, recipient: string, relayer: string, signer:ethers.Signer - ) { - const chainId = await signer.getChainId(); + ) { + const chainId = getChainIdType(await signer.getChainId()); const signerAddress = await signer.getAddress(); const vAnchor = this.getVAnchor(chainId); if (!vAnchor) { @@ -311,11 +305,13 @@ export class VBridge { vAnchor.setSigner(signer); while (inputs.length !== 2 && inputs.length < 16) { - inputs.push(new Utxo({chainId: BigNumber.from(await signer.getChainId())})); + inputs.push(new Utxo({ + chainId: BigNumber.from(chainId) + })); } - + //do we have to check if amount is greater than 0 before the checks????? - //Check that input dest chain is this chain + // Check that input dest chain is this chain for (let i=0; i this.getVAnchor(Number(x.originChainId))!.getMerkleProof(x)); //console.log((await tokenInstance.getBalance(signerAddress)).toString()); await vAnchor.bridgedTransact(inputs, outputs, fee, recipient, relayer, merkleProof); @@ -367,7 +363,7 @@ export class VBridge { signer:ethers.Signer ) { - const chainId = await signer.getChainId(); + const chainId = getChainIdType(await signer.getChainId()); const signerAddress = await signer.getAddress(); const vAnchor = this.getVAnchor(chainId); if (!vAnchor) { @@ -376,7 +372,9 @@ export class VBridge { vAnchor.setSigner(signer); while (inputs.length !== 2 && inputs.length < 16) { - inputs.push(new Utxo({chainId: BigNumber.from(await signer.getChainId())})); + inputs.push(new Utxo({ + chainId: BigNumber.from(chainId) + })); } //console.log(inputs.length); //do we have to check if amount is greater than 0 before the checks????? diff --git a/test/anchor/anchor.test.ts b/test/anchor/anchor.test.ts index 345926a2d..e8d8d8091 100644 --- a/test/anchor/anchor.test.ts +++ b/test/anchor/anchor.test.ts @@ -22,10 +22,10 @@ import { } from '../../typechain'; // Convenience wrapper classes for contract classes -import { Verifier } from '@webb-tools/bridges'; -import { Anchor } from '@webb-tools/anchors'; -import { MerkleTree } from '@webb-tools/merkle-tree'; -import { fetchComponentsFromFilePaths, ZkComponents, toFixedHex } from '@webb-tools/utils'; +import { Verifier } from '../../packages/bridges/src'; +import { Anchor } from '../../packages/anchors/src'; +import { MerkleTree } from '../../packages/merkle-tree/src'; +import { fetchComponentsFromFilePaths, ZkComponents, toFixedHex } from '../../packages/utils/src'; const { NATIVE_AMOUNT } = process.env const snarkjs = require('snarkjs') diff --git a/test/anchor/anchorProxy.test.ts b/test/anchor/anchorProxy.test.ts index f496b57b8..6f4d20e99 100644 --- a/test/anchor/anchorProxy.test.ts +++ b/test/anchor/anchorProxy.test.ts @@ -21,10 +21,10 @@ import { } from '../../typechain'; // Convenience wrapper classes for contract classes -import { Verifier } from '@webb-tools/bridges' -import { fetchComponentsFromFilePaths, ZkComponents, toFixedHex } from '@webb-tools/utils'; -import { Anchor, AnchorProxy } from '@webb-tools/anchors'; -import { MerkleTree } from '@webb-tools/merkle-tree'; +import { Verifier } from '../../packages/bridges/src' +import { fetchComponentsFromFilePaths, ZkComponents, toFixedHex } from '../../packages/utils/src'; +import { Anchor, AnchorProxy } from '../../packages/anchors/src'; +import { MerkleTree } from '../../packages/merkle-tree/src'; const { NATIVE_AMOUNT } = process.env const snarkjs = require('snarkjs') diff --git a/test/bridge/signatureBridge.test.ts b/test/bridge/signatureBridge.test.ts index 92f04c580..d724a174d 100644 --- a/test/bridge/signatureBridge.test.ts +++ b/test/bridge/signatureBridge.test.ts @@ -9,11 +9,11 @@ import { ethers, network } from 'hardhat'; const path = require('path'); // Convenience wrapper classes for contract classes -import { Anchor } from '@webb-tools/anchors'; -import { SignatureBridge } from '@webb-tools/bridges'; -import { BridgeInput } from '@webb-tools/interfaces'; -import { MintableToken } from '@webb-tools/tokens'; -import { fetchComponentsFromFilePaths, getChainIdType, ZkComponents } from '@webb-tools/utils'; +import { Anchor } from '../../packages/anchors/src'; +import { SignatureBridge } from '../../packages/bridges/src'; +import { BridgeInput } from '../../packages/interfaces/src'; +import { MintableToken } from '../../packages/tokens/src'; +import { fetchComponentsFromFilePaths, getChainIdType, ZkComponents } from '../../packages/utils/src'; import { BigNumber } from '@ethersproject/bignumber'; import { Signer } from 'ethers'; import { startGanacheServer } from '../helpers/startGanacheServer'; @@ -24,6 +24,7 @@ describe('multichain tests for erc20 bridges', () => { const chainID1 = getChainIdType(31337); const chainID2 = getChainIdType(1337); const chainID3 = getChainIdType(9999); + const chainID4 = getChainIdType(4444) // setup ganache networks let ganacheServer2: any; let ganacheServer3: any; @@ -84,7 +85,7 @@ describe('multichain tests for erc20 bridges', () => { await tokenInstance1.mintTokens(signers[1].address, '100000000000000000000000000'); }); - it.only('create 2 side bridge for one token', async () => { + it('create 2 side bridge for one token', async () => { bridge2WebbEthInput = { anchorInputs: { asset: { @@ -139,7 +140,7 @@ describe('multichain tests for erc20 bridges', () => { assert.deepEqual(webbTokenBalance2, ethers.BigNumber.from(anchorSize)); }); - it.only('create 3 side bridge for one token', async () => { + it('create 3 side bridge for one token', async () => { bridge3WebbEthInput = { anchorInputs: { asset: { @@ -190,33 +191,7 @@ describe('multichain tests for erc20 bridges', () => { assert.deepStrictEqual(destAnchorEdge2After.latestLeafIndex, destAnchorEdge3After.latestLeafIndex); assert.deepStrictEqual(destAnchorEdge2After.root, destAnchorEdge3After.root); }).timeout(40000); - - it.only('create 2 side bridge for multiple tokens', async () => { - bridge2WebbEthInput = { - anchorInputs: { - asset: { - [chainID1]: [tokenInstance1.contract.address], - [chainID2]: [tokenInstance2.contract.address], - }, - anchorSizes: ['1000000000000000000', '100000000000000000000', '10000000000000000000000'], - }, - chainIDs: [chainID1, chainID2] - }; - }); - - it.only('create 2 side bridge for native and erc20 token', async () => { - bridge2WebbEthInput = { - anchorInputs: { - asset: { - [chainID1]: [tokenInstance1.contract.address, '0'], - [chainID2]: [tokenInstance2.contract.address, '0x0000000000000000000000000000000000000000'], - }, - anchorSizes: ['1000000000000000000', '100000000000000000000', '10000000000000000000000'], - }, - chainIDs: [chainID1, chainID2] - }; - }); - }).timeout(50000); + }); describe('2 sided bridge existing token use', () => { @@ -271,7 +246,7 @@ describe('multichain tests for erc20 bridges', () => { }) describe('#bridging', () => { - it.only('should withdraw successfully from latest deposit', async () => { + it('should withdraw successfully from latest deposit', async () => { // Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); const anchorSize = '1000000000000000000'; @@ -309,7 +284,7 @@ describe('multichain tests for erc20 bridges', () => { assert.deepEqual(endingBalanceDest, startingBalanceDest.add(anchorSize)); }) - it.only('should withdraw on hardhat from ganache deposit', async () => { + it('should withdraw on hardhat from ganache deposit', async () => { // Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); const anchorSize = '1000000000000000000'; @@ -335,7 +310,7 @@ describe('multichain tests for erc20 bridges', () => { assert.deepStrictEqual(endingBalanceDest, startingBalanceDest.add(anchorSize)); }) - it.only('should update multiple deposits and withdraw historic deposit', async () => { + it('should update multiple deposits and withdraw historic deposit', async () => { // Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); const anchorSize = '1000000000000000000'; @@ -362,7 +337,7 @@ describe('multichain tests for erc20 bridges', () => { assert.deepStrictEqual(endingBalanceDest, startingBalanceDest.add(anchorSize)); }); - it.only('should update multiple deposits and withdraw historic deposit from ganache', async () => { + it('should update multiple deposits and withdraw historic deposit from ganache', async () => { // Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); const anchorSize = '1000000000000000000'; @@ -399,7 +374,6 @@ describe('multichain tests for erc20 bridges', () => { let existingTokenSrc4: MintableToken; let bridge: SignatureBridge; - const chainId4 = 4444; let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); ganacheProvider2.pollingInterval = 1; let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); @@ -433,11 +407,11 @@ describe('multichain tests for erc20 bridges', () => { [chainID1]: [existingTokenSrc.contract.address], [chainID2]: [existingTokenSrc2.contract.address], [chainID3]: [existingTokenSrc3.contract.address], - [chainId4]: [existingTokenSrc4.contract.address], + [chainID4]: [existingTokenSrc4.contract.address], }, anchorSizes: ['1000000000000000000', '100000000000000000000'], }, - chainIDs: [chainID1, chainID2, chainID3, chainId4] + chainIDs: [chainID1, chainID2, chainID3, chainID4] }; // setup the config for deployers of contracts (admins) @@ -445,7 +419,7 @@ describe('multichain tests for erc20 bridges', () => { [chainID1]: signers[1], [chainID2]: ganacheWallet2, [chainID3]: ganacheWallet3, - [chainId4]: ganacheWallet4, + [chainID4]: ganacheWallet4, } // deploy the bridge @@ -466,13 +440,13 @@ describe('multichain tests for erc20 bridges', () => { } }) - it.only('should withdraw successfully from latest deposits on all chains', async () => { + it('should withdraw successfully from latest deposits on all chains', async () => { const signers = await ethers.getSigners(); // make deposits so edges exists await bridge.wrapAndDeposit(chainID2, existingTokenSrc.contract.address, '1000000000000000000', signers[1]); await bridge.wrapAndDeposit(chainID3, existingTokenSrc2.contract.address, '1000000000000000000', ganacheWallet2); - await bridge.wrapAndDeposit(chainId4, existingTokenSrc3.contract.address, '1000000000000000000', ganacheWallet3); + await bridge.wrapAndDeposit(chainID4, existingTokenSrc3.contract.address, '1000000000000000000', ganacheWallet3); await bridge.wrapAndDeposit(chainID1, existingTokenSrc4.contract.address, '1000000000000000000', ganacheWallet4); // Fetch information about the anchor to be updated. @@ -520,7 +494,7 @@ describe('multichain tests for erc20 bridges', () => { currentBalance = cumulativeBalance; // make a deposit from the fourth connected chain - edgeIndex = await anchor1.contract.edgeIndex(chainId4); + edgeIndex = await anchor1.contract.edgeIndex(chainID4); const destAnchorEdge4Before = await anchor1.contract.edgeList(edgeIndex); const depositNote4 = await bridge.wrapAndDeposit(chainID1, existingTokenSrc4.contract.address, anchorSize, ganacheWallet4); diff --git a/test/bridge/signatureBridgeSide.test.ts b/test/bridge/signatureBridgeSide.test.ts index 239c9a01c..0609f233f 100644 --- a/test/bridge/signatureBridgeSide.test.ts +++ b/test/bridge/signatureBridgeSide.test.ts @@ -8,12 +8,12 @@ const TruffleAssert = require('truffle-assertions'); // Convenience wrapper classes for contract classes - import { Verifier, SignatureBridgeSide } from '@webb-tools/bridges'; - import { Anchor, AnchorHandler } from '@webb-tools/anchors'; - import { MintableToken } from '@webb-tools/tokens'; - import { fetchComponentsFromFilePaths, ZkComponents } from '@webb-tools/utils'; - import { PoseidonT3__factory } from '@webb-tools/contracts'; - import { GovernedTokenWrapper, TokenWrapperHandler } from '@webb-tools/tokens'; + import { Verifier, SignatureBridgeSide } from '../../packages/bridges/src'; + import { Anchor, AnchorHandler } from '../../packages/anchors/src'; + import { MintableToken } from '../../packages/tokens/src'; + import { fetchComponentsFromFilePaths, ZkComponents } from '../../packages/utils/src'; + import { PoseidonT3__factory } from '../../packages/contracts'; + import { GovernedTokenWrapper, TokenWrapperHandler } from '../../packages/tokens/src'; describe('SignatureBridgeSideConstruction', () => { @@ -31,14 +31,14 @@ const signers = await ethers.getSigners(); const initialGovernor = signers[1]; const admin = signers[1]; - const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, 0, 100, admin); + const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, admin); }) it('should set resource with signature', async () => { const signers = await ethers.getSigners(); const initialGovernor = signers[1]; const admin = signers[1]; - const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, 0, 100, admin); + const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, admin); // Create the Hasher and Verifier for the chain const hasherFactory = new PoseidonT3__factory(admin); @@ -77,7 +77,7 @@ const signers = await ethers.getSigners(); const initialGovernor = signers[1]; const admin = signers[1]; - const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, 0, 100, admin); + const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, admin); // Create the Hasher and Verifier for the chain const hasherFactory = new PoseidonT3__factory(admin); @@ -129,7 +129,7 @@ const signers = await ethers.getSigners(); const initialGovernor = signers[1]; const admin = signers[1]; - const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, 0, 100, admin); + const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, admin); //Deploy TokenWrapperHandler const tokenWrapperHandler = await TokenWrapperHandler.createTokenWrapperHandler(bridgeSide.contract.address, [], [], admin); @@ -158,7 +158,7 @@ const signers = await ethers.getSigners(); const initialGovernor = signers[1]; const admin = signers[1]; - const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, 0, 100, admin); + const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, admin); //Deploy TokenWrapperHandler const tokenWrapperHandler = await TokenWrapperHandler.createTokenWrapperHandler(bridgeSide.contract.address, [], [], admin); @@ -190,7 +190,7 @@ const signers = await ethers.getSigners(); const initialGovernor = signers[1]; const admin = signers[1]; - const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, 0, 100, admin); + const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, admin); //Deploy TokenWrapperHandler const tokenWrapperHandler = await TokenWrapperHandler.createTokenWrapperHandler(bridgeSide.contract.address, [], [], admin); @@ -225,7 +225,7 @@ const signers = await ethers.getSigners(); const initialGovernor = signers[1]; const admin = signers[1]; - const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, 0, 100, admin); + const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, admin); //Deploy TokenWrapperHandler const tokenWrapperHandler = await TokenWrapperHandler.createTokenWrapperHandler(bridgeSide.contract.address, [], [], admin); @@ -270,7 +270,7 @@ const signers = await ethers.getSigners(); const initialGovernor = signers[1]; const admin = signers[1]; - const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, 0, 100, admin); + const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, admin); //Deploy TokenWrapperHandler const tokenWrapperHandler = await TokenWrapperHandler.createTokenWrapperHandler(bridgeSide.contract.address, [], [], admin); @@ -322,7 +322,7 @@ assert.strictEqual((await governedToken.contract.proposalNonce()).toString(), '2 const signers = await ethers.getSigners(); const initialGovernor = signers[1]; const admin = signers[1]; - const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, 0, 100, admin); + const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor.address, admin); // Create the Hasher and Verifier for the chain const hasherFactory = new PoseidonT3__factory(admin); diff --git a/test/governance/governable.test.ts b/test/governance/governable.test.ts index c5a953b46..3615ba734 100644 --- a/test/governance/governable.test.ts +++ b/test/governance/governable.test.ts @@ -5,7 +5,7 @@ const assert = require('assert'); const path = require('path'); import { ethers } from 'hardhat'; - import { toHex } from '@webb-tools/utils'; + import { toHex } from '../../packages/utils/src'; const TruffleAssert = require('truffle-assertions'); // Convenience wrapper classes for contract classes diff --git a/test/helpers/startGanacheServer.ts b/test/helpers/startGanacheServer.ts index b95a60f36..83cf68d6a 100644 --- a/test/helpers/startGanacheServer.ts +++ b/test/helpers/startGanacheServer.ts @@ -12,6 +12,5 @@ export async function startGanacheServer(port: number, networkId: number, mnemon await ganacheServer.listen(port); //console.log(`Ganache Started on http://127.0.0.1:${port} ..`); - return ganacheServer; } diff --git a/test/merkleTree/MerkleTreePoseidon.test.ts b/test/merkleTree/MerkleTreePoseidon.test.ts index dbbf1c3d2..c86ea88f3 100644 --- a/test/merkleTree/MerkleTreePoseidon.test.ts +++ b/test/merkleTree/MerkleTreePoseidon.test.ts @@ -3,8 +3,8 @@ * SPDX-License-Identifier: GPL-3.0-or-later-only */ -import { MerkleTree } from '@webb-tools/merkle-tree'; -import { PoseidonHasher } from '@webb-tools/utils'; +import { MerkleTree } from '../../packages/merkle-tree/src'; +import { PoseidonHasher } from '../../packages/utils/src'; import { artifacts, contract } from 'hardhat'; const TruffleAssert = require('truffle-assertions'); const helpers = require('../helpers'); diff --git a/test/token/GovernedTokenWrapper.test.ts b/test/token/GovernedTokenWrapper.test.ts index befcd302a..30b496aa5 100644 --- a/test/token/GovernedTokenWrapper.test.ts +++ b/test/token/GovernedTokenWrapper.test.ts @@ -7,7 +7,7 @@ import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { ethers } from 'hardhat'; // Convenience wrapper classes for contract classes -import { ERC20 as ERC20Class, GovernedTokenWrapper as GovernedTokenWrapperClass } from '@webb-tools/tokens'; +import { ERC20 as ERC20Class, GovernedTokenWrapper as GovernedTokenWrapperClass } from '../../packages/tokens/src'; describe('GovernedTokenWrapper', () => { let token: ERC20Class; diff --git a/test/vanchor/vanchor.test.ts b/test/vanchor/vanchor.test.ts index b04ae0ee3..ca455077f 100644 --- a/test/vanchor/vanchor.test.ts +++ b/test/vanchor/vanchor.test.ts @@ -12,7 +12,7 @@ import { GovernedTokenWrapper as WrappedToken, GovernedTokenWrapper__factory as WrappedTokenFactory, PoseidonT3__factory -} from '@webb-tools/contracts'; +} from '../../packages/contracts'; // These contracts are not included in the package, so can use generated typechain import { @@ -21,14 +21,14 @@ import { } from '../../typechain'; // Convenience wrapper classes for contract classes -import { toFixedHex } from '@webb-tools/utils'; +import { getChainIdType, toFixedHex } from '../../packages/utils/src'; import { BigNumber } from 'ethers'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; -import { MerkleTree } from '@webb-tools/merkle-tree'; -import { Utxo, poseidonHash, poseidonHash2 } from '@webb-tools/utils'; -import { VAnchor } from '@webb-tools/anchors'; -import { Verifier } from "@webb-tools/vbridge" +import { MerkleTree } from '../../packages/merkle-tree/src'; +import { Utxo, poseidonHash, poseidonHash2 } from '../../packages/utils/src'; +import { VAnchor } from '../../packages/anchors/src'; +import { Verifier } from "../../packages/vbridge" const { NATIVE_AMOUNT } = process.env const BN = require('bn.js'); @@ -40,17 +40,15 @@ describe('VAnchor for 2 max edges', () => { let anchor: VAnchor; const levels = 5; - const value = NATIVE_AMOUNT || '1000000000000000000' // 1 ether let tree: MerkleTree; let fee = BigInt((new BN(`${NATIVE_AMOUNT}`).shrn(1)).toString()) || BigInt((new BN(`${1e17}`)).toString()); - const refund = BigInt((new BN('0')).toString()); let recipient = "0x1111111111111111111111111111111111111111"; let verifier: Verifier; let hasherInstance: any; let token: Token; let wrappedToken: WrappedToken; let tokenDenomination = '1000000000000000000' // 1 ether - const chainID = 31337; + const chainID = getChainIdType(31337); const MAX_EDGES = 1; let create2InputWitness: any; let create16InputWitness: any; @@ -121,14 +119,14 @@ describe('VAnchor for 2 max edges', () => { }) describe('#constructor', () => { - it('should initialize', async () => { + it'should initialize', async () => { const maxEdges = await anchor.contract.maxEdges(); assert.strictEqual(maxEdges.toString(), `${MAX_EDGES}`); }); }); describe('snark proof native verification on js side', () => { - it('should work', async () => { + it'should work', async () => { const relayer = "0x2111111111111111111111111111111111111111"; const extAmount = 1e7; const isL1Withdrawal = false; @@ -170,7 +168,7 @@ describe('VAnchor for 2 max edges', () => { }); - it('poseidon4 isolated gadget test', async () => { + it'poseidon4 isolated gadget test', async () => { const relayer = "0x2111111111111111111111111111111111111111"; const extAmount = 1e7; const isL1Withdrawal = false; @@ -189,11 +187,11 @@ describe('VAnchor for 2 max edges', () => { // const input = await anchor.generateWitnessInputPoseidon4( // ); - const output = new Utxo({chainId: BigNumber.from(31337), amount: BigNumber.from(0), + const output = new Utxo({chainId: BigNumber.from(chainID), amount: BigNumber.from(0), blinding: BigNumber.from(13)}) const input = { // data for 2 transaction outputs - outChainID: 31337, + outChainID: chainID, outAmount: 0, outPubkey: output.keypair.pubkey, outBlinding: toFixedHex(13), @@ -205,7 +203,7 @@ describe('VAnchor for 2 max edges', () => { }) describe ('Setting Handler/Verifier Address Negative Tests', () => { - it('should revert (setting handler) with improper nonce', async() => { + it'should revert (setting handler) with improper nonce', async() => { const signers = await ethers.getSigners(); await TruffleAssert.reverts( anchor.contract.setHandler(signers[1].address, 0), @@ -217,7 +215,7 @@ describe('VAnchor for 2 max edges', () => { ) }); - it('should revert (setting verifier) with improper nonce', async() => { + it'should revert (setting verifier) with improper nonce', async() => { const signers = await ethers.getSigners(); await TruffleAssert.reverts( anchor.contract.setVerifier(signers[1].address, 0), @@ -231,7 +229,7 @@ describe('VAnchor for 2 max edges', () => { }) describe('#transact', () => { - it('should transact', async () => { + it'should transact', async () => { // Alice deposits into tornado pool const aliceDepositAmount = 1e7; const aliceDepositUtxo = new Utxo({ @@ -248,7 +246,7 @@ describe('VAnchor for 2 max edges', () => { ); }) - it('should process fee on deposit', async () => { + it'should process fee on deposit', async () => { const signers = await ethers.getSigners(); const alice= signers[0]; @@ -280,7 +278,7 @@ describe('VAnchor for 2 max edges', () => { assert.strictEqual((await token.balanceOf(relayer)).toString(), BigNumber.from(fee).toString()); }) - it('should spend input utxo and create output utxo', async () => { + it'should spend input utxo and create output utxo', async () => { // Alice deposits into tornado pool const aliceDepositAmount = 1e7; const aliceDepositUtxo = new Utxo({ @@ -309,7 +307,7 @@ describe('VAnchor for 2 max edges', () => { ); }) - it('should spend input utxo and split', async () => { + it'should spend input utxo and split', async () => { // Alice deposits into tornado pool const aliceDepositAmount = 10; const aliceDepositUtxo = new Utxo({ @@ -344,7 +342,7 @@ describe('VAnchor for 2 max edges', () => { ); }) - it('should join and spend', async () => { + it'should join and spend', async () => { const aliceDepositAmount1 = 1e7; const aliceDepositUtxo1 = new Utxo({ chainId: BigNumber.from(chainID), @@ -386,7 +384,7 @@ describe('VAnchor for 2 max edges', () => { ); }) - it('should join and spend with 16 inputs', async () => { + it'should join and spend with 16 inputs', async () => { const aliceDepositAmount1 = 1e7; const aliceDepositUtxo1 = new Utxo({ chainId: BigNumber.from(chainID), @@ -442,7 +440,7 @@ describe('VAnchor for 2 max edges', () => { ); }).timeout(40000); - it('should withdraw', async () => { + it'should withdraw', async () => { const aliceDepositAmount = 1e7; const aliceDepositUtxo = new Utxo({ chainId: BigNumber.from(chainID), @@ -475,7 +473,7 @@ describe('VAnchor for 2 max edges', () => { assert.strictEqual(aliceWithdrawAmount.toString(), await (await token.balanceOf(aliceETHAddress)).toString()); }).timeout(40000); - it('should prevent double spend', async () => { + it'should prevent double spend', async () => { const aliceDepositAmount = 1e7; const aliceDepositUtxo = new Utxo({ chainId: BigNumber.from(chainID), @@ -512,7 +510,7 @@ describe('VAnchor for 2 max edges', () => { ) }); - it('should prevent increasing UTXO amount without depositing', async () => { + it'should prevent increasing UTXO amount without depositing', async () => { const signers = await ethers.getSigners(); const alice= signers[0]; @@ -554,7 +552,7 @@ describe('VAnchor for 2 max edges', () => { ) }); - it('should reject tampering with public inputs', async () => { + it'should reject tampering with public inputs', async () => { const relayer = "0x2111111111111111111111111111111111111111"; const extAmount = 1e7; const isL1Withdrawal = false; @@ -737,7 +735,7 @@ describe('VAnchor for 2 max edges', () => { ); }); - it('should be compliant', async function () { + it'should be compliant', async function () { // basically verifier should check if a commitment and a nullifier hash are on chain const [sender] = await ethers.getSigners(); @@ -778,7 +776,7 @@ describe('VAnchor for 2 max edges', () => { // nullifier = hash(commitment, merklePath, sign(merklePath, privKey)) const dataForVerifier = { commitment: { - chainId: 31337, + chainId: chainID, amount: aliceDepositUtxo.amount, pubkey: aliceDepositUtxo.keypair.pubkey, blinding: aliceDepositUtxo.blinding, @@ -809,7 +807,7 @@ describe('VAnchor for 2 max edges', () => { }) }) describe('#wrapping tests', () => { - it('should wrap and deposit', async () => { + it'should wrap and deposit', async () => { const signers = await ethers.getSigners(); const wallet = signers[0]; const sender = wallet; @@ -866,7 +864,7 @@ describe('VAnchor for 2 max edges', () => { assert.strictEqual(balWrappedTokenAfterDepositSender.toString(), '0'); }); - it('should withdraw and unwrap', async () => { + it'should withdraw and unwrap', async () => { const signers = await ethers.getSigners(); const wallet = signers[0]; const sender = wallet; @@ -936,7 +934,7 @@ describe('VAnchor for 2 max edges', () => { assert.strictEqual(balTokenBeforeDepositSender.toString(), balTokenAfterWithdrawAndUnwrapSender.toString()); }); - it('wrapping fee should work correctly with transactWrap', async () => { + it'wrapping fee should work correctly with transactWrap', async () => { const signers = await ethers.getSigners(); const wallet = signers[0]; const sender = wallet; @@ -1020,7 +1018,7 @@ describe('VAnchor for 2 max edges', () => { assert.strictEqual(balUnwrappedTokenAfterDepositWrapper.sub(balUnwrappedTokenAfterWithdrawWrapper).toString(), BigNumber.from(1e7).toString()); }); - it('non-governor setting fee should fail', async () => { + it'non-governor setting fee should fail', async () => { const signers = await ethers.getSigners(); const wallet = signers[0]; const sender = wallet; @@ -1040,7 +1038,7 @@ describe('VAnchor for 2 max edges', () => { ); }); - it('fee percentage cannot be greater than 100', async () => { + it'fee percentage cannot be greater than 100', async () => { const signers = await ethers.getSigners(); const wallet = signers[0]; const sender = wallet; @@ -1059,7 +1057,7 @@ describe('VAnchor for 2 max edges', () => { ); }); - it('fee percentage cannot be negative', async () => { + it'fee percentage cannot be negative', async () => { const signers = await ethers.getSigners(); const wallet = signers[0]; const sender = wallet; @@ -1077,7 +1075,7 @@ describe('VAnchor for 2 max edges', () => { ); }); - it('fee percentage cannot be non-integer', async () => { + it'fee percentage cannot be non-integer', async () => { const signers = await ethers.getSigners(); const wallet = signers[0]; const sender = wallet; diff --git a/test/vbridge/signatureVBridge.test.ts b/test/vbridge/signatureVBridge.test.ts index 378168413..62b2465ef 100644 --- a/test/vbridge/signatureVBridge.test.ts +++ b/test/vbridge/signatureVBridge.test.ts @@ -7,17 +7,20 @@ const assert = require('assert'); import { ethers } from 'hardhat'; // Convenience wrapper classes for contract classes -import { VBridge, VBridgeInput } from '@webb-tools/vbridge'; -import { VAnchor } from '@webb-tools/anchors'; -import { MintableToken, GovernedTokenWrapper } from '@webb-tools/tokens'; +import { VBridge, VBridgeInput } from '../../packages/vbridge/src'; +import { VAnchor } from '../../packages/anchors/src'; +import { MintableToken, GovernedTokenWrapper } from '../../packages/tokens/src'; import { BigNumber } from 'ethers'; -import { Utxo } from '@webb-tools/utils'; +import { getChainIdType, Utxo } from '../../packages/utils/src'; import { startGanacheServer } from '../helpers/startGanacheServer'; export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); describe('multichain tests for signature vbridge', () => { - + const chainID1 = getChainIdType(31337); + const chainID2 = getChainIdType(1337); + const chainID3 = getChainIdType(9999); + const chainID4 = getChainIdType(4444); // setup ganache networks let ganacheServer2: any; let ganacheServer3: any; @@ -27,11 +30,9 @@ describe('multichain tests for signature vbridge', () => { ganacheServer2 = await startGanacheServer(1337, 1337, 'congress island collect purity dentist team gas unlock nuclear pig combine sight'); ganacheServer3 = await startGanacheServer(9999, 9999, 'aspect biology suit thought bottom popular custom rebuild recall sauce endless local'); ganacheServer4 = await startGanacheServer(4444, 4444, 'harvest useful giraffe swim rail ostrich public awful provide amazing tank weapon'); - await sleep(2000); }); describe('BridgeConstruction', () => { - let bridge2WebbEthInput: VBridgeInput; let bridge3WebbEthInput: VBridgeInput; let tokenName: string = 'existingERC20'; @@ -50,6 +51,8 @@ describe('multichain tests for signature vbridge', () => { before('construction-tests', async () => { const signers = await ethers.getSigners(); + await ganacheProvider2.ready; + // Create a token to test bridge construction support for existing tokens tokenInstance1 = await MintableToken.createToken(tokenName, tokenAbbreviation, signers[7]); tokenInstance2 = await MintableToken.createToken(tokenName, tokenAbbreviation, ganacheWallet2); @@ -58,45 +61,47 @@ describe('multichain tests for signature vbridge', () => { await tokenInstance1.mintTokens(signers[2].address, '100000000000000000000000000'); }); - it('create 2 side bridge for one token', async () => { + it.only('create 2 side bridge for one token', async () => { let webbTokens1 = new Map(); - webbTokens1.set(31337, null!); - webbTokens1.set(1337, null!); + webbTokens1.set(chainID1, null!); + webbTokens1.set(chainID2, null!); bridge2WebbEthInput = { vAnchorInputs: { asset: { - 31337: [tokenInstance1.contract.address], - 1337: [tokenInstance2.contract.address], + [chainID1]: [tokenInstance1.contract.address], + [chainID2]: [tokenInstance2.contract.address], } }, - chainIDs: [31337, 1337], + chainIDs: [chainID1, chainID2], webbTokens: webbTokens1 }; const signers = await ethers.getSigners(); const deploymentConfig = { - 31337: signers[1], - 1337: ganacheWallet2, + [chainID1]: signers[1], + [chainID2]: ganacheWallet2, }; const vBridge = await VBridge.deployVariableAnchorBridge(bridge2WebbEthInput, deploymentConfig); // Should be able to retrieve individual anchors - const chainId1 = 31337; - const chainId2 = 1337; - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; - const vAnchor2: VAnchor = vBridge.getVAnchor(chainId2)! as VAnchor; + const vAnchor1: VAnchor = vBridge.getVAnchor(chainID1)! as VAnchor; + const vAnchor2: VAnchor = vBridge.getVAnchor(chainID2)! as VAnchor; // Should be able to retrieve the token address (so we can mint tokens for test scenario) - const webbTokenAddress = vBridge.getWebbTokenAddress(chainId1); + const webbTokenAddress = vBridge.getWebbTokenAddress(chainID1); const webbToken = await MintableToken.tokenFromAddress(webbTokenAddress!, signers[1]); const tx = await webbToken.mintTokens(signers[2].address, '100000000000000000000000'); - // get the state of anchors before deposit + // Get the state of anchors before deposit const sourceAnchorRootBefore = await vAnchor1.contract.getLastRoot(); //console.log(sourceAnchorRootBefore); - //Define inputs/outputs for transact function - const depositUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}) - //Transact on the bridge + // Define inputs/outputs for transact function + const depositUtxo = new Utxo({ + amount: BigNumber.from(1e7), + originChainId: BigNumber.from(chainID1), + chainId: BigNumber.from(chainID1) + }); + // Transact on the bridge await vBridge.transact([], [depositUtxo], 0, '0', '0', signers[2]); // Check the state of anchors after deposit - let edgeIndex = await vAnchor2.contract.edgeIndex(chainId1); + let edgeIndex = await vAnchor2.contract.edgeIndex(chainID1); const sourceAnchorRootAfter = await vAnchor1.contract.getLastRoot(); const destAnchorEdgeAfter = await vAnchor2.contract.edgeList(edgeIndex); @@ -106,7 +111,7 @@ describe('multichain tests for signature vbridge', () => { assert.deepEqual(ethers.BigNumber.from(1), destAnchorEdgeAfter.latestLeafIndex); const transferUtxo = new Utxo({ - originChainId: BigNumber.from(chainId1), + originChainId: BigNumber.from(chainID1), amount: BigNumber.from(1e7), keypair: depositUtxo.keypair }); @@ -116,14 +121,11 @@ describe('multichain tests for signature vbridge', () => { }); describe('2 sided bridge existing token use', () => { - // ERC20 compliant contracts that can easily create balances for test let existingToken1: MintableToken; let existingToken2: MintableToken; let vBridge: VBridge; - const chainId1 = 31337; - const chainId2 = 1337; let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); ganacheProvider2.pollingInterval = 1; let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); @@ -143,39 +145,39 @@ describe('multichain tests for signature vbridge', () => { beforeEach(async () => { const signers = await ethers.getSigners(); let webbTokens1 = new Map(); - webbTokens1.set(31337, null!); - webbTokens1.set(1337, null!); + webbTokens1.set(chainID1, null!); + webbTokens1.set(chainID2, null!); // create the config for the bridge const vBridgeInput = { vAnchorInputs: { asset: { - 31337: [existingToken1.contract.address], - 1337: [existingToken2.contract.address], + [chainID1]: [existingToken1.contract.address], + [chainID2]: [existingToken2.contract.address], } }, - chainIDs: [31337, 1337], + chainIDs: [chainID1, chainID2], webbTokens: webbTokens1 } // setup the config for deployers of contracts (admins) const deploymentConfig = { - [chainId1]: signers[1], - [chainId2]: ganacheWallet2, + [chainID1]: signers[1], + [chainID2]: ganacheWallet2, } // deploy the bridge vBridge = await VBridge.deployVariableAnchorBridge(vBridgeInput, deploymentConfig); // make one deposit so the edge exists - const depositUtxo1 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId2)}) - const depositUtxo2 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}) + const depositUtxo1 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainID1), chainId: BigNumber.from(chainID2)}) + const depositUtxo2 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainID2), chainId: BigNumber.from(chainID1)}) // Should be able to retrieve the token address (so we can mint tokens for test scenario) - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); + const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainID1); const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); const tx1 = await webbToken1.mintTokens(signers[1].address, '100000000000000000000000'); - const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainId2); + const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainID2); const webbToken2 = await MintableToken.tokenFromAddress(webbTokenAddress2!, ganacheWallet2); const tx2 = await webbToken2.mintTokens(ganacheWallet2.address, '100000000000000000000000'); @@ -186,20 +188,20 @@ describe('multichain tests for signature vbridge', () => { }) describe('#bridging', () => { - it('basic ganache deposit should withdraw on hardhat', async () => { + it.only('basic ganache deposit should withdraw on hardhat', async () => { // Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; + const vAnchor1: VAnchor = vBridge.getVAnchor(chainID1)! as VAnchor; const vAnchor1Address = vAnchor1.contract.address; - let edgeIndex = await vAnchor1.contract.edgeIndex(chainId2); + let edgeIndex = await vAnchor1.contract.edgeIndex(chainID2); const destAnchorEdge2Before = await vAnchor1.contract.edgeList(edgeIndex); - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); + const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainID1); const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); const signers2BalanceBefore = await webbToken1.getBalance(await signers[2].getAddress()); - //ganacheWallet2 makes a deposit with dest chain chainId1 - const ganacheDepositUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); + //ganacheWallet2 makes a deposit with dest chain chainID1 + const ganacheDepositUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainID2), chainId: BigNumber.from(chainID1)}); await vBridge.transact([], [ganacheDepositUtxo], 0, '0', '0', ganacheWallet2); @@ -207,26 +209,26 @@ describe('multichain tests for signature vbridge', () => { const destAnchorEdge2After = await vAnchor1.contract.edgeList(edgeIndex); assert.deepStrictEqual(destAnchorEdge2Before.latestLeafIndex.add(2), destAnchorEdge2After.latestLeafIndex); - //withdraw ganacheWallet2 deposit on chainId1 to signers[2] address - const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(5e6), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}) + //withdraw ganacheWallet2 deposit on chainID1 to signers[2] address + const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(5e6), originChainId: BigNumber.from(chainID1), chainId: BigNumber.from(chainID1)}) await vBridge.transact([ganacheDepositUtxo], [hardhatWithdrawUtxo], 0, await signers[2].getAddress(), '0', signers[2]); const signers2BalanceAfter = await webbToken1.getBalance(await signers[2].getAddress()); assert.strictEqual(signers2BalanceBefore.add(5e6).toString(), signers2BalanceAfter.toString()); }).timeout(40000) - it('join and split ganache deposits and withdraw on hardhat', async () => { + it.only('join and split ganache deposits and withdraw on hardhat', async () => { const signers = await ethers.getSigners(); - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; - let edgeIndex = await vAnchor1.contract.edgeIndex(chainId2); + const vAnchor1: VAnchor = vBridge.getVAnchor(chainID1)! as VAnchor; + let edgeIndex = await vAnchor1.contract.edgeIndex(chainID2); const destAnchorEdge2Before = await vAnchor1.contract.edgeList(edgeIndex); - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); + const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainID1); const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); const signers2BalanceBefore = await webbToken1.getBalance(await signers[2].getAddress()); - //ganacheWallet2 makes a deposit with dest chain chainId1 - const ganacheDepositUtxo1 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - const ganacheDepositUtxo2 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1), keypair: ganacheDepositUtxo1.keypair}); + //ganacheWallet2 makes a deposit with dest chain chainID1 + const ganacheDepositUtxo1 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainID2), chainId: BigNumber.from(chainID1)}); + const ganacheDepositUtxo2 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainID2), chainId: BigNumber.from(chainID1), keypair: ganacheDepositUtxo1.keypair}); await vBridge.transact([], [ganacheDepositUtxo1], 0, '0', '0', ganacheWallet2); await vBridge.transact([], [ganacheDepositUtxo2], 0, '0', '0', ganacheWallet2); @@ -235,29 +237,29 @@ describe('multichain tests for signature vbridge', () => { const destAnchorEdge2After = await vAnchor1.contract.edgeList(edgeIndex); assert.deepStrictEqual(destAnchorEdge2Before.latestLeafIndex.add(4), destAnchorEdge2After.latestLeafIndex); - //withdraw ganacheWallet2 deposit on chainId1 to signers[2] address - const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(5e6), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}) + //withdraw ganacheWallet2 deposit on chainID1 to signers[2] address + const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(5e6), originChainId: BigNumber.from(chainID1), chainId: BigNumber.from(chainID1)}) await vBridge.transact([ganacheDepositUtxo1, ganacheDepositUtxo2], [hardhatWithdrawUtxo], 0, await signers[2].getAddress(), '0', signers[2]); const signers2BalanceAfter = await webbToken1.getBalance(await signers[2].getAddress()); assert.strictEqual(signers2BalanceBefore.add(1.5e7).toString(), signers2BalanceAfter.toString()); }) - it('should update multiple deposits and withdraw historic deposit from ganache', async () => { + it.only('should update multiple deposits and withdraw historic deposit from ganache', async () => { // Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; - let edgeIndex = await vAnchor1.contract.edgeIndex(chainId2); + const vAnchor1: VAnchor = vBridge.getVAnchor(chainID1)! as VAnchor; + let edgeIndex = await vAnchor1.contract.edgeIndex(chainID2); const destAnchorEdge2Before = await vAnchor1.contract.edgeList(edgeIndex); - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); + const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainID1); const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); const startingBalanceDest = await webbToken1.getBalance(signers[1].address); - //ganacheWallet2 makes a deposit with dest chain chainId1 - const ganacheDepositUtxo1 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); + //ganacheWallet2 makes a deposit with dest chain chainID1 + const ganacheDepositUtxo1 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainID2), chainId: BigNumber.from(chainID1)}); - const ganacheDepositUtxo2 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); + const ganacheDepositUtxo2 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainID2), chainId: BigNumber.from(chainID1)}); await vBridge.transact([], [ganacheDepositUtxo1], 0, '0', '0', ganacheWallet2); await vBridge.transact([], [ganacheDepositUtxo2], 0, '0', '0', ganacheWallet2); @@ -266,8 +268,8 @@ describe('multichain tests for signature vbridge', () => { const destAnchorEdge2After = await vAnchor1.contract.edgeList(edgeIndex); assert.deepStrictEqual(destAnchorEdge2Before.latestLeafIndex.add(4), destAnchorEdge2After.latestLeafIndex); - //withdraw ganacheWallet2 deposit on chainId1 to signers[2] address - const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(5e6), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}) + //withdraw ganacheWallet2 deposit on chainID1 to signers[2] address + const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(5e6), originChainId: BigNumber.from(chainID1), chainId: BigNumber.from(chainID1)}) await vBridge.transact([ganacheDepositUtxo1], [hardhatWithdrawUtxo], 0, await signers[1].getAddress(), '0', signers[2]); // // Check balances @@ -275,13 +277,13 @@ describe('multichain tests for signature vbridge', () => { assert.deepStrictEqual(endingBalanceDest, startingBalanceDest.add(5e6)); }) - it('prevent cross-chain double spending', async () => { + it.only('prevent cross-chain double spending', async () => { const signers = await ethers.getSigners(); - //ganacheWallet2 makes a deposit with dest chain chainId1 - const ganacheDepositUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); + //ganacheWallet2 makes a deposit with dest chain chainID1 + const ganacheDepositUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainID2), chainId: BigNumber.from(chainID1)}); - const hardhatUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}); + const hardhatUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainID1), chainId: BigNumber.from(chainID1)}); await vBridge.transact([], [ganacheDepositUtxo], 0, '0', '0', ganacheWallet2); await vBridge.transact([ganacheDepositUtxo], [hardhatUtxo], 0, '0', '0', signers[2]); @@ -291,27 +293,27 @@ describe('multichain tests for signature vbridge', () => { ); }) - it('mintable token task test', async () => { + it.only('mintable token task test', async () => { // Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; + const vAnchor1: VAnchor = vBridge.getVAnchor(chainID1)! as VAnchor; const vAnchor1Address = vAnchor1.contract.address; - let edgeIndex = await vAnchor1.contract.edgeIndex(chainId2); + let edgeIndex = await vAnchor1.contract.edgeIndex(chainID2); const destAnchorEdge2Before = await vAnchor1.contract.edgeList(edgeIndex); - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); + const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainID1); const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); const signers2BalanceBefore = await webbToken1.getBalance(await signers[2].getAddress()); - //ganacheWallet2 makes a deposit with dest chain chainId1 - const ganacheDepositUtxo = new Utxo({amount: BigNumber.from(5e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); + //ganacheWallet2 makes a deposit with dest chain chainID1 + const ganacheDepositUtxo = new Utxo({amount: BigNumber.from(5e7), originChainId: BigNumber.from(chainID2), chainId: BigNumber.from(chainID1)}); await vBridge.transact([], [ganacheDepositUtxo], 0, '0', '0', ganacheWallet2); //Check that deposit went through - const vAnchor2: VAnchor = vBridge.getVAnchor(chainId2)! as VAnchor; + const vAnchor2: VAnchor = vBridge.getVAnchor(chainID2)! as VAnchor; const vAnchor2Address = vAnchor2.contract.address; - const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainId2); + const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainID2); const webbToken2 = await MintableToken.tokenFromAddress(webbTokenAddress2!, ganacheWallet2); assert.strictEqual((await webbToken2.getBalance(vAnchor2Address)).toString(), BigNumber.from(6e7).toString()); @@ -322,8 +324,8 @@ describe('multichain tests for signature vbridge', () => { const destAnchorEdge2After = await vAnchor1.contract.edgeList(edgeIndex); assert.deepStrictEqual(destAnchorEdge2Before.latestLeafIndex.add(2), destAnchorEdge2After.latestLeafIndex); - //withdrawing 3e7 from ganacheWallet2 deposit on chainId1 should work despite vanchor1 only having 1e7 webb tokens...this indicates that it minted 2e7 webb tokens to make up the balance - const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(2e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}) + //withdrawing 3e7 from ganacheWallet2 deposit on chainID1 should work despite vanchor1 only having 1e7 webb tokens...this indicates that it minted 2e7 webb tokens to make up the balance + const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(2e7), originChainId: BigNumber.from(chainID1), chainId: BigNumber.from(chainID1)}) await vBridge.transact([ganacheDepositUtxo], [hardhatWithdrawUtxo], 0, await signers[2].getAddress(), '0', signers[2]); const signers2BalanceAfter = await webbToken1.getBalance(await signers[2].getAddress()); assert.strictEqual(signers2BalanceBefore.add(3e7).toString(), signers2BalanceAfter.toString()); @@ -333,15 +335,12 @@ describe('multichain tests for signature vbridge', () => { }) describe('2 sided bridge existing token test wrapping functionality', () => { - // ERC20 compliant contracts that can easily create balances for test let existingToken1: MintableToken; let existingToken2: MintableToken; let vBridge: VBridge; - const chainId1 = 31337; - const chainId2 = 1337; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); + let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:chainID2'); ganacheProvider2.pollingInterval = 1; let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); @@ -360,33 +359,32 @@ describe('multichain tests for signature vbridge', () => { beforeEach(async () => { const signers = await ethers.getSigners(); let webbTokens1 = new Map(); - webbTokens1.set(31337, null!); - webbTokens1.set(1337, null!); + webbTokens1.set(chainID1, null!); + webbTokens1.set(chainID2, null!); // create the config for the bridge const vBridgeInput = { vAnchorInputs: { asset: { - 31337: [existingToken1.contract.address], - 1337: [existingToken2.contract.address], + [chainID1]: [existingToken1.contract.address], + [chainID2]: [existingToken2.contract.address], } }, - chainIDs: [31337, 1337], + chainIDs: [chainID1, chainID2], webbTokens: webbTokens1 } // setup the config for deployers of contracts (admins) const deploymentConfig = { - [chainId1]: signers[1], - [chainId2]: ganacheWallet2, + [chainID1]: signers[1], + [chainID2]: ganacheWallet2, } // deploy the bridge - vBridge = await VBridge.deployVariableAnchorBridge(vBridgeInput, deploymentConfig); // make one deposit so the edge exists - const depositUtxo1 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId2)}); - const depositUtxo2 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); + const depositUtxo1 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainID1), chainId: BigNumber.from(chainID2)}); + const depositUtxo2 = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainID2), chainId: BigNumber.from(chainID1)}); //Transact on the bridge await vBridge.transactWrap(existingToken1.contract.address, [], [depositUtxo1], 0, '0', '0', signers[1]); @@ -395,50 +393,50 @@ describe('multichain tests for signature vbridge', () => { }) describe('#bridging wrapping/unwrapping', () => { - it('check there is a bidirectional bridge between the two chains', async () => { + it.only('check there is a bidirectional bridge between the two chains', async () => { //Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; + const vAnchor1: VAnchor = vBridge.getVAnchor(chainID1)! as VAnchor; const vAnchor1Address = vAnchor1.contract.address; - const vAnchor2: VAnchor = vBridge.getVAnchor(chainId2)! as VAnchor; + const vAnchor2: VAnchor = vBridge.getVAnchor(chainID2)! as VAnchor; const vAnchor2Address = vAnchor2.contract.address; - let edgeIndex12 = await vAnchor1.contract.edgeIndex(chainId2); + let edgeIndex12 = await vAnchor1.contract.edgeIndex(chainID2); const destAnchorEdge2Before = await vAnchor1.contract.edgeList(edgeIndex12); assert.strictEqual(destAnchorEdge2Before.root.toString(), (await vAnchor2.contract.getLastRoot()).toString()); - let edgeIndex21 = await vAnchor2.contract.edgeIndex(chainId1); + let edgeIndex21 = await vAnchor2.contract.edgeIndex(chainID1); const destAnchorEdge1Before = await vAnchor2.contract.edgeList(edgeIndex21); assert.strictEqual(destAnchorEdge1Before.root.toString(), (await vAnchor1.contract.getLastRoot()).toString()); - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); + const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainID1); const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); const vAnchor1Balance = await webbToken1.getBalance(vAnchor1Address); assert.strictEqual(vAnchor1Balance.toString(), BigNumber.from(1e7).toString()); - const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainId2); + const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainID2); const webbToken2 = await MintableToken.tokenFromAddress(webbTokenAddress2!, ganacheWallet2); const vAnchor2Balance = await webbToken2.getBalance(vAnchor2Address); assert.strictEqual(vAnchor2Balance.toString(), BigNumber.from(1e7).toString()); }) - it('wrap and deposit, withdraw and unwrap works join split via transactWrap', async () => { + it.only('wrap and deposit, withdraw and unwrap works join split via transactWrap', async () => { const signers = await ethers.getSigners(); - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; + const vAnchor1: VAnchor = vBridge.getVAnchor(chainID1)! as VAnchor; const vAnchor1Address = vAnchor1.contract.address; - const vAnchor2: VAnchor = vBridge.getVAnchor(chainId2)! as VAnchor; + const vAnchor2: VAnchor = vBridge.getVAnchor(chainID2)! as VAnchor; const vAnchor2Address = vAnchor2.contract.address; - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); + const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainID1); const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); //Deposit UTXO - const ganacheDepositUtxo1 = new Utxo({amount: BigNumber.from(2.5e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - const ganacheDepositUtxo2 = new Utxo({amount: BigNumber.from(2.5e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); + const ganacheDepositUtxo1 = new Utxo({amount: BigNumber.from(2.5e7), originChainId: BigNumber.from(chainID2), chainId: BigNumber.from(chainID1)}); + const ganacheDepositUtxo2 = new Utxo({amount: BigNumber.from(2.5e7), originChainId: BigNumber.from(chainID2), chainId: BigNumber.from(chainID1)}); await vBridge.transactWrap(existingToken2.contract.address, [], [ganacheDepositUtxo1, ganacheDepositUtxo2], 0, '0', '0', ganacheWallet2); - const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainId2); + const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainID2); const webbToken2 = await MintableToken.tokenFromAddress(webbTokenAddress2!, ganacheWallet2); assert.strictEqual((await webbToken2.getBalance(vAnchor2Address)).toString(), BigNumber.from(6e7).toString()); @@ -447,7 +445,7 @@ describe('multichain tests for signature vbridge', () => { const vAnchor1TokenAddr = await vAnchor1.contract.token() await existingToken1.mintTokens(vAnchor1TokenAddr, '100000000'); const balWrapper1UnwrappedBefore = await existingToken1.contract.balanceOf(vAnchor1TokenAddr); - const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}) + const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainID1), chainId: BigNumber.from(chainID1)}) await vBridge.transactWrap(existingToken1.contract.address, [ganacheDepositUtxo1, ganacheDepositUtxo2], [hardhatWithdrawUtxo], 0, await signers[2].getAddress(), '0', signers[1]); //Check relevant balances @@ -462,20 +460,20 @@ describe('multichain tests for signature vbridge', () => { assert.strictEqual(balVAnchor1Wrapped.toString(), BigNumber.from(1e7).toString()); }); - it('wrap and deposit, withdraw and unwrap works join split 16 input via transactWrap', async () => { + it.only('wrap and deposit, withdraw and unwrap works join split 16 input via transactWrap', async () => { const signers = await ethers.getSigners(); - const vAnchor1: VAnchor = vBridge.getVAnchor(chainId1)! as VAnchor; + const vAnchor1: VAnchor = vBridge.getVAnchor(chainID1)! as VAnchor; const vAnchor1Address = vAnchor1.contract.address; - const vAnchor2: VAnchor = vBridge.getVAnchor(chainId2)! as VAnchor; + const vAnchor2: VAnchor = vBridge.getVAnchor(chainID2)! as VAnchor; const vAnchor2Address = vAnchor2.contract.address; - const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainId1); + const webbTokenAddress1 = vBridge.getWebbTokenAddress(chainID1); const webbToken1 = await MintableToken.tokenFromAddress(webbTokenAddress1!, signers[1]); //Deposit UTXO - const ganacheDepositUtxo1 = new Utxo({amount: BigNumber.from(2e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - const ganacheDepositUtxo2 = new Utxo({amount: BigNumber.from(2e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); - const ganacheDepositUtxo3 = new Utxo({amount: BigNumber.from(2e7), originChainId: BigNumber.from(chainId2), chainId: BigNumber.from(chainId1)}); + const ganacheDepositUtxo1 = new Utxo({amount: BigNumber.from(2e7), originChainId: BigNumber.from(chainID2), chainId: BigNumber.from(chainID1)}); + const ganacheDepositUtxo2 = new Utxo({amount: BigNumber.from(2e7), originChainId: BigNumber.from(chainID2), chainId: BigNumber.from(chainID1)}); + const ganacheDepositUtxo3 = new Utxo({amount: BigNumber.from(2e7), originChainId: BigNumber.from(chainID2), chainId: BigNumber.from(chainID1)}); await vBridge.transactWrap(existingToken2.contract.address, [], [ganacheDepositUtxo1], 0, '0', '0', ganacheWallet2); @@ -483,7 +481,7 @@ describe('multichain tests for signature vbridge', () => { await vBridge.transactWrap(existingToken2.contract.address, [], [ganacheDepositUtxo3], 0, '0', '0', ganacheWallet2); - const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainId2); + const webbTokenAddress2 = vBridge.getWebbTokenAddress(chainID2); const webbToken2 = await MintableToken.tokenFromAddress(webbTokenAddress2!, ganacheWallet2); assert.strictEqual((await webbToken2.getBalance(vAnchor2Address)).toString(), BigNumber.from(7e7).toString()); @@ -493,7 +491,7 @@ describe('multichain tests for signature vbridge', () => { const vAnchor1TokenAddr = await vAnchor1.contract.token() await existingToken1.mintTokens(vAnchor1TokenAddr, '100000000'); const balWrapper1UnwrappedBefore = await existingToken1.contract.balanceOf(vAnchor1TokenAddr); - const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainId1), chainId: BigNumber.from(chainId1)}) + const hardhatWithdrawUtxo = new Utxo({amount: BigNumber.from(1e7), originChainId: BigNumber.from(chainID1), chainId: BigNumber.from(chainID1)}) await vBridge.transactWrap(existingToken1.contract.address, [ganacheDepositUtxo1, ganacheDepositUtxo2, ganacheDepositUtxo3], [hardhatWithdrawUtxo], 0, await signers[2].getAddress(), '0', signers[1]); //Check relevant balances From f89c5c21d1b53839b11b67be8ae53adb927b6dee Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 26 Jan 2022 18:03:13 -0500 Subject: [PATCH 08/15] Fix fmt --- test/vanchor/vanchor.test.ts | 46 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/test/vanchor/vanchor.test.ts b/test/vanchor/vanchor.test.ts index ca455077f..9eeb97428 100644 --- a/test/vanchor/vanchor.test.ts +++ b/test/vanchor/vanchor.test.ts @@ -119,14 +119,14 @@ describe('VAnchor for 2 max edges', () => { }) describe('#constructor', () => { - it'should initialize', async () => { + it('should initialize', async () => { const maxEdges = await anchor.contract.maxEdges(); assert.strictEqual(maxEdges.toString(), `${MAX_EDGES}`); }); }); describe('snark proof native verification on js side', () => { - it'should work', async () => { + it('should work', async () => { const relayer = "0x2111111111111111111111111111111111111111"; const extAmount = 1e7; const isL1Withdrawal = false; @@ -168,7 +168,7 @@ describe('VAnchor for 2 max edges', () => { }); - it'poseidon4 isolated gadget test', async () => { + it('poseidon4 isolated gadget test', async () => { const relayer = "0x2111111111111111111111111111111111111111"; const extAmount = 1e7; const isL1Withdrawal = false; @@ -203,7 +203,7 @@ describe('VAnchor for 2 max edges', () => { }) describe ('Setting Handler/Verifier Address Negative Tests', () => { - it'should revert (setting handler) with improper nonce', async() => { + it('should revert (setting handler) with improper nonce', async() => { const signers = await ethers.getSigners(); await TruffleAssert.reverts( anchor.contract.setHandler(signers[1].address, 0), @@ -215,7 +215,7 @@ describe('VAnchor for 2 max edges', () => { ) }); - it'should revert (setting verifier) with improper nonce', async() => { + it('should revert (setting verifier) with improper nonce', async() => { const signers = await ethers.getSigners(); await TruffleAssert.reverts( anchor.contract.setVerifier(signers[1].address, 0), @@ -229,7 +229,7 @@ describe('VAnchor for 2 max edges', () => { }) describe('#transact', () => { - it'should transact', async () => { + it('should transact', async () => { // Alice deposits into tornado pool const aliceDepositAmount = 1e7; const aliceDepositUtxo = new Utxo({ @@ -246,7 +246,7 @@ describe('VAnchor for 2 max edges', () => { ); }) - it'should process fee on deposit', async () => { + it('should process fee on deposit', async () => { const signers = await ethers.getSigners(); const alice= signers[0]; @@ -278,7 +278,7 @@ describe('VAnchor for 2 max edges', () => { assert.strictEqual((await token.balanceOf(relayer)).toString(), BigNumber.from(fee).toString()); }) - it'should spend input utxo and create output utxo', async () => { + it('should spend input utxo and create output utxo', async () => { // Alice deposits into tornado pool const aliceDepositAmount = 1e7; const aliceDepositUtxo = new Utxo({ @@ -307,7 +307,7 @@ describe('VAnchor for 2 max edges', () => { ); }) - it'should spend input utxo and split', async () => { + it('should spend input utxo and split', async () => { // Alice deposits into tornado pool const aliceDepositAmount = 10; const aliceDepositUtxo = new Utxo({ @@ -342,7 +342,7 @@ describe('VAnchor for 2 max edges', () => { ); }) - it'should join and spend', async () => { + it('should join and spend', async () => { const aliceDepositAmount1 = 1e7; const aliceDepositUtxo1 = new Utxo({ chainId: BigNumber.from(chainID), @@ -384,7 +384,7 @@ describe('VAnchor for 2 max edges', () => { ); }) - it'should join and spend with 16 inputs', async () => { + it('should join and spend with 16 inputs', async () => { const aliceDepositAmount1 = 1e7; const aliceDepositUtxo1 = new Utxo({ chainId: BigNumber.from(chainID), @@ -440,7 +440,7 @@ describe('VAnchor for 2 max edges', () => { ); }).timeout(40000); - it'should withdraw', async () => { + it('should withdraw', async () => { const aliceDepositAmount = 1e7; const aliceDepositUtxo = new Utxo({ chainId: BigNumber.from(chainID), @@ -473,7 +473,7 @@ describe('VAnchor for 2 max edges', () => { assert.strictEqual(aliceWithdrawAmount.toString(), await (await token.balanceOf(aliceETHAddress)).toString()); }).timeout(40000); - it'should prevent double spend', async () => { + it('should prevent double spend', async () => { const aliceDepositAmount = 1e7; const aliceDepositUtxo = new Utxo({ chainId: BigNumber.from(chainID), @@ -510,7 +510,7 @@ describe('VAnchor for 2 max edges', () => { ) }); - it'should prevent increasing UTXO amount without depositing', async () => { + it('should prevent increasing UTXO amount without depositing', async () => { const signers = await ethers.getSigners(); const alice= signers[0]; @@ -552,7 +552,7 @@ describe('VAnchor for 2 max edges', () => { ) }); - it'should reject tampering with public inputs', async () => { + it('should reject tampering with public inputs', async () => { const relayer = "0x2111111111111111111111111111111111111111"; const extAmount = 1e7; const isL1Withdrawal = false; @@ -735,7 +735,7 @@ describe('VAnchor for 2 max edges', () => { ); }); - it'should be compliant', async function () { + it('should be compliant', async function () { // basically verifier should check if a commitment and a nullifier hash are on chain const [sender] = await ethers.getSigners(); @@ -807,7 +807,7 @@ describe('VAnchor for 2 max edges', () => { }) }) describe('#wrapping tests', () => { - it'should wrap and deposit', async () => { + it('should wrap and deposit', async () => { const signers = await ethers.getSigners(); const wallet = signers[0]; const sender = wallet; @@ -864,7 +864,7 @@ describe('VAnchor for 2 max edges', () => { assert.strictEqual(balWrappedTokenAfterDepositSender.toString(), '0'); }); - it'should withdraw and unwrap', async () => { + it('should withdraw and unwrap', async () => { const signers = await ethers.getSigners(); const wallet = signers[0]; const sender = wallet; @@ -934,7 +934,7 @@ describe('VAnchor for 2 max edges', () => { assert.strictEqual(balTokenBeforeDepositSender.toString(), balTokenAfterWithdrawAndUnwrapSender.toString()); }); - it'wrapping fee should work correctly with transactWrap', async () => { + it('wrapping fee should work correctly with transactWrap', async () => { const signers = await ethers.getSigners(); const wallet = signers[0]; const sender = wallet; @@ -1018,7 +1018,7 @@ describe('VAnchor for 2 max edges', () => { assert.strictEqual(balUnwrappedTokenAfterDepositWrapper.sub(balUnwrappedTokenAfterWithdrawWrapper).toString(), BigNumber.from(1e7).toString()); }); - it'non-governor setting fee should fail', async () => { + it('non-governor setting fee should fail', async () => { const signers = await ethers.getSigners(); const wallet = signers[0]; const sender = wallet; @@ -1038,7 +1038,7 @@ describe('VAnchor for 2 max edges', () => { ); }); - it'fee percentage cannot be greater than 100', async () => { + it('fee percentage cannot be greater than 100', async () => { const signers = await ethers.getSigners(); const wallet = signers[0]; const sender = wallet; @@ -1057,7 +1057,7 @@ describe('VAnchor for 2 max edges', () => { ); }); - it'fee percentage cannot be negative', async () => { + it('fee percentage cannot be negative', async () => { const signers = await ethers.getSigners(); const wallet = signers[0]; const sender = wallet; @@ -1075,7 +1075,7 @@ describe('VAnchor for 2 max edges', () => { ); }); - it'fee percentage cannot be non-integer', async () => { + it('fee percentage cannot be non-integer', async () => { const signers = await ethers.getSigners(); const wallet = signers[0]; const sender = wallet; From b542761b1f02b7f09d0b09799d1f2a934aa484f7 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 26 Jan 2022 18:07:39 -0500 Subject: [PATCH 09/15] Fix tests --- test/vbridge/signatureVBridge.test.ts | 31 +++++++++++---------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/test/vbridge/signatureVBridge.test.ts b/test/vbridge/signatureVBridge.test.ts index 62b2465ef..3c4ba7c00 100644 --- a/test/vbridge/signatureVBridge.test.ts +++ b/test/vbridge/signatureVBridge.test.ts @@ -19,17 +19,11 @@ export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); describe('multichain tests for signature vbridge', () => { const chainID1 = getChainIdType(31337); const chainID2 = getChainIdType(1337); - const chainID3 = getChainIdType(9999); - const chainID4 = getChainIdType(4444); // setup ganache networks let ganacheServer2: any; - let ganacheServer3: any; - let ganacheServer4: any; before('setup networks', async () => { ganacheServer2 = await startGanacheServer(1337, 1337, 'congress island collect purity dentist team gas unlock nuclear pig combine sight'); - ganacheServer3 = await startGanacheServer(9999, 9999, 'aspect biology suit thought bottom popular custom rebuild recall sauce endless local'); - ganacheServer4 = await startGanacheServer(4444, 4444, 'harvest useful giraffe swim rail ostrich public awful provide amazing tank weapon'); }); describe('BridgeConstruction', () => { @@ -61,7 +55,7 @@ describe('multichain tests for signature vbridge', () => { await tokenInstance1.mintTokens(signers[2].address, '100000000000000000000000000'); }); - it.only('create 2 side bridge for one token', async () => { + it('create 2 side bridge for one token', async () => { let webbTokens1 = new Map(); webbTokens1.set(chainID1, null!); webbTokens1.set(chainID2, null!); @@ -188,7 +182,7 @@ describe('multichain tests for signature vbridge', () => { }) describe('#bridging', () => { - it.only('basic ganache deposit should withdraw on hardhat', async () => { + it('basic ganache deposit should withdraw on hardhat', async () => { // Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); @@ -216,7 +210,7 @@ describe('multichain tests for signature vbridge', () => { assert.strictEqual(signers2BalanceBefore.add(5e6).toString(), signers2BalanceAfter.toString()); }).timeout(40000) - it.only('join and split ganache deposits and withdraw on hardhat', async () => { + it('join and split ganache deposits and withdraw on hardhat', async () => { const signers = await ethers.getSigners(); const vAnchor1: VAnchor = vBridge.getVAnchor(chainID1)! as VAnchor; @@ -245,7 +239,7 @@ describe('multichain tests for signature vbridge', () => { assert.strictEqual(signers2BalanceBefore.add(1.5e7).toString(), signers2BalanceAfter.toString()); }) - it.only('should update multiple deposits and withdraw historic deposit from ganache', async () => { + it('should update multiple deposits and withdraw historic deposit from ganache', async () => { // Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); @@ -277,7 +271,7 @@ describe('multichain tests for signature vbridge', () => { assert.deepStrictEqual(endingBalanceDest, startingBalanceDest.add(5e6)); }) - it.only('prevent cross-chain double spending', async () => { + it('prevent cross-chain double spending', async () => { const signers = await ethers.getSigners(); //ganacheWallet2 makes a deposit with dest chain chainID1 @@ -293,7 +287,7 @@ describe('multichain tests for signature vbridge', () => { ); }) - it.only('mintable token task test', async () => { + it('mintable token task test', async () => { // Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); @@ -340,7 +334,7 @@ describe('multichain tests for signature vbridge', () => { let existingToken2: MintableToken; let vBridge: VBridge; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:chainID2'); + let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); ganacheProvider2.pollingInterval = 1; let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); @@ -393,7 +387,7 @@ describe('multichain tests for signature vbridge', () => { }) describe('#bridging wrapping/unwrapping', () => { - it.only('check there is a bidirectional bridge between the two chains', async () => { + it('check there is a bidirectional bridge between the two chains', async () => { //Fetch information about the anchor to be updated. const signers = await ethers.getSigners(); @@ -419,8 +413,9 @@ describe('multichain tests for signature vbridge', () => { const vAnchor2Balance = await webbToken2.getBalance(vAnchor2Address); assert.strictEqual(vAnchor2Balance.toString(), BigNumber.from(1e7).toString()); - }) - it.only('wrap and deposit, withdraw and unwrap works join split via transactWrap', async () => { + }); + + it('wrap and deposit, withdraw and unwrap works join split via transactWrap', async () => { const signers = await ethers.getSigners(); const vAnchor1: VAnchor = vBridge.getVAnchor(chainID1)! as VAnchor; @@ -460,7 +455,7 @@ describe('multichain tests for signature vbridge', () => { assert.strictEqual(balVAnchor1Wrapped.toString(), BigNumber.from(1e7).toString()); }); - it.only('wrap and deposit, withdraw and unwrap works join split 16 input via transactWrap', async () => { + it('wrap and deposit, withdraw and unwrap works join split 16 input via transactWrap', async () => { const signers = await ethers.getSigners(); const vAnchor1: VAnchor = vBridge.getVAnchor(chainID1)! as VAnchor; @@ -510,7 +505,5 @@ describe('multichain tests for signature vbridge', () => { after('terminate networks', async () => { await ganacheServer2.close(); - await ganacheServer3.close(); - await ganacheServer4.close(); }); }); \ No newline at end of file From a437586c868f2dd603e339cf7fb08720bad5011f Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Thu, 27 Jan 2022 09:57:32 -0500 Subject: [PATCH 10/15] Fix another test --- packages/tokens/src/GovernedTokenWrapper.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/tokens/src/GovernedTokenWrapper.ts b/packages/tokens/src/GovernedTokenWrapper.ts index 4d9f5d8cd..f372acdda 100644 --- a/packages/tokens/src/GovernedTokenWrapper.ts +++ b/packages/tokens/src/GovernedTokenWrapper.ts @@ -1,5 +1,5 @@ import { ethers } from 'ethers'; -import { toHex } from '@webb-tools/utils'; +import { getChainIdType, toHex } from '@webb-tools/utils'; import { GovernedTokenWrapper as GovernedTokenWrapperContract, GovernedTokenWrapper__factory } from '@webb-tools/contracts'; export class GovernedTokenWrapper { @@ -50,7 +50,7 @@ export class GovernedTokenWrapper { } public async createResourceId(): Promise { - return toHex(this.contract.address + toHex((await this.signer.getChainId()), 4).substr(2), 32); + return toHex(this.contract.address + toHex(getChainIdType(await this.signer.getChainId()), 6).substr(2), 32); } public async getAddTokenProposalData(tokenAddress: string): Promise { From f50adaca4d32b1e049c875f4439a17e1b0e17f01 Mon Sep 17 00:00:00 2001 From: Akilesh Tangella Date: Thu, 27 Jan 2022 10:24:34 -0500 Subject: [PATCH 11/15] fixed reject tampered public inputs test --- test/anchor/anchor.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/anchor/anchor.test.ts b/test/anchor/anchor.test.ts index e8d8d8091..efc14a7c2 100644 --- a/test/anchor/anchor.test.ts +++ b/test/anchor/anchor.test.ts @@ -25,7 +25,7 @@ import { import { Verifier } from '../../packages/bridges/src'; import { Anchor } from '../../packages/anchors/src'; import { MerkleTree } from '../../packages/merkle-tree/src'; -import { fetchComponentsFromFilePaths, ZkComponents, toFixedHex } from '../../packages/utils/src'; +import { fetchComponentsFromFilePaths, ZkComponents, toFixedHex, getChainIdType } from '../../packages/utils/src'; const { NATIVE_AMOUNT } = process.env const snarkjs = require('snarkjs') @@ -48,7 +48,7 @@ describe('Anchor for 2 max edges', () => { let token: Token; let wrappedToken: WrappedToken; let tokenDenomination = '1000000000000000000' // 1 ether - const chainID = 31337; + const chainID = getChainIdType(31337); const MAX_EDGES = 1; let createWitness: any; From ab208024dfa02948064dad46b0f6f9870eddeda6 Mon Sep 17 00:00:00 2001 From: Akilesh Tangella Date: Thu, 27 Jan 2022 10:28:49 -0500 Subject: [PATCH 12/15] fixed refresh deposit test --- test/anchor/anchor.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/anchor/anchor.test.ts b/test/anchor/anchor.test.ts index efc14a7c2..00c76bc2d 100644 --- a/test/anchor/anchor.test.ts +++ b/test/anchor/anchor.test.ts @@ -655,7 +655,7 @@ describe('Anchor for 2 max edges', () => { // create a deposit on the anchor already setup const { deposit, index } = await anchor.deposit(); - const refreshedDestId = await wallet.getChainId(); + const refreshedDestId = getChainIdType(await wallet.getChainId()); const refreshedDeposit = Anchor.generateDeposit(refreshedDestId); const { merkleRoot, pathElements, pathIndices } = anchor.tree.path(0); From 5505eeaf308da9d7900575f3df441893fd628529 Mon Sep 17 00:00:00 2001 From: Akilesh Tangella Date: Thu, 27 Jan 2022 10:33:59 -0500 Subject: [PATCH 13/15] wrap fee test passing --- test/anchor/anchor.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/anchor/anchor.test.ts b/test/anchor/anchor.test.ts index 00c76bc2d..59802b323 100644 --- a/test/anchor/anchor.test.ts +++ b/test/anchor/anchor.test.ts @@ -810,7 +810,7 @@ describe('Anchor for 2 max edges', () => { const balUnwrappedTokenBeforeWithdrawSender = await token.balanceOf(sender.address); const newAnchor = await Anchor.connect(wrappedAnchor.contract.address, zkComponents, wallet); - await TruffleAssert.passes(newAnchor.withdrawAndUnwrap(deposit, 31337, index, sender.address, signers[1].address, bigInt(0), bigInt(0), token.address)); + await TruffleAssert.passes(newAnchor.withdrawAndUnwrap(deposit, getChainIdType(31337), index, sender.address, signers[1].address, bigInt(0), bigInt(0), token.address)); const balWrappedTokenAfterWithdrawAnchor = await wrappedToken.balanceOf(wrappedAnchor.contract.address); assert.strictEqual(balWrappedTokenAfterWithdrawAnchor.toString(), '0'); From 301b60e610d7af3b3a340a4517b5f71e8a437618 Mon Sep 17 00:00:00 2001 From: Akilesh Tangella Date: Thu, 27 Jan 2022 10:36:00 -0500 Subject: [PATCH 14/15] fix anchorproxy test --- test/anchor/anchorProxy.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/anchor/anchorProxy.test.ts b/test/anchor/anchorProxy.test.ts index 6f4d20e99..bf115f3e0 100644 --- a/test/anchor/anchorProxy.test.ts +++ b/test/anchor/anchorProxy.test.ts @@ -22,7 +22,7 @@ import { // Convenience wrapper classes for contract classes import { Verifier } from '../../packages/bridges/src' -import { fetchComponentsFromFilePaths, ZkComponents, toFixedHex } from '../../packages/utils/src'; +import { fetchComponentsFromFilePaths, ZkComponents, toFixedHex, getChainIdType } from '../../packages/utils/src'; import { Anchor, AnchorProxy } from '../../packages/anchors/src'; import { MerkleTree } from '../../packages/merkle-tree/src'; @@ -50,7 +50,7 @@ describe('AnchorProxy', () => { let token: Token; let wrappedToken: WrappedToken; let tokenDenomination = '1000000000000000000' // 1 ether - const chainID = 31337; + const chainID = getChainIdType(31337); const MAX_EDGES = 1; let createWitness: any; From dc343430f3086f2e7f7629ab911882db07fe5dee Mon Sep 17 00:00:00 2001 From: Akilesh Tangella Date: Thu, 27 Jan 2022 10:59:51 -0500 Subject: [PATCH 15/15] all tests should pass --- test/vbridge/signatureVBridge.test.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/vbridge/signatureVBridge.test.ts b/test/vbridge/signatureVBridge.test.ts index 3c4ba7c00..aea53d273 100644 --- a/test/vbridge/signatureVBridge.test.ts +++ b/test/vbridge/signatureVBridge.test.ts @@ -33,7 +33,6 @@ describe('multichain tests for signature vbridge', () => { let tokenAbbreviation: string = 'EXIST'; let tokenInstance1: MintableToken; let tokenInstance2: MintableToken; - let tokenInstance3: MintableToken; let ganacheProvider2 = new ethers.providers.JsonRpcProvider('http://localhost:1337'); ganacheProvider2.pollingInterval = 1; @@ -44,14 +43,10 @@ describe('multichain tests for signature vbridge', () => { before('construction-tests', async () => { const signers = await ethers.getSigners(); - await ganacheProvider2.ready; - // Create a token to test bridge construction support for existing tokens tokenInstance1 = await MintableToken.createToken(tokenName, tokenAbbreviation, signers[7]); tokenInstance2 = await MintableToken.createToken(tokenName, tokenAbbreviation, ganacheWallet2); - tokenInstance3 = await MintableToken.createToken(tokenName, tokenAbbreviation, ganacheWallet3); - await tokenInstance1.mintTokens(signers[2].address, '100000000000000000000000000'); });