diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 37790e5f6b1..de91a66c7f2 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,4 +1,4 @@ -- [ ] I've asked for help in the [Truffle Gitter](http://gitter.im/Consensys/truffle) before filing this issue. +- [ ] I've [opened a support ticket](https://trufflesuite.zendesk.com/hc/en-us/requests/new) before filing this issue. --------------------------- diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 1dca82151c9..3eff7f18d9d 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -14,20 +14,19 @@ on: jobs: yarncheck: - runs-on: ubuntu-20.04 #please unpin once possible + runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 - run: npm install -g yarn - - run: yarn bootstrap - - run: test -z "$(git diff)" || (echo 'Please run yarn and commit all changes to yarn.lock'; false) + - run: yarn install --ignore-scripts --frozen-lockfile --ignore-engines build: strategy: matrix: - platform: [ubuntu-20.04] #please unpin once possible - node-version: [10.x, 12.x, 14.x] + platform: [ubuntu-latest] + node-version: [12.x, 14.x] env: [GETH=true, PACKAGES=true, INTEGRATION=true] runs-on: ${{ matrix.platform }} @@ -53,7 +52,7 @@ jobs: slack_notification: needs: [yarncheck, build] - runs-on: ubuntu-20.04 #please unpin once possible + runs-on: ubuntu-latest continue-on-error: true steps: - uses: 8398a7/action-slack@v1.1.1 diff --git a/packages/artifactor/package.json b/packages/artifactor/package.json index 015f3056775..adfc72b22ca 100644 --- a/packages/artifactor/package.json +++ b/packages/artifactor/package.json @@ -4,12 +4,16 @@ "description": "A contract packager for Ethereum and Javascript", "license": "MIT", "author": "Tim Coulter", + "bugs": { + "url": "https://github.com/trufflesuite/truffle/issues" + }, + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/artifactor#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", "directory": "packages/artifactor" }, - "version": "4.0.118", + "version": "4.0.126", "main": "dist/index.js", "scripts": { "build": "tsc", @@ -24,7 +28,7 @@ "lodash.merge": "^4.6.2" }, "devDependencies": { - "@truffle/contract": "^4.3.30", + "@truffle/contract": "^4.3.38", "@types/fs-extra": "^8.1.0", "@types/lodash.assign": "^4.2.6", "@types/lodash.merge": "^4.6.6", @@ -38,7 +42,7 @@ "tmp": "^0.2.1", "ts-node": "^9.0.0", "typescript": "^4.1.4", - "web3": "1.5.2" + "web3": "1.5.3" }, "publishConfig": { "access": "public" diff --git a/packages/box/package.json b/packages/box/package.json index 768a80158ca..1e391d3bbe2 100644 --- a/packages/box/package.json +++ b/packages/box/package.json @@ -3,12 +3,16 @@ "description": "Truffle project boilerplate utility", "license": "MIT", "author": "g. nicholas d'andrea ", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/box#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", "directory": "packages/box" }, - "version": "2.1.24", + "bugs": { + "url": "https://github.com/trufflesuite/truffle/issues" + }, + "version": "2.1.30", "main": "dist/box.js", "scripts": { "build": "tsc", @@ -17,7 +21,7 @@ }, "types": "./typings/index.d.ts", "dependencies": { - "@truffle/config": "^1.3.4", + "@truffle/config": "^1.3.10", "axios": "^0.21.1", "download-git-repo": "^3.0.2", "fs-extra": "^9.1.0", diff --git a/packages/code-utils/package.json b/packages/code-utils/package.json index 839259bcf6d..02c0798c16b 100644 --- a/packages/code-utils/package.json +++ b/packages/code-utils/package.json @@ -3,12 +3,16 @@ "description": "Utilities for parsing and managing EVM-compatible bytecode", "license": "MIT", "author": "", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/code-utils#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", "directory": "packages/code-utils" }, - "version": "1.2.29", + "bugs": { + "url": "https://github.com/trufflesuite/truffle/issues" + }, + "version": "1.2.30", "main": "dist/src/index.js", "scripts": { "build": "tsc", diff --git a/packages/codec/lib/abi-data/allocate/index.ts b/packages/codec/lib/abi-data/allocate/index.ts index 0612437a840..471403c458a 100644 --- a/packages/codec/lib/abi-data/allocate/index.ts +++ b/packages/codec/lib/abi-data/allocate/index.ts @@ -196,6 +196,7 @@ function abiSizeAndAllocate( case "fixed": case "ufixed": case "enum": + case "userDefinedValueType": return { size: Evm.Utils.WORD_SIZE, dynamic: false, @@ -367,6 +368,7 @@ function allocateCalldataAndReturndata( let inputParametersAbi: Abi.Parameter[]; let outputParametersAbi: Abi.Parameter[]; let offset: number; //refers to INPUT offset; output offset is always 0 + debug("allocating calldata and returndata"); switch (abiEntry.type) { case "constructor": if (!constructorContext) { @@ -405,6 +407,7 @@ function allocateCalldataAndReturndata( ), contractNode ).node; //may be undefined! that's OK! + debug("found node: %o", Boolean(node)); } break; } @@ -463,6 +466,7 @@ function allocateCalldataAndReturndata( compiler //note no offset ); + debug("modes: %s in, %s out", inputMode, outputMode); //finally: transform the allocation appropriately let inputArgumentsAllocation = abiAllocationInput.members.map(member => ({ ...member, @@ -546,6 +550,7 @@ function allocateDataArguments( )[id]; } catch { //if something goes wrong, switch to ABI mdoe + debug("falling back to ABI due to exception!"); allocationMode = "abi"; } } diff --git a/packages/codec/lib/abify.ts b/packages/codec/lib/abify.ts index 623f22b19de..7f34cd66c90 100644 --- a/packages/codec/lib/abify.ts +++ b/packages/codec/lib/abify.ts @@ -14,7 +14,7 @@ import * as Conversion from "@truffle/codec/conversion"; export function abifyType( dataType: Format.Types.Type, userDefinedTypes?: Format.Types.TypesById -): Format.Types.Type | undefined { +): Format.Types.AbiType | undefined { switch (dataType.typeClass) { //we only need to specially handle types that don't go in //the ABI, or that have some information loss when going @@ -23,6 +23,7 @@ export function abifyType( //First: types that do not go in the ABI case "mapping": case "magic": + case "type": return undefined; //Next: address & contract, these can get handled together case "address": @@ -50,7 +51,7 @@ export function abifyType( const fullType = ( Format.Types.fullType(dataType, userDefinedTypes) ); - if (!fullType) { + if (!fullType.memberTypes) { let typeToDisplay = Format.Types.typeString(dataType); throw new Common.UnknownUserDefinedTypeError( dataType.id, @@ -73,7 +74,7 @@ export function abifyType( const fullType = ( Format.Types.fullType(dataType, userDefinedTypes) ); - if (!fullType) { + if (!fullType.options) { let typeToDisplay = Format.Types.typeString(dataType); throw new Common.UnknownUserDefinedTypeError( dataType.id, @@ -88,6 +89,26 @@ export function abifyType( typeHint: Format.Types.typeString(fullType) }; } + case "userDefinedValueType": { + const fullType = ( + Format.Types.fullType(dataType, userDefinedTypes) + ); + if (!fullType.underlyingType) { + let typeToDisplay = Format.Types.typeString(dataType); + throw new Common.UnknownUserDefinedTypeError( + dataType.id, + typeToDisplay + ); + } + const abifiedUnderlying = abifyType( + fullType.underlyingType, + userDefinedTypes + ); + return { + ...abifiedUnderlying, + typeHint: Format.Types.typeStringWithoutLocation(dataType) + }; + } //finally: arrays case "array": return { @@ -105,10 +126,11 @@ export function abifyType( export function abifyResult( result: Format.Values.Result, userDefinedTypes?: Format.Types.TypesById -): Format.Values.Result | undefined { +): Format.Values.AbiResult | undefined { switch (result.type.typeClass) { case "mapping": //doesn't go in ABI case "magic": //doesn't go in ABI + case "type": //doesn't go in ABI return undefined; case "address": //abify the type but leave the value alone @@ -187,7 +209,7 @@ export function abifyResult( ); return { kind: "value", - type: ( + type: ( abifyType(result.type, userDefinedTypes) ), //note: may throw exception value: abifiedMembers @@ -195,12 +217,25 @@ export function abifyResult( case "error": return { ...coercedResult, - type: ( + type: ( abifyType(result.type, userDefinedTypes) ) //note: may throw exception }; } } + case "userDefinedValueType": { + const coercedResult = result; + switch (coercedResult.kind) { + case "value": + return abifyResult(coercedResult.value, userDefinedTypes); + case "error": + return { //I have no idea what TS is thinking here + ...coercedResult, + type: abifyType(result.type, userDefinedTypes) + }; + } + break; //to satisfy TS :P + } case "enum": { //NOTE: this is the one case where errors are converted to non-error values!! //(other than recursively, I mean) @@ -295,7 +330,7 @@ export function abifyResult( } } default: - return result; + return result; //just coerce :-/ } } diff --git a/packages/codec/lib/ast/import/index.ts b/packages/codec/lib/ast/import/index.ts index aa94c1deaa6..16412c1ae20 100644 --- a/packages/codec/lib/ast/import/index.ts +++ b/packages/codec/lib/ast/import/index.ts @@ -47,8 +47,7 @@ export function definitionToType( kind: "general", typeHint }; - case "0.5.x": - case "0.8.x": + default: return { typeClass, kind: "specific", @@ -254,9 +253,7 @@ export function definitionToType( } case "struct": { let id = makeTypeId(Utils.typeId(definition), compilationId); - let qualifiedName = Utils.typeStringWithoutLocation(definition).match( - /struct (.*)/ - )[1]; + let qualifiedName = typeHint.match(/struct (.*)/)[1]; let definingContractName: string; let typeName: string; if (qualifiedName.includes(".")) { @@ -305,9 +302,7 @@ export function definitionToType( } case "enum": { let id = makeTypeId(Utils.typeId(definition), compilationId); - let qualifiedName = Utils.typeStringWithoutLocation(definition).match( - /enum (.*)/ - )[1]; + let qualifiedName = typeHint.match(/enum (.*)/)[1]; let definingContractName: string; let typeName: string; if (qualifiedName.includes(".")) { @@ -333,11 +328,37 @@ export function definitionToType( }; } } + case "userDefinedValueType": { + let id = makeTypeId(Utils.typeId(definition), compilationId); + let definingContractName: string; + let typeName: string; + if (typeHint.includes(".")) { + [definingContractName, typeName] = typeHint.split("."); + } else { + typeName = typeHint; + //leave definingContractName undefined + } + if (definingContractName) { + return { + typeClass, + kind: "local", + id, + typeName, + definingContractName + }; + } else { + return { + typeClass, + kind: "global", + id, + typeName + }; + } + } case "contract": { let id = makeTypeId(Utils.typeId(definition), compilationId); - let typeName = Utils.typeStringWithoutLocation(definition).match( - /(contract|library|interface) (.*)/ - )[2]; //note: we use the type string rather than the type identifier + let typeName = typeHint.match(/(contract|library|interface) (.*)/)[2]; + //note: we use the type string rather than the type identifier //in order to avoid having to deal with the underscore problem let contractKind = Utils.contractKind(definition); return { @@ -371,37 +392,24 @@ export function definitionToStoredType( ): Format.Types.UserDefinedType { switch (definition.nodeType) { case "StructDefinition": { - let id = makeTypeId(definition.id, compilationId); - let definingContractName: string; - let typeName: string; - if (definition.canonicalName.includes(".")) { - [definingContractName, typeName] = definition.canonicalName.split("."); - } else { - typeName = definition.canonicalName; - //leave definingContractName undefined - } - let memberTypes: { + const { + id, + typeName, + definingContractName, + definingContract + } = getDefiningInfo( + definition, + compilationId, + compiler, + referenceDeclarations + ); + const memberTypes: { name: string; type: Format.Types.Type; }[] = definition.members.map(member => ({ name: member.name, type: definitionToType(member, compilationId, compiler, null) })); - let definingContract; - if (referenceDeclarations) { - let contractDefinition = Object.values(referenceDeclarations).find( - node => - node.nodeType === "ContractDefinition" && - node.nodes.some( - (subNode: AstNode) => makeTypeId(subNode.id, compilationId) === id - ) - ); - if (contractDefinition) { - definingContract = ( - definitionToStoredType(contractDefinition, compilationId, compiler) - ); //can skip reference declarations - } - } if (definingContract) { return { typeClass: "struct", @@ -423,34 +431,18 @@ export function definitionToStoredType( } } case "EnumDefinition": { - let id = makeTypeId(definition.id, compilationId); - let definingContractName: string; - let typeName: string; - debug("typeName: %s", typeName); - if (definition.canonicalName.includes(".")) { - [definingContractName, typeName] = definition.canonicalName.split("."); - } else { - typeName = definition.canonicalName; - //leave definingContractName undefined - } - let options = definition.members.map(member => member.name); - let definingContract; - if (referenceDeclarations) { - let contractDefinition = Object.values(referenceDeclarations).find( - node => - node.nodeType === "ContractDefinition" && - node.nodes.some( - (subNode: AstNode) => makeTypeId(subNode.id, compilationId) === id - ) - ); - if (contractDefinition) { - definingContract = ( - definitionToStoredType(contractDefinition, compilationId, compiler) - ); //can skip reference declarations - debug("contractDefinition: %o", contractDefinition); - debug("definingContract: %o", definingContract); - } - } + const { + id, + typeName, + definingContractName, + definingContract + } = getDefiningInfo( + definition, + compilationId, + compiler, + referenceDeclarations + ); + const options = definition.members.map(member => member.name); if (definingContract) { return { typeClass: "enum", @@ -471,6 +463,40 @@ export function definitionToStoredType( }; } } + case "UserDefinedValueTypeDefinition": { + const { + id, + typeName, + definingContractName, + definingContract + } = getDefiningInfo( + definition, + compilationId, + compiler, + referenceDeclarations + ); + let underlyingType = //we know it's that, TS doesn't + definitionToType(definition.underlyingType, compilationId, compiler, null); //final null doesn't matter here + if (definingContract) { + return { + typeClass: "userDefinedValueType", + kind: "local", + id, + typeName, + definingContractName, + definingContract, + underlyingType + }; + } else { + return { + typeClass: "userDefinedValueType", + kind: "global", + id, + typeName, + underlyingType + }; + } + } case "ContractDefinition": { let id = makeTypeId(definition.id, compilationId); let typeName = definition.name; @@ -487,3 +513,60 @@ export function definitionToStoredType( } } } + +interface DefiningInfo { + definingContract?: Format.Types.ContractTypeNative; + definingContractName?: string; + typeName: string; + id: string; +} + +function getDefiningInfo( + definition: AstNode, + compilationId: string, + compiler: Compiler.CompilerVersion, + referenceDeclarations?: AstNodes +): DefiningInfo { + const id = makeTypeId(definition.id, compilationId); + let definingContractName: string | undefined; + let typeName: string; + if (definition.canonicalName) { + if (definition.canonicalName.includes(".")) { + [definingContractName, typeName] = definition.canonicalName.split("."); + } else { + typeName = definition.canonicalName; + } + } else { + //due to a bug, in 0.8.8 UDVTs lack a canonicalName. + //so we'll set typeName based on name instead of canonicalName, + //and set definingContractName below based on definingContract. + //(this does mean that we'll mess up a bit if referenceDeclarations + //is not passed... but realistically that shouldn't come up? really the + //same kind of hapepns for every type) + typeName = definition.name; + } + let definingContract: Format.Types.ContractTypeNative | undefined = undefined;; + if (referenceDeclarations) { + let contractDefinition = Object.values(referenceDeclarations).find( + node => + node.nodeType === "ContractDefinition" && + node.nodes.some( + (subNode: AstNode) => makeTypeId(subNode.id, compilationId) === id + ) + ); + if (contractDefinition) { + definingContract = ( + definitionToStoredType(contractDefinition, compilationId, compiler) + ); //can skip reference declarations + if (!definingContractName) { + definingContractName = contractDefinition.name; + } + } + } + return { + definingContract, + definingContractName, + typeName, + id + }; +} diff --git a/packages/codec/lib/ast/types.ts b/packages/codec/lib/ast/types.ts index 7ec9fb58882..ed089e7d450 100644 --- a/packages/codec/lib/ast/types.ts +++ b/packages/codec/lib/ast/types.ts @@ -13,6 +13,7 @@ export interface AstNode { canonicalName?: string; linearizedBaseContracts?: number[]; members?: AstNode[]; + underlyingType?: AstNode; nodes?: AstNode[]; nodeType: string; ast_type?: string; //HACK: Vyper equivalent of nodeType diff --git a/packages/codec/lib/ast/utils.ts b/packages/codec/lib/ast/utils.ts index 4e21f9ace3c..38ed7676fe3 100644 --- a/packages/codec/lib/ast/utils.ts +++ b/packages/codec/lib/ast/utils.ts @@ -216,6 +216,8 @@ export function contractKind(definition: AstNode): Common.ContractKind { /** * stack size, in words, of a given type + * note: this function assumes that UDVTs only ever take up + * a single word, which is currently true * @category Definition Reading */ export function stackSize(definition: AstNode): number { @@ -480,6 +482,18 @@ export function functionKind(node: AstNode): string | undefined { return node.name === "" ? "fallback" : "function"; } +//this is kind of a weird one, it exposes some Solidity internals. +//for internal functions it'll return "internal". +//for external functions it'll return "external". +//for library functions it'll return "delegatecall". +//and for builtin functions, it'll return an internal name for +//that particular builtin function. +//(there are more possibilities but I'm not going to list them all here) +export function functionClass(node: AstNode): string | undefined { + const match = typeIdentifier(node).match(/^t_function_([^_]+)_/); + return match ? match[1] : undefined; +} + /** * similar compatibility function for mutability for pre-0.4.16 versions * returns undefined if you don't give it a FunctionDefinition or @@ -744,19 +758,33 @@ function toAbiType(node: AstNode, referenceDeclarations: AstNodes): string { return "address"; case "struct": return "tuple"; //the more detailed checking will be handled elsewhere - case "enum": - let referenceId = typeId(node); - let referenceDeclaration = referenceDeclarations[referenceId]; + case "enum": { + const referenceId = typeId(node); + const referenceDeclaration = referenceDeclarations[referenceId]; if (referenceDeclaration === undefined) { - let typeToDisplay = typeString(node); + const typeToDisplay = typeString(node); throw new Common.UnknownUserDefinedTypeError( referenceId.toString(), typeToDisplay ); } - let numOptions = referenceDeclaration.members.length; - let bits = 8 * Math.ceil(Math.log2(numOptions) / 8); + const numOptions = referenceDeclaration.members.length; + const bits = 8 * Math.ceil(Math.log2(numOptions) / 8); return `uint${bits}`; + } + case "userDefinedValueType": { + const referenceId = typeId(node); + const referenceDeclaration = referenceDeclarations[referenceId]; + if (referenceDeclaration === undefined) { + const typeToDisplay = typeString(node); + throw new Common.UnknownUserDefinedTypeError( + referenceId.toString(), + typeToDisplay + ); + } + const underlyingType = referenceDeclaration.underlyingType; + return toAbiType(underlyingType, referenceDeclarations); + } default: return basicType; //note that: int/uint/fixed/ufixed/bytes will have their size and such left on; diff --git a/packages/codec/lib/basic/allocate/index.ts b/packages/codec/lib/basic/allocate/index.ts index c2cf691bcb2..e64cf271d02 100644 --- a/packages/codec/lib/basic/allocate/index.ts +++ b/packages/codec/lib/basic/allocate/index.ts @@ -30,9 +30,9 @@ export function byteLength( } case "bytes": //we assume we're in the static case return (dataType).length; - case "enum": //the only complex case! + case "enum": { const storedType = userDefinedTypes[dataType.id]; - if (!storedType.options) { + if (!storedType || !storedType.options) { throw new Common.UnknownUserDefinedTypeError( dataType.id, Format.Types.typeString(dataType) @@ -40,5 +40,17 @@ export function byteLength( } const numValues = storedType.options.length; return Math.ceil(Math.log2(numValues) / 8); + } + case "userDefinedValueType": { + const storedType = userDefinedTypes[dataType.id]; + if (!storedType || !storedType.underlyingType) { + throw new Common.UnknownUserDefinedTypeError( + dataType.id, + Format.Types.typeString(dataType) + ); + } + const { underlyingType } = storedType; + return byteLength(underlyingType, userDefinedTypes); + } } } diff --git a/packages/codec/lib/basic/decode/index.ts b/packages/codec/lib/basic/decode/index.ts index 94bca7d6050..b7e75b34a15 100644 --- a/packages/codec/lib/basic/decode/index.ts +++ b/packages/codec/lib/basic/decode/index.ts @@ -36,6 +36,57 @@ export function* decodeBasic( debug("pointer %o", pointer); switch (dataType.typeClass) { + case "userDefinedValueType": { + const fullType = ( + Format.Types.fullType(dataType, info.userDefinedTypes) + ); + if (!fullType.underlyingType) { + const error = { + kind: "UserDefinedTypeNotFoundError" as const, + type: fullType, + }; + if (strict || options.allowRetry) { + throw new StopDecodingError(error, true); + //note that we allow a retry if we couldn't locate the underlying type! + } + return { + type: fullType, + kind: "error" as const, + error + }; + } + const underlyingResult = yield* decodeBasic( + fullType.underlyingType, + pointer, + info, + options + ); + switch (underlyingResult.kind) { //yes this switch is a little unnecessary :P + case "value": + //wrap the value and return + return { //no idea why need coercion here + type: fullType, + kind: "value" as const, + value: underlyingResult + }; + case "error": + //wrap the error and return an error result! + //this is inconsistent with how we handle other container types + //(structs, arrays, mappings), where having an error in one element + //does not cause an error in the whole thing, but to do that here + //would cause problems for the type system :-/ + //so we'll just be inconsistent + return { //TS is being bad again :-/ + type: fullType, + kind: "error" as const, + error: { + kind: "WrappedError", + error: underlyingResult + } + }; + } + break; //to satisfy TS :P + } case "bool": { if (!checkPadding(bytes, dataType, paddingMode)) { let error = { @@ -653,7 +704,7 @@ function checkPadding( userDefinedTypes?: Format.Types.TypesById ): boolean { const length = byteLength(dataType, userDefinedTypes); - let paddingType = getPaddingType(dataType, paddingMode); + const paddingType = getPaddingType(dataType, paddingMode); if (paddingMode === "permissive") { switch (dataType.typeClass) { case "bool": @@ -686,11 +737,10 @@ function removePaddingDirect( paddingType: PaddingType ) { switch (paddingType) { - case "left": - case "signed": - return bytes.slice(-length); case "right": return bytes.slice(0, length); + default: + return bytes.slice(-length); } } @@ -706,6 +756,8 @@ function checkPaddingDirect( return checkPaddingRight(bytes, length); case "signed": return checkPaddingSigned(bytes, length); + case "signedOrLeft": + return checkPaddingSigned(bytes, length) || checkPaddingLeft(bytes, length); } } @@ -719,9 +771,14 @@ function getPaddingType( case "default": case "permissive": return defaultPaddingType(dataType); - case "zero": - let defaultType = defaultPaddingType(dataType); + case "zero": { + const defaultType = defaultPaddingType(dataType); return defaultType === "signed" ? "left" : defaultType; + } + case "defaultOrZero": { + const defaultType = defaultPaddingType(dataType); + return defaultType === "signed" ? "signedOrLeft" : defaultType; + } } } diff --git a/packages/codec/lib/basic/encode/index.ts b/packages/codec/lib/basic/encode/index.ts index 0c8072c78c6..53c2606c8d7 100644 --- a/packages/codec/lib/basic/encode/index.ts +++ b/packages/codec/lib/basic/encode/index.ts @@ -15,6 +15,8 @@ import * as Evm from "@truffle/codec/evm"; export function encodeBasic(input: Format.Values.Value): Uint8Array { let bytes: Uint8Array; switch (input.type.typeClass) { + case "userDefinedValueType": + return encodeBasic((input).value); case "uint": case "int": return Conversion.toBytes( diff --git a/packages/codec/lib/common/types.ts b/packages/codec/lib/common/types.ts index 1fba462fa5c..1209eebe6c9 100644 --- a/packages/codec/lib/common/types.ts +++ b/packages/codec/lib/common/types.ts @@ -18,16 +18,17 @@ export type ContractKind = "contract" | "library" | "interface"; /** * @Category Enumerations */ -export type PaddingMode = "default" | "permissive" | "zero" | "right"; +export type PaddingMode = "default" | "permissive" | "zero" | "right" | "defaultOrZero"; //default: check padding; the type of padding is determined by the type //permissive: like default, but turns off the check on certain types //zero: forces zero-padding even on signed types //right: forces right-padding on all types +//defaultOrZero: allows either default or zero /** * @Category Enumerations */ -export type PaddingType = "left" | "right" | "signed"; +export type PaddingType = "left" | "right" | "signed" | "signedOrLeft"; /** diff --git a/packages/codec/lib/compilations/utils.ts b/packages/codec/lib/compilations/utils.ts index 49aa0aefe32..78f69bda922 100644 --- a/packages/codec/lib/compilations/utils.ts +++ b/packages/codec/lib/compilations/utils.ts @@ -9,7 +9,7 @@ import type { GeneratedSources } from "@truffle/contract-schema/spec"; import type * as Common from "@truffle/compile-common"; -import type * as Format from "@truffle/codec/format"; +import * as Format from "@truffle/codec/format"; import type { Compilation, Contract, @@ -472,12 +472,17 @@ export function collectUserDefinedTypesAndTaggedOutputs( compilations: Compilation[] ): { definitions: { [compilationId: string]: AstNodes }; + typesByCompilation: Format.Types.TypesByCompilationAndId; types: Format.Types.TypesById; } { let references: { [compilationId: string]: AstNodes } = {}; - let types: Format.Types.TypesById = {}; + let types: Format.Types.TypesByCompilationAndId = {}; for (const compilation of compilations) { references[compilation.id] = {}; + types[compilation.id] = { + compiler: compilation.compiler, + types: {} + }; for (const source of compilation.sources) { if (!source) { continue; //remember, sources could be empty if shimmed! @@ -489,6 +494,7 @@ export function collectUserDefinedTypesAndTaggedOutputs( if ( node.nodeType === "StructDefinition" || node.nodeType === "EnumDefinition" || + node.nodeType === "UserDefinedValueTypeDefinition" || node.nodeType === "ContractDefinition" ) { references[compilation.id][node.id] = node; @@ -499,7 +505,7 @@ export function collectUserDefinedTypesAndTaggedOutputs( compiler, references[compilation.id] ); - types[dataType.id] = dataType; + types[compilation.id].types[dataType.id] = dataType; } else if ( node.nodeType === "EventDefinition" || node.nodeType === "ErrorDefinition" @@ -510,7 +516,8 @@ export function collectUserDefinedTypesAndTaggedOutputs( for (const subNode of node.nodes) { if ( subNode.nodeType === "StructDefinition" || - subNode.nodeType === "EnumDefinition" + subNode.nodeType === "EnumDefinition" || + subNode.nodeType === "UserDefinedValueTypeDefinition" ) { references[compilation.id][subNode.id] = subNode; //we don't have all the references yet, but we only need the @@ -521,7 +528,7 @@ export function collectUserDefinedTypesAndTaggedOutputs( compiler, references[compilation.id] ); - types[dataType.id] = dataType; + types[compilation.id].types[dataType.id] = dataType; } else if ( subNode.nodeType === "EventDefinition" || subNode.nodeType === "ErrorDefinition" @@ -534,7 +541,11 @@ export function collectUserDefinedTypesAndTaggedOutputs( } } } - return { definitions: references, types }; + return { + definitions: references, + typesByCompilation: types, + types: Format.Types.forgetCompilations(types) + }; } function projectInfoIsCodecStyle( diff --git a/packages/codec/lib/compiler/types.ts b/packages/codec/lib/compiler/types.ts index 8f2b2d69660..dc4233189d2 100644 --- a/packages/codec/lib/compiler/types.ts +++ b/packages/codec/lib/compiler/types.ts @@ -7,5 +7,11 @@ export interface CompilerVersion { //NOTE: Families 0.5.0 and up will be named by the lowest version that //fits in the given family. So e.g. 0.5.x covers 0.5.x-0.7.x; -//0.8.x covers 0.8.x-current (as I write this) -export type SolidityFamily = "unknown" | "pre-0.5.0" | "0.5.x" | "0.8.x"; +//0.8.x covers 0.8.0-0.8.6; 0.8.7+ covers 0.8.7 to current (as I write this) +export type SolidityFamily = + | "unknown" + | "pre-0.5.0" + | "0.5.x" + | "0.8.x" + | "0.8.7+" + | "0.8.9+"; diff --git a/packages/codec/lib/compiler/utils.ts b/packages/codec/lib/compiler/utils.ts index 48009279fc8..3a278c2f842 100644 --- a/packages/codec/lib/compiler/utils.ts +++ b/packages/codec/lib/compiler/utils.ts @@ -9,11 +9,23 @@ export function solidityFamily(compiler: CompilerVersion): SolidityFamily { return "unknown"; } if ( - semver.satisfies(compiler.version, "~0.8 || >=0.8.0", { + semver.satisfies(compiler.version, ">=0.8.9", { + includePrerelease: true + }) + ) { + return "0.8.9+"; + } else if ( + semver.satisfies(compiler.version, ">=0.8.7", { includePrerelease: true }) ) { + return "0.8.7+"; + } else if ( //see comment below about the weird-looking condition + semver.satisfies(compiler.version, "~0.8 || >=0.8.0", { + includePrerelease: true + }) + ) { return "0.8.x"; } else if ( semver.satisfies(compiler.version, "~0.5 || >=0.5.0", { diff --git a/packages/codec/lib/core.ts b/packages/codec/lib/core.ts index b8cfa1b8f5a..d85c9d62ba5 100644 --- a/packages/codec/lib/core.ts +++ b/packages/codec/lib/core.ts @@ -4,6 +4,7 @@ const debug = debugModule("codec:core"); import type * as Abi from "@truffle/abi-utils"; import * as Ast from "@truffle/codec/ast"; import * as AbiData from "@truffle/codec/abi-data"; +import * as Compiler from "@truffle/codec/compiler"; import * as Topic from "@truffle/codec/topic"; import type * as Pointer from "@truffle/codec/pointer"; import type { @@ -850,7 +851,7 @@ function* decodeBytecode( value = yield* decode(dataType, variable.pointer, info, { allowRetry: true, //we know we're in full mode strictAbiMode: true, - paddingMode: "zero" //force zero-padding! + paddingMode: "defaultOrZero" }); } catch (error) { if (error instanceof StopDecodingError && error.allowRetry) { diff --git a/packages/codec/lib/decode.ts b/packages/codec/lib/decode.ts index afa1e026831..0ce63ba99f9 100644 --- a/packages/codec/lib/decode.ts +++ b/packages/codec/lib/decode.ts @@ -3,6 +3,7 @@ const debug = debugModule("codec:decode"); import * as AstConstant from "@truffle/codec/ast-constant"; import * as AbiData from "@truffle/codec/abi-data"; +import * as Compiler from "@truffle/codec/compiler"; import * as Format from "@truffle/codec/format"; import type * as Pointer from "@truffle/codec/pointer"; import * as Basic from "@truffle/codec/basic"; @@ -62,19 +63,29 @@ function* decodeDispatch( case "nowhere": //currently only basic types can go in code, so we'll dispatch directly to decodeBasic //(if it's a nowhere pointer, this will return an error result, of course) - //also: we force zero-padding! + //(also, Solidity <0.8.9 would always zero-pad immutables regardless of type, + //so we have to set the padding mode appropriately to allow for this) return yield* Basic.Decode.decodeBasic(dataType, pointer, info, { ...options, - paddingMode: "zero" + paddingMode: "defaultOrZero" }); case "memory": //this case -- decoding something that resides *directly* in memory, //rather than located via a pointer -- only comes up when decoding immutables - //in a constructor. thus, we turn on the forceRightPadding option. - return yield* Memory.Decode.decodeMemory(dataType, pointer, info, { - ...options, - paddingMode: "right" - }); + //in a constructor. thus, we turn on the forceRightPadding option on Solidity + //versions prior to 0.8.9, because before then all immutables would be right-padded + //while in memory + switch (Compiler.Utils.solidityFamily(info.currentContext.compiler)) { + case "0.5.x": + case "0.8.x": + case "0.8.7+": + return yield* Memory.Decode.decodeMemory(dataType, pointer, info, { + ...options, + paddingMode: "right" + }); + default: + return yield* Memory.Decode.decodeMemory(dataType, pointer, info, options); + } } } diff --git a/packages/codec/lib/export.ts b/packages/codec/lib/export.ts index fe41c79c443..4a81e8054a6 100644 --- a/packages/codec/lib/export.ts +++ b/packages/codec/lib/export.ts @@ -119,7 +119,8 @@ function ethersCompatibleNativize( case "bool": return (result).value.asBoolean; case "bytes": - return (result).value.asHex; + const asHex = (result).value.asHex; + return asHex !== "0x" ? asHex : null; case "address": return (result).value.asAddress; case "contract": @@ -138,6 +139,11 @@ function ethersCompatibleNativize( ).toString(); } } + case "userDefinedValueType": + return ethersCompatibleNativize( + (result).value, + numberFormatter + ); case "array": return (result).value.map(value => ethersCompatibleNativize(value, numberFormatter) diff --git a/packages/codec/lib/format/elementary.ts b/packages/codec/lib/format/elementary.ts index 63f673c6d5b..7ae2bb45ace 100644 --- a/packages/codec/lib/format/elementary.ts +++ b/packages/codec/lib/format/elementary.ts @@ -19,8 +19,18 @@ export type ElementaryValue = | FixedValue | UfixedValue | EnumValue + | UserDefinedValueTypeValue | ContractValue; +export type BuiltInValueValue = + | UintValue + | IntValue + | BoolValue + | BytesStaticValue + | AddressValue + | FixedValue + | UfixedValue; + /** * A bytestring value (static or dynamic) * @@ -208,6 +218,17 @@ export interface EnumValue { }; } +/** + * A UDVT value + * + * @Category User-defined elementary types + */ +export interface UserDefinedValueTypeValue { + type: Types.UserDefinedValueTypeType; + kind: "value"; + value: BuiltInValueValue; +} + /** * A contract value; see [[ContractValueInfo]] for more detail * diff --git a/packages/codec/lib/format/errors.ts b/packages/codec/lib/format/errors.ts index aa7edf88855..ef86a18efbb 100644 --- a/packages/codec/lib/format/errors.ts +++ b/packages/codec/lib/format/errors.ts @@ -39,6 +39,24 @@ export type ErrorResult = | FunctionExternalErrorResult | FunctionInternalErrorResult; +/** + * An error result for an ABI type + * + * @Category General categories + */ +export type AbiErrorResult = + | UintErrorResult + | IntErrorResult + | BoolErrorResult + | BytesErrorResult + | AddressErrorResult + | FixedErrorResult + | UfixedErrorResult + | StringErrorResult + | ArrayErrorResult + | FunctionExternalErrorResult + | TupleErrorResult; + /** * One of the underlying errors contained in an [[ErrorResult]] * @@ -62,6 +80,7 @@ export type DecoderError = | TypeErrorUnion | TupleError | EnumError + | UserDefinedValueTypeError | ContractError | FunctionExternalError | FunctionInternalError @@ -86,8 +105,23 @@ export type ElementaryErrorResult = | FixedErrorResult | UfixedErrorResult | EnumErrorResult + | UserDefinedValueTypeErrorResult | ContractErrorResult; +/** + * An error result for a built-in value type + * + * @Category Elementary types + */ +export type BuiltInValueErrorResult = + | UintErrorResult + | IntErrorResult + | BoolErrorResult + | BytesStaticErrorResult + | AddressErrorResult + | FixedErrorResult + | UfixedErrorResult; + /** * An error result for a bytestring * @@ -426,6 +460,35 @@ export interface EnumNotFoundDecodingError { rawAsBN: BN; } +/** + * An error result for a user-defined value type + * + * @Category User-defined elementary types + */ +export interface UserDefinedValueTypeErrorResult { + type: Types.UserDefinedValueTypeType; + kind: "error"; + error: GenericError | UserDefinedValueTypeError; +} + +/** + * A UDVT-specific error + * + * @Category User-defined elementary types + */ +export type UserDefinedValueTypeError = WrappedError; + +/** + * An error result representing something going wrong decoding + * the underlying type when decoding a UDVT + * + * @Category User-defined elementary types + */ +export interface WrappedError { + kind: "WrappedError"; + error: BuiltInValueErrorResult; +} + /** * An error result for a contract * @@ -719,6 +782,7 @@ export type GenericError = | UserDefinedTypeNotFoundError | IndexedReferenceTypeError | ReadError; + /** * A read error * @@ -730,6 +794,7 @@ export type ReadError = | ReadErrorBytes | ReadErrorStorage | UnusedImmutableError; + /** * An error resulting from overlarge length or pointer values * diff --git a/packages/codec/lib/format/types.ts b/packages/codec/lib/format/types.ts index c1953227700..64fcee3fb6f 100644 --- a/packages/codec/lib/format/types.ts +++ b/packages/codec/lib/format/types.ts @@ -25,6 +25,7 @@ const debug = debugModule("codec:format:types"); import type BN from "bn.js"; import type { ContractKind, Location, Mutability } from "@truffle/codec/common"; +import type { CompilerVersion } from "@truffle/codec/compiler"; /** * Object representing a type @@ -45,6 +46,7 @@ export type Type = | FunctionType | StructType | EnumType + | UserDefinedValueTypeType | ContractType | MagicType | TypeType @@ -226,8 +228,41 @@ export type ElementaryType = | AddressType | StringType | EnumType + | UserDefinedValueTypeType | ContractType; +/** + * Types that can underlie a user-defined value type + * + * @Category General categories + */ +export type BuiltInValueType = + | UintType + | IntType + | BoolType + | BytesTypeStatic + | FixedType + | UfixedType + | AddressTypeSpecific; //UDVTs only exist on 0.8.8 and later + +/** + * Types that can go in the ABI + * + * @Category General categories + */ +export type AbiType = + | UintType + | IntType + | BoolType + | BytesType + | AddressTypeGeneral + | FixedType + | UfixedType + | StringType + | ArrayType + | FunctionExternalTypeGeneral + | TupleType; + /** * Type of a mapping * @@ -303,7 +338,11 @@ export interface FunctionExternalTypeGeneral { * * @Category General categories */ -export type ContractDefinedType = StructTypeLocal | EnumTypeLocal; +export type ContractDefinedType = + | StructTypeLocal + | EnumTypeLocal + | UserDefinedValueTypeTypeLocal; + /** * User-defined types * @@ -313,7 +352,8 @@ export type UserDefinedType = | ContractDefinedType | ContractTypeNative | StructTypeGlobal - | EnumTypeGlobal; + | EnumTypeGlobal + | UserDefinedValueTypeTypeGlobal; /** * Type of a struct @@ -486,6 +526,49 @@ export interface ContractTypeForeign { //now } +/** + * Type of a user-defined value type + * + * These may be local (defined in a contract) or global (defined outside of any contract) + * + * @Category User-defined elementary types + */ +export type UserDefinedValueTypeType = UserDefinedValueTypeTypeLocal | UserDefinedValueTypeTypeGlobal; + +/** + * Local UDVT (defined in a contract) + * + * @Category User-defined elementary types + */ +export interface UserDefinedValueTypeTypeLocal { + typeClass: "userDefinedValueType"; + kind: "local"; + /** + * Internal ID. Format may change in future. + */ + id: string; + typeName: string; + definingContractName: string; + definingContract?: ContractTypeNative; + underlyingType?: BuiltInValueType; +} + +/** + * Global UDVT (defined outside a contract) + * + * @Category User-defined elementary types + */ +export interface UserDefinedValueTypeTypeGlobal { + typeClass: "userDefinedValueType"; + kind: "global"; + /** + * Internal ID. Format may change in future. + */ + id: string; + typeName: string; + underlyingType?: BuiltInValueType; +} + export type MagicVariableName = "message" | "block" | "transaction"; /** @@ -551,8 +634,24 @@ export interface TypesById { [id: string]: UserDefinedType; } +export interface TypesByCompilationAndId { + [compilationId: string]: { + compiler: CompilerVersion; + types: TypesById; + }; +} + +export function forgetCompilations( + typesByCompilation: TypesByCompilationAndId +): TypesById { + return Object.assign( + {}, + ...Object.values(typesByCompilation).map(({ types }) => types) + ); +} + function isUserDefinedType(anyType: Type): anyType is UserDefinedType { - const userDefinedTypes = ["contract", "enum", "struct"]; + const userDefinedTypes = ["contract", "enum", "struct", "userDefinedValueType"]; return userDefinedTypes.includes(anyType.typeClass); } @@ -698,6 +797,16 @@ export function typeStringWithoutLocation(dataType: Type): string { case "global": return `${dataType.typeClass} ${dataType.typeName}`; } + break; //to satisfy TS :P + case "userDefinedValueType": + //differs from struct & enum in that typeClass is omitted + switch (dataType.kind) { + case "local": + return `${dataType.definingContractName}.${dataType.typeName}`; + case "global": + return `${dataType.typeName}`; + } + break; //to satisfy TS :P case "tuple": return ( dataType.typeHint || @@ -749,6 +858,7 @@ export function typeStringWithoutLocation(dataType: Type): string { export function isContractDefinedType( anyType: Type ): anyType is ContractDefinedType { - const contractDefinedTypes = ["enum", "struct"]; - return contractDefinedTypes.includes(anyType.typeClass); + const contractDefinedTypes = ["enum", "struct", "userDefinedValueType"]; + return contractDefinedTypes.includes(anyType.typeClass) + && (anyType).kind === "local"; } diff --git a/packages/codec/lib/format/utils/inspect.ts b/packages/codec/lib/format/utils/inspect.ts index 479d6061038..65d4639a2ef 100644 --- a/packages/codec/lib/format/utils/inspect.ts +++ b/packages/codec/lib/format/utils/inspect.ts @@ -2,7 +2,7 @@ import debugModule from "debug"; const debug = debugModule("codec:format:utils:inspect"); import util from "util"; -import type * as Format from "@truffle/codec/format/common"; +import * as Format from "@truffle/codec/format/common"; import * as Exception from "./exception"; //we'll need to write a typing for the options type ourself, it seems; just @@ -150,6 +150,15 @@ export class ResultInspector { options ); } + case "userDefinedValueType": { + const typeName = Format.Types.typeStringWithoutLocation(this.result.type); + const coercedResult = this.result; + const inspectOfUnderlying = util.inspect( + new ResultInspector(coercedResult.value), + options + ); + return `${typeName}.wrap(${inspectOfUnderlying})`; //note only the underlying part is stylized + } case "tuple": { let coercedResult = this.result; //if everything is named, do same as with struct. @@ -291,6 +300,11 @@ export class ResultInspector { debug("this.result: %O", this.result); let errorResult = this.result; //the hell?? why couldn't it make this inference?? switch (errorResult.error.kind) { + case "WrappedError": + return util.inspect( + new ResultInspector(errorResult.error.error), + options + ); case "UintPaddingError": return `Uint has incorrect padding (expected padding: ${errorResult.error.paddingType}) (raw value ${errorResult.error.raw})`; case "IntPaddingError": @@ -383,7 +397,7 @@ class ContractInfoInspector { } } -function enumTypeName(enumType: Format.Types.EnumType) { +function enumTypeName(enumType: Format.Types.EnumType): string { return ( (enumType.kind === "local" ? enumType.definingContractName + "." : "") + enumType.typeName @@ -529,6 +543,9 @@ function unsafeNativizeWithTable( return seenSoFar[coercedResult.reference - 1]; } } + case "userDefinedValueType": { + return unsafeNativize((result).value); + } case "mapping": return Object.assign( {}, diff --git a/packages/codec/lib/format/values.ts b/packages/codec/lib/format/values.ts index 23f80970c49..5c85a3c2ad9 100644 --- a/packages/codec/lib/format/values.ts +++ b/packages/codec/lib/format/values.ts @@ -26,11 +26,13 @@ import type { BoolValue, BytesStaticValue, BytesDynamicValue, + BytesValue, AddressValue, StringValue, FixedValue, UfixedValue, EnumValue, + UserDefinedValueTypeValue, ContractValue, ContractValueInfoKnown, ContractValueInfoUnknown @@ -75,6 +77,42 @@ export type Value = | FunctionExternalValue | FunctionInternalValue; +/** + * A value that can go in the ABI + * + * @Category General categories + */ +export type AbiValue = + | UintValue + | IntValue + | BoolValue + | BytesValue + | AddressValue + | FixedValue + | UfixedValue + | StringValue + | ArrayValue + | FunctionExternalValue + | TupleValue; + +/** + * A result for an ABI type + * + * @Category General categories + */ +export type AbiResult = + | UintResult + | IntResult + | BoolResult + | BytesResult + | AddressResult + | FixedResult + | UfixedResult + | StringResult + | ArrayResult + | FunctionExternalResult + | TupleResult; + /* * SECTION 2: Built-in elementary types */ @@ -98,6 +136,7 @@ export type ElementaryResult = | FixedResult | UfixedResult | EnumResult + | UserDefinedValueTypeResult | ContractResult; /** @@ -185,6 +224,13 @@ export type UfixedResult = UfixedValue | Errors.UfixedErrorResult; */ export type EnumResult = EnumValue | Errors.EnumErrorResult; +/** + * A UDVT value or error + * + * @Category User-defined elementary types + */ +export type UserDefinedValueTypeResult = UserDefinedValueTypeValue | Errors.UserDefinedValueTypeErrorResult; + /** * A contract value or error * diff --git a/packages/codec/lib/special/decode/index.ts b/packages/codec/lib/special/decode/index.ts index 4588781e3c7..6eb6a3dccb6 100644 --- a/packages/codec/lib/special/decode/index.ts +++ b/packages/codec/lib/special/decode/index.ts @@ -109,6 +109,9 @@ export function* decodeMagic( if (solidityVersionHasChainId(info.currentContext.compiler)) { variables.push("chainid"); } + if (solidityVersionHasBaseFee(info.currentContext.compiler)) { + variables.push("basefee"); + } for (let variable of variables) { block[variable] = yield* Basic.Decode.decodeBasic( { @@ -143,7 +146,7 @@ function senderType( kind: "specific", payable: true }; - case "0.8.x": + default: return { typeClass: "address", kind: "specific", @@ -164,6 +167,8 @@ function coinbaseType( }; case "0.5.x": case "0.8.x": + case "0.8.7+": + case "0.8.9+": return { typeClass: "address", kind: "specific", @@ -180,7 +185,21 @@ function solidityVersionHasChainId( case "pre-0.5.0": case "0.5.x": return false; + default: + return true; + } +} + +function solidityVersionHasBaseFee( + compiler: Compiler.CompilerVersion +): boolean { + switch (Compiler.Utils.solidityFamily(compiler)) { + case "unknown": + case "pre-0.5.0": + case "0.5.x": case "0.8.x": + return false; + default: return true; } } diff --git a/packages/codec/lib/storage/allocate/index.ts b/packages/codec/lib/storage/allocate/index.ts index db4ffcbae57..ebecaf305bf 100644 --- a/packages/codec/lib/storage/allocate/index.ts +++ b/packages/codec/lib/storage/allocate/index.ts @@ -1,7 +1,7 @@ import debugModule from "debug"; const debug = debugModule("codec:storage:allocate"); -import type * as Compiler from "@truffle/codec/compiler"; +import * as Compiler from "@truffle/codec/compiler"; import * as Common from "@truffle/codec/common"; import * as Basic from "@truffle/codec/basic"; import type * as Storage from "@truffle/codec/storage/types"; @@ -61,19 +61,27 @@ interface StorageAllocationInfo { //contracts contains only the contracts to be allocated; any base classes not //being allocated should just be in referenceDeclarations export function getStorageAllocations( - userDefinedTypes: Format.Types.TypesById + userDefinedTypesByCompilation: Format.Types.TypesByCompilationAndId ): StorageAllocations { let allocations: StorageAllocations = {}; - for (const dataType of Object.values(userDefinedTypes)) { - if (dataType.typeClass === "struct") { - try { - allocations = allocateStruct(dataType, userDefinedTypes, allocations); - } catch (_) { - //if allocation fails... oh well, allocation fails, we do nothing and just move on :P - //note: a better way of handling this would probably be to *mark* it - //as failed rather than throwing an exception as that would lead to less - //recomputation, but this is simpler and I don't think the recomputation - //should really be a problem + for (const compilation of Object.values(userDefinedTypesByCompilation)) { + const { compiler, types: userDefinedTypes } = compilation; + for (const dataType of Object.values(compilation.types)) { + if (dataType.typeClass === "struct") { + try { + allocations = allocateStruct( + dataType, + userDefinedTypes, + allocations, + compiler + ); + } catch { + //if allocation fails... oh well, allocation fails, we do nothing and just move on :P + //note: a better way of handling this would probably be to *mark* it + //as failed rather than throwing an exception as that would lead to less + //recomputation, but this is simpler and I don't think the recomputation + //should really be a problem + } } } } @@ -115,7 +123,7 @@ export function getStateAllocations( storageAllocations, allocations ); - } catch (_) { + } catch { //we're just going to allow failure here and catch the problem elsewhere } } @@ -125,7 +133,8 @@ export function getStateAllocations( function allocateStruct( dataType: Format.Types.StructType, userDefinedTypes: Format.Types.TypesById, - existingAllocations: StorageAllocations + existingAllocations: StorageAllocations, + compiler?: Compiler.CompilerVersion ): StorageAllocations { //NOTE: dataType here should be a *stored* type! //it is up to the caller to take care of this @@ -133,7 +142,8 @@ function allocateStruct( dataType.id, dataType.memberTypes, userDefinedTypes, - existingAllocations + existingAllocations, + compiler ); } @@ -141,7 +151,8 @@ function allocateMembers( parentId: string, members: Format.Types.NameTypePair[], userDefinedTypes: Format.Types.TypesById, - existingAllocations: StorageAllocations + existingAllocations: StorageAllocations, + compiler?: Compiler.CompilerVersion ): StorageAllocations { let offset: number = 0; //will convert to BN when placing in slot let index: number = Evm.Utils.WORD_SIZE - 1; @@ -161,7 +172,8 @@ function allocateMembers( ({ size, allocations } = storageSizeAndAllocate( member.type, userDefinedTypes, - allocations + allocations, + compiler )); //if it's sized in words (and we're not at the start of slot) we need to start on a new slot @@ -339,7 +351,7 @@ function allocateContractState( ); //transform storage variables into data types - let storageVariableTypes = storageVariables.map(variable => ({ + const storageVariableTypes = storageVariables.map(variable => ({ name: variable.definition.name, type: Ast.Import.definitionToType( variable.definition, @@ -350,15 +362,16 @@ function allocateContractState( //let's allocate the storage variables using a fictitious ID const id = "-1"; - let storageVariableStorageAllocations = allocateMembers( + const storageVariableStorageAllocations = allocateMembers( id, storageVariableTypes, userDefinedTypes, - storageAllocations + storageAllocations, + compiler )[id]; //transform to new format - let storageVariableAllocations = storageVariables.map( + const storageVariableAllocations = storageVariables.map( ({ definition, definedIn }, index) => ({ definition, definedIn, @@ -433,15 +446,22 @@ function allocateContractState( export function storageSize( dataType: Format.Types.Type, userDefinedTypes?: Format.Types.TypesById, - allocations?: StorageAllocations + allocations?: StorageAllocations, + compiler?: Compiler.CompilerVersion ): Storage.StorageLength { - return storageSizeAndAllocate(dataType, userDefinedTypes, allocations).size; + return storageSizeAndAllocate( + dataType, + userDefinedTypes, + allocations, + compiler + ).size; } function storageSizeAndAllocate( dataType: Format.Types.Type, userDefinedTypes?: Format.Types.TypesById, - existingAllocations?: StorageAllocations + existingAllocations?: StorageAllocations, + compiler?: Compiler.CompilerVersion ): StorageAllocationInfo { //we'll only directly handle reference types here; //direct types will be handled by dispatching to Basic.Allocate.byteLength @@ -541,10 +561,24 @@ function storageSizeAndAllocate( }; } + case "userDefinedValueType": + if (Compiler.Utils.solidityFamily(compiler) === "0.8.7+") { + //UDVTs were introduced in Solidity 0.8.8. However, in that version, + //and that version only, they have a bug where they always take up a + //full word in storage regardless of the size of the underlying type. + return { + size: { words: 1 }, + allocations: existingAllocations + }; + } + //otherwise, treat them normally + //DELIBERATE FALL-TRHOUGH default: //otherwise, it's a direct type return { - size: { bytes: Basic.Allocate.byteLength(dataType, userDefinedTypes) }, + size: { + bytes: Basic.Allocate.byteLength(dataType, userDefinedTypes) + }, allocations: existingAllocations }; } diff --git a/packages/codec/package.json b/packages/codec/package.json index 4a70571ce31..ef4b9f1547f 100644 --- a/packages/codec/package.json +++ b/packages/codec/package.json @@ -3,7 +3,7 @@ "description": "Library for encoding and decoding smart contract data", "license": "MIT", "author": "", - "homepage": "https://github.com/trufflesuite/truffle#readme", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/codec#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", @@ -12,7 +12,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "0.11.10", + "version": "0.11.17", "main": "dist/lib/index.js", "files": [ "dist" @@ -26,7 +26,7 @@ "types": "dist/lib/index.d.ts", "dependencies": { "@truffle/abi-utils": "^0.2.4", - "@truffle/compile-common": "^0.7.16", + "@truffle/compile-common": "^0.7.22", "big.js": "^5.2.2", "bn.js": "^5.1.3", "cbor": "^5.1.0", @@ -37,7 +37,7 @@ "lodash.sum": "^4.0.2", "semver": "^7.3.4", "utf8": "^3.0.0", - "web3-utils": "1.5.2" + "web3-utils": "1.5.3" }, "devDependencies": { "@truffle/contract-schema": "^3.4.3", diff --git a/packages/compile-common/package.json b/packages/compile-common/package.json index 7c86ffa386d..313a767129c 100644 --- a/packages/compile-common/package.json +++ b/packages/compile-common/package.json @@ -1,14 +1,18 @@ { "name": "@truffle/compile-common", - "version": "0.7.16", + "version": "0.7.22", "description": "Common compiler integration support infrastructure for Truffle", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/compile-common#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", "directory": "packages/compile-common" }, + "bugs": { + "url": "https://github.com/trufflesuite/truffle/issues" + }, "license": "MIT", "scripts": { "build": "tsc", @@ -17,9 +21,7 @@ "watch": "tsc -w" }, "devDependencies": { - "@truffle/config": "^1.3.4", "@truffle/contract-schema": "^3.4.3", - "@types/fs-extra": "^8.1.0", "@types/mocha": "^5.2.7", "@types/node": "12.12.21", "mocha": "8.0.1", @@ -27,11 +29,8 @@ "typescript": "^4.1.4" }, "dependencies": { - "@truffle/contract-sources": "^0.1.12", "@truffle/error": "^0.0.14", - "@truffle/expect": "^0.0.18", - "colors": "^1.4.0", - "debug": "^4.3.1" + "colors": "^1.4.0" }, "gitHead": "6b84be7849142588ef2e3224d8a9d7c2ceeb6e4a" } diff --git a/packages/compile-common/src/index.ts b/packages/compile-common/src/index.ts index 9ab9eacc465..92ee06d9f49 100644 --- a/packages/compile-common/src/index.ts +++ b/packages/compile-common/src/index.ts @@ -1,4 +1,3 @@ -export { Profiler } from "./profiler"; export * as Shims from "./shims"; export * as Sources from "./sources"; export * as Errors from "./errors"; diff --git a/packages/compile-common/src/profiler/index.ts b/packages/compile-common/src/profiler/index.ts deleted file mode 100644 index da933d17a3c..00000000000 --- a/packages/compile-common/src/profiler/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Profiler } from "./profiler"; diff --git a/packages/compile-common/src/sources.ts b/packages/compile-common/src/sources.ts index 5cfa72dc9c5..173d009fbba 100644 --- a/packages/compile-common/src/sources.ts +++ b/packages/compile-common/src/sources.ts @@ -18,6 +18,10 @@ export function collectSources( replacement: string = "/" ): CollectedSources { const mappedResults = Object.entries(originalSources) + .filter(([originalSourcePath, _]) => + !path.isAbsolute(originalSourcePath) || + originalSourcePath.startsWith(baseDirectory) + ) .map(([originalSourcePath, contents]) => ({ originalSourcePath, contents, diff --git a/packages/compile-common/tsconfig.json b/packages/compile-common/tsconfig.json index b070d09ee87..35c7e0f0370 100644 --- a/packages/compile-common/tsconfig.json +++ b/packages/compile-common/tsconfig.json @@ -13,10 +13,7 @@ "paths": { }, "rootDir": ".", - "types": ["node", "mocha"], - "typeRoots": [ - "../../node_modules/@types/fs-extra" - ] + "types": ["node", "mocha"] }, "include": [ "./src/**/*.ts" diff --git a/packages/compile-solidity/package.json b/packages/compile-solidity/package.json index 1900bf73ce5..413c09df43e 100644 --- a/packages/compile-solidity/package.json +++ b/packages/compile-solidity/package.json @@ -3,7 +3,7 @@ "description": "Compiler helper and artifact manager for Solidity files", "license": "MIT", "author": "Tim Coulter ", - "homepage": "https://github.com/trufflesuite/compile-solidity#readme", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/compile-solidity#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", @@ -12,17 +12,18 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "5.3.17", + "version": "5.3.25", "main": "index.js", "scripts": { "prepare": "exit 0", "test": "./scripts/test.sh" }, "dependencies": { - "@truffle/compile-common": "^0.7.16", - "@truffle/config": "^1.3.4", + "@truffle/compile-common": "^0.7.22", + "@truffle/config": "^1.3.10", "@truffle/contract-sources": "^0.1.12", "@truffle/expect": "^0.0.18", + "@truffle/profiler": "^0.1.1", "axios": "^0.21.1", "debug": "^4.3.1", "fs-extra": "^9.1.0", @@ -35,9 +36,9 @@ "solc": "0.6.9" }, "devDependencies": { - "@truffle/artifactor": "^4.0.118", - "@truffle/box": "^2.1.24", - "@truffle/resolver": "^7.0.24", + "@truffle/artifactor": "^4.0.126", + "@truffle/box": "^2.1.30", + "@truffle/resolver": "^7.0.32", "babel-core": "^6.26.0", "babel-polyfill": "^6.26.0", "babel-preset-env": "^1.6.1", diff --git a/packages/compile-solidity/profiler/index.js b/packages/compile-solidity/profiler/index.js index 6c39c31a634..e0e6d313454 100644 --- a/packages/compile-solidity/profiler/index.js +++ b/packages/compile-solidity/profiler/index.js @@ -2,13 +2,13 @@ // determines which .sol files have been updated. const debug = require("debug")("compile:profiler"); -const Common = require("@truffle/compile-common"); +const { Profiler } = require("@truffle/profiler"); const { loadParser } = require("./loadParser"); const { shouldIncludePath } = require("./shouldIncludePath"); module.exports = { updated: async options => { - const profiler = await new Common.Profiler({}); + const profiler = await new Profiler({}); return await profiler.updated(options); }, @@ -19,7 +19,7 @@ module.exports = { const parseImports = await loadParser(options); // generate profiler - const profiler = new Common.Profiler({ + const profiler = new Profiler({ parseImports, shouldIncludePath }); @@ -31,7 +31,7 @@ module.exports = { requiredSourcesForSingleFile: async options => { const parseImports = await loadParser(options); - const profiler = new Common.Profiler({ + const profiler = new Profiler({ parseImports, shouldIncludePath }); diff --git a/packages/compile-solidity/run.js b/packages/compile-solidity/run.js index b841e9e4518..b2a0be6f07b 100644 --- a/packages/compile-solidity/run.js +++ b/packages/compile-solidity/run.js @@ -45,11 +45,14 @@ async function run(rawSources, options, language = "Solidity") { // handle warnings as errors if options.strict // log if not options.quiet - const { warnings, errors } = detectErrors({ + const { infos, warnings, errors } = detectErrors({ compilerOutput, options, solcVersion }); + if (infos.length > 0) { + options.events.emit("compile:infos", { infos }); + } if (warnings.length > 0) { options.events.emit("compile:warnings", { warnings }); } @@ -238,7 +241,7 @@ async function invokeCompiler({ compilerInput, options }) { /** * Extract errors/warnings from compiler output based on strict mode setting - * @return { errors: string, warnings: string } + * @return { errors: string, warnings: string, infos: string } */ function detectErrors({ compilerOutput: { errors: outputErrors }, @@ -246,17 +249,21 @@ function detectErrors({ solcVersion }) { outputErrors = outputErrors || []; - const rawErrors = options.strict - ? outputErrors - : outputErrors.filter(({ severity }) => severity !== "warning"); + const rawErrors = outputErrors.filter( + ({ severity }) => options.strict + ? severity !== "info" //strict mode: warnings are errors too + : severity === "error" //nonstrict mode: only errors are errors + ); const rawWarnings = options.strict - ? [] // none of those in strict mode + ? [] // in strict mode these get classified as errors, not warnings : outputErrors.filter(({ severity, message }) => severity === "warning" && message !== "Yul is still experimental. Please use the output with care." //filter out Yul warning ); + const rawInfos = outputErrors.filter(({ severity }) => severity === "info"); + // extract messages let errors = rawErrors.map( ({ formattedMessage }) => formattedMessage.replace( @@ -265,6 +272,7 @@ function detectErrors({ ) ).join(); const warnings = rawWarnings.map(({ formattedMessage }) => formattedMessage); + const infos = rawInfos.map(({ formattedMessage }) => formattedMessage); if (errors.includes("requires different compiler version")) { const contractSolcVer = errors.match(/pragma solidity[^;]*/gm)[0]; @@ -287,7 +295,7 @@ function detectErrors({ ); } - return { warnings, errors }; + return { warnings, errors, infos }; } /** diff --git a/packages/compile-solidity/test/profiler/index.js b/packages/compile-solidity/test/profiler/index.js index 39cb1d2d1a3..232aa30201e 100644 --- a/packages/compile-solidity/test/profiler/index.js +++ b/packages/compile-solidity/test/profiler/index.js @@ -1,10 +1,10 @@ -var assert = require("chai").assert; -var fs = require("fs-extra"); -var glob = require("glob"); -var { default: Box } = require("@truffle/box"); -var Profiler = require("../../profiler"); -var Resolver = require("@truffle/resolver"); -var Artifactor = require("@truffle/artifactor"); +const assert = require("chai").assert; +const fs = require("fs-extra"); +const glob = require("glob"); +const { default: Box } = require("@truffle/box"); +const Profiler = require("../../profiler"); +const Resolver = require("@truffle/resolver"); +const Artifactor = require("@truffle/artifactor"); describe("profiler", function () { var config; diff --git a/packages/compile-solidity/test/test_nonrelative.js b/packages/compile-solidity/test/test_nonrelative.js index 4550abff24b..9db39de5ecf 100644 --- a/packages/compile-solidity/test/test_nonrelative.js +++ b/packages/compile-solidity/test/test_nonrelative.js @@ -4,6 +4,9 @@ const { Compile } = require("@truffle/compile-solidity"); const assert = require("assert"); const Resolver = require("@truffle/resolver"); const process = require("process"); +const tmp = require("tmp"); +tmp.setGracefulCleanup(); +const fs = require("fs"); describe("Non-relative non-absolute file paths", function () { this.timeout(5000); // solc @@ -59,3 +62,58 @@ describe("Non-relative non-absolute file paths", function () { process.chdir(originalWorkingDirectory); }); }); + +describe("Non-canonical absolute file paths", function () { + this.timeout(5000); // solc + let tmpdir; + let options; + + before("Set up temporary directory and project", async function () { + tmpdir = tmp.dirSync({ unsafeCleanup: true }).name; //tmp uses callbacks, not promises, so using sync + await fs.promises.mkdir(path.join(tmpdir, "./contracts")); + const contracts_directory = path.join(tmpdir, "./contracts"); + options = { + working_directory: tmpdir, + contracts_directory, + contracts_build_directory: path.join(tmpdir, "./build/contracts"), //nothing is actually written, but resolver demands it + compilers: { + solc: { + version: "0.8.6", + settings: { + optimizer: { + enabled: false, + runs: 200 + } + } + } + }, + quiet: true + }; + options.resolver = new Resolver(options); + const importedPath = path.join(options.contracts_directory, "Imported.sol"); + const importerPath = path.join(options.contracts_directory, "DoubleSlash.sol"); + await fs.promises.copyFile( + path.join(__dirname, "./sources/badSources/Imported.sol"), + importedPath + ); + await fs.promises.writeFile( + importerPath, + `import "/${importedPath}";` //note the extra slash + ); + }); + + it("Refuses to compile non-canonical absolute paths", async function () { + this.timeout(150000); + + try { + await Compile.all(options); + assert.fail("Compilation should have failed"); + } catch (error) { + debug("error: %O", error); + if(!error.message.match(/Source "\/\/[^"]*" not found/)) { + throw error; //rethrow errors that aren't the one we expect + } + //otherwise, we're good + } + }); +}); diff --git a/packages/compile-vyper/index.js b/packages/compile-vyper/index.js index 3aba4d1c17e..724dfc31290 100644 --- a/packages/compile-vyper/index.js +++ b/packages/compile-vyper/index.js @@ -7,8 +7,8 @@ const minimatch = require("minimatch"); const semver = require("semver"); const findContracts = require("@truffle/contract-sources"); -const Common = require("@truffle/compile-common"); const Config = require("@truffle/config"); +const { Profiler } = require("@truffle/profiler"); const { requiredSources } = require("./profiler"); const { compileJson } = require("./vyper-json"); @@ -316,7 +316,7 @@ const Compile = { async necessary(options) { options = Config.default().merge(options); - const profiler = await new Common.Profiler({}); + const profiler = await new Profiler({}); const updated = await profiler.updated(options); if (updated.length === 0) { return { compilations: [] }; diff --git a/packages/compile-vyper/package.json b/packages/compile-vyper/package.json index 915073dbeb7..16772a5f40c 100644 --- a/packages/compile-vyper/package.json +++ b/packages/compile-vyper/package.json @@ -3,21 +3,26 @@ "description": "Vyper compiler support", "license": "MIT", "author": "Evgeniy Filatov ", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/compile-vyper#readme", + "bugs": { + "url": "https://github.com/trufflesuite/truffle/issues" + }, "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", "directory": "packages/compile-vyper" }, - "version": "3.1.21", + "version": "3.1.29", "main": "index.js", "scripts": { "prepare": "exit 0", "test": "mocha" }, "dependencies": { - "@truffle/compile-common": "^0.7.16", - "@truffle/config": "^1.3.4", - "@truffle/resolver": "^7.0.24", + "@truffle/compile-common": "^0.7.22", + "@truffle/config": "^1.3.10", + "@truffle/profiler": "^0.1.1", + "@truffle/resolver": "^7.0.32", "colors": "^1.4.0", "debug": "^4.3.1", "lodash.partition": "^4.6.0", @@ -25,7 +30,7 @@ "semver": "^7.3.4" }, "devDependencies": { - "@truffle/code-utils": "^1.2.29", + "@truffle/code-utils": "^1.2.30", "mocha": "8.1.2" }, "keywords": [ diff --git a/packages/compile-vyper/profiler.js b/packages/compile-vyper/profiler.js index fbf2def4123..6b9fed47986 100644 --- a/packages/compile-vyper/profiler.js +++ b/packages/compile-vyper/profiler.js @@ -1,5 +1,5 @@ const debug = require("debug")("compile-vyper:profiler"); -const Common = require("@truffle/compile-common"); +const { Profiler } = require("@truffle/profiler"); const Resolver = require("@truffle/resolver"); const { parseImports } = require("./parser"); @@ -14,7 +14,7 @@ async function requiredSources(options) { debug("resolver.sources.length: %d", resolver.sources.length); // generate profiler - const profiler = new Common.Profiler({ + const profiler = new Profiler({ parseImports, shouldIncludePath }); diff --git a/packages/config/package.json b/packages/config/package.json index e8a025cb3e9..851a18bf537 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -12,7 +12,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "1.3.4", + "version": "1.3.10", "main": "dist/index.js", "scripts": { "build": "tsc", @@ -22,12 +22,13 @@ "types": "dist/index.d.ts", "dependencies": { "@truffle/error": "^0.0.14", - "@truffle/events": "^0.0.13", - "@truffle/provider": "^0.2.37", - "configstore": "^4.0.0", + "@truffle/events": "^0.0.16", + "@truffle/provider": "^0.2.42", + "conf": "^10.0.2", "find-up": "^2.1.0", "lodash.assignin": "^4.2.0", "lodash.merge": "^4.6.2", + "lodash.pick": "^4.4.0", "module": "^1.2.5", "original-require": "^1.0.1" }, @@ -36,6 +37,7 @@ "@types/find-up": "^2.1.0", "@types/lodash.assignin": "^4.2.6", "@types/lodash.merge": "^4.6.6", + "@types/lodash.pick": "^4.4.6", "@types/node": "12.12.21", "@types/sinon": "^9.0.10", "mocha": "8.1.2", diff --git a/packages/config/src/configDefaults.ts b/packages/config/src/configDefaults.ts index d420ac6e2a5..0b43c8a179c 100644 --- a/packages/config/src/configDefaults.ts +++ b/packages/config/src/configDefaults.ts @@ -1,4 +1,3 @@ -import assignIn from "lodash.assignin"; import * as path from "path"; import Provider from "@truffle/provider"; import TruffleConfig from "./"; @@ -78,11 +77,6 @@ export const configProps = ({ const resolveDirectory = (value: string): string => path.resolve(configObject.working_directory, value); - const defaultTXValues = { - gas: 6721975, - from: null - }; - return { // These are already set. truffle_directory() {}, @@ -158,8 +152,6 @@ export const configProps = ({ config = {}; } - config = assignIn({}, defaultTXValues, config); - return config; }, set() { @@ -173,7 +165,7 @@ export const configProps = ({ try { return configObject.network_config.from; } catch (e) { - return defaultTXValues.from; + return null; } }, set() { @@ -187,7 +179,7 @@ export const configProps = ({ try { return configObject.network_config.gas; } catch (e) { - return defaultTXValues.gas; + return null; } }, set() { diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 7895a8110dc..715895b1e94 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -1,9 +1,10 @@ import path from "path"; import assignIn from "lodash.assignin"; import merge from "lodash.merge"; +import pick from "lodash.pick"; import Module from "module"; import findUp from "find-up"; -import Configstore from "configstore"; +import Conf from "conf"; import TruffleError from "@truffle/error"; import originalRequire from "original-require"; import { getInitialConfig, configProps } from "./configDefaults"; @@ -40,10 +41,11 @@ class TruffleConfig { ); } - public eventManagerOptions(config: TruffleConfig): any { - let muteLogging; - const { quiet, logger, subscribers } = config; - return { logger, quiet, subscribers }; + private eventManagerOptions( + options: Partial + ): Partial> { + const optionsWhitelist = ["quiet", "logger", "subscribers"]; + return pick(options, optionsWhitelist); } public addProp(propertyName: string, descriptor: any): void { @@ -102,8 +104,12 @@ class TruffleConfig { const current = this.normalize(this); const normalized = this.normalize(obj); - let eventsOptions = this.eventManagerOptions(this); - this.events.updateSubscriberOptions(eventsOptions); + const currentEventsOptions = this.eventManagerOptions(this); + const optionsToMerge = this.eventManagerOptions(obj); + this.events.updateSubscriberOptions({ + ...currentEventsOptions, + ...optionsToMerge + }); return assignIn( Object.create(TruffleConfig.prototype), @@ -212,14 +218,13 @@ class TruffleConfig { return config; } - public static getUserConfig(): Configstore { - return new Configstore("truffle", {}, { globalConfigPath: true }); + public static getUserConfig(): Conf { + return new Conf({ projectName: "truffle" }); } public static getTruffleDataDirectory(): string { - const configStore = TruffleConfig.getUserConfig(); - - return path.dirname(configStore.path); + const conf = TruffleConfig.getUserConfig(); + return path.dirname(conf.path); } } diff --git a/packages/contract-tests/package.json b/packages/contract-tests/package.json index 2336c112693..4851f2cea41 100644 --- a/packages/contract-tests/package.json +++ b/packages/contract-tests/package.json @@ -4,7 +4,7 @@ "description": "Test suite for @truffle/contract smart contract abstraction (unpublished)", "license": "MIT", "author": "g. nicholas d'andrea ", - "homepage": "https://github.com/trufflesuite/truffle#readme", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/contract-tests#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", @@ -13,7 +13,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "0.1.49", + "version": "0.1.57", "scripts": { "prepare": "exit 0", "test": "./scripts/test.sh", @@ -22,15 +22,15 @@ }, "devDependencies": { "@truffle/blockchain-utils": "^0.0.31", - "@truffle/compile-solidity": "^5.3.17", - "@truffle/contract": "^4.3.30", + "@truffle/compile-solidity": "^5.3.25", + "@truffle/contract": "^4.3.38", "bignumber.js": "^7.2.1", "chai": "^4.2.0", "debug": "^4.3.1", "ganache-core": "2.13.0", "mocha": "8.0.1", "sinon": "^9.0.2", - "web3": "1.5.2", - "web3-core-promievent": "1.5.2" + "web3": "1.5.3", + "web3-core-promievent": "1.5.3" } } diff --git a/packages/contract/lib/execute.js b/packages/contract/lib/execute.js index 9b7a94c055c..9473918375b 100644 --- a/packages/contract/lib/execute.js +++ b/packages/contract/lib/execute.js @@ -13,35 +13,48 @@ const execute = { // ----------------------------------- Helpers -------------------------------------------------- /** * Retrieves gas estimate multiplied by the set gas multiplier for a `sendTransaction` call. + * Lacking an estimate, sets gas to have of latest blockLimit * @param {Object} params `sendTransaction` parameters * @param {Number} blockLimit most recent network block.blockLimit * @return {Number} gas estimate */ - getGasEstimate: function (params, blockLimit) { + getGasEstimate: function (params, blockLimit, stacktrace = false) { const constructor = this; const interfaceAdapter = this.interfaceAdapter; return new Promise(function (accept) { - // Always prefer specified gas - this includes gas set by class_defaults + // Always prefer gas specified by user (if a user sets gas to 0, that is treated + // as undefined here and we do proceed to do gas estimation) if (params.gas) return accept(params.gas); if (!constructor.autoGas) return accept(); interfaceAdapter - .estimateGas(params) + .estimateGas(params, stacktrace) .then(gas => { - const bestEstimate = utils.multiplyBigNumberByDecimal( - utils.bigNumberify(gas), - constructor.gasMultiplier - ); - - // Don't go over blockLimit - const limit = utils.bigNumberify(blockLimit); - bestEstimate.gte(limit) - ? accept(limit.sub(1).toHexString()) - : accept(bestEstimate.toHexString()); - - // We need to let txs that revert through. - // Often that's exactly what you are testing. + // there are situations where the web3 gas estimation function in interfaceAdapter + // fails, specifically when a transaction will revert; we still want to continue + // the user flow for debugging purposes if the user has enabled stacktraces; so we provide a + // default gas for that situation, equal to half of the blockLimit for the latest block + // + // note: this means if a transaction will revert but the user does not have stacktracing enabled, + // they will get an error from the gas estimation and be unable to proceed; we may need to revisit this + if (gas === null) { + const defaultGas = utils.bigNumberify(Math.floor(blockLimit/2)); + accept(defaultGas.toHexString()); + } else { + const limit = utils.bigNumberify(blockLimit); + // if we did get a numerical gas estimate from interfaceAdapter, we + // multiply that estimate by the gasMultiplier to help ensure we + // have enough gas for the transaction + const bestEstimate = utils.multiplyBigNumberByDecimal( + utils.bigNumberify(gas), + constructor.gasMultiplier + ); + // Check that we don't go over blockLimit + bestEstimate.gte(limit) + ? accept(limit.sub(1).toHexString()) + : accept(bestEstimate.toHexString()); + } }) .catch(() => accept()); }); @@ -189,11 +202,13 @@ const execute = { contract: constructor }); + const stacktrace = promiEvent.debug ? promiEvent.debug : false; try { params.gas = await execute.getGasEstimate.call( constructor, params, - network.blockLimit + network.blockLimit, + stacktrace ); } catch (error) { promiEvent.reject(error); @@ -252,11 +267,13 @@ const execute = { const contract = new web3.eth.Contract(constructor.abi); params.data = contract.deploy(options).encodeABI(); + const stacktrace = promiEvent.debug ? promiEvent.debug : false; params.gas = await execute.getGasEstimate.call( constructor, params, - blockLimit + blockLimit, + stacktrace ); context.params = params; diff --git a/packages/contract/package.json b/packages/contract/package.json index a828e562aa4..fadf8c149a5 100644 --- a/packages/contract/package.json +++ b/packages/contract/package.json @@ -12,7 +12,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "4.3.30", + "version": "4.3.38", "main": "index.js", "scripts": { "compile": "sh -c \"mkdir -p ./dist\" && browserify --debug ./index.js | exorcist ./dist/truffle-contract.js.map > ./dist/truffle-contract.js && uglifyjs ./dist/truffle-contract.js -o ./dist/truffle-contract.min.js", @@ -24,16 +24,16 @@ "@ensdomains/ensjs": "^2.0.1", "@truffle/blockchain-utils": "^0.0.31", "@truffle/contract-schema": "^3.4.3", - "@truffle/debug-utils": "^5.1.10", + "@truffle/debug-utils": "^5.1.18", "@truffle/error": "^0.0.14", - "@truffle/interface-adapter": "^0.5.4", + "@truffle/interface-adapter": "^0.5.8", "bignumber.js": "^7.2.1", "ethers": "^4.0.32", - "web3": "1.5.2", - "web3-core-helpers": "1.5.2", - "web3-core-promievent": "1.5.2", - "web3-eth-abi": "1.5.2", - "web3-utils": "1.5.2" + "web3": "1.5.3", + "web3-core-helpers": "1.5.3", + "web3-core-promievent": "1.5.3", + "web3-eth-abi": "1.5.3", + "web3-utils": "1.5.3" }, "devDependencies": { "browserify": "^17.0.0", diff --git a/packages/core/lib/command-options.js b/packages/core/lib/command-options.js index ee810d9b5a5..40e5c3389f7 100644 --- a/packages/core/lib/command-options.js +++ b/packages/core/lib/command-options.js @@ -8,6 +8,10 @@ const options = { option: "--config ", description: "Specify configuration file to be used. The default is truffle-config.js" + }, + quiet: { + option: "--quiet", + description: "Suppress excess logging output." } }; module.exports = options; diff --git a/packages/core/lib/command.js b/packages/core/lib/command.js index a32a1a81646..f871fc9e8a3 100644 --- a/packages/core/lib/command.js +++ b/packages/core/lib/command.js @@ -5,6 +5,9 @@ const OS = require("os"); const analytics = require("../lib/services/analytics"); const { extractFlags } = require("./utils/utils"); // Contains utility methods const commandOptions = require("./command-options"); +const debugModule = require("debug"); +const debug = debugModule("core:command:run"); + class Command { constructor(commands) { @@ -76,6 +79,14 @@ class Command { async run(inputStrings, options) { const result = this.getCommand(inputStrings, options.noAliases); + try { + // migrate Truffle data to the new location if necessary + const configMigration = require("./config-migration"); + await configMigration.migrateTruffleDataIfNecessary(); + } catch (error) { + debug("Truffle data migration failed: %o", error); + }; + if (result == null) { throw new TaskError( "Cannot find command based on input: " + JSON.stringify(inputStrings) diff --git a/packages/core/lib/commands/compile.js b/packages/core/lib/commands/compile.js index e2eb1b1186a..7ae980d9e5b 100644 --- a/packages/core/lib/commands/compile.js +++ b/packages/core/lib/commands/compile.js @@ -38,10 +38,6 @@ const command = { "that\n type of release or docker tags. The filter parameter must be one of the following: " + "prereleases,\n releases, latestRelease or docker." }, - { - option: "--quiet", - description: "Suppress all compilation output." - }, { option: "--compiler ", description: @@ -54,7 +50,7 @@ const command = { "Save the raw compiler results into , overwriting any existing content." }, ], - allowedGlobalOptions: ["config"] + allowedGlobalOptions: ["config", "quiet"] }, run: async function (options) { const TruffleError = require("@truffle/error"); diff --git a/packages/core/lib/commands/obtain.js b/packages/core/lib/commands/obtain.js index 19c0ae5d17d..60910b90b92 100644 --- a/packages/core/lib/commands/obtain.js +++ b/packages/core/lib/commands/obtain.js @@ -9,7 +9,7 @@ module.exports = { description: `Download and cache a version of the solc compiler. (required)` } ], - allowedGlobalOptions: [] + allowedGlobalOptions: ["quiet"] }, run: async function (options) { const SUPPORTED_COMPILERS = ["--solc"]; diff --git a/packages/core/lib/commands/test/index.js b/packages/core/lib/commands/test/index.js index 701f44f593c..7d2fc4e644f 100644 --- a/packages/core/lib/commands/test/index.js +++ b/packages/core/lib/commands/test/index.js @@ -190,7 +190,6 @@ const command = { network_id: 4447, mnemonic: "candy maple cake sugar pudding cream honey rich smooth crumble sweet treat", - gasLimit: config.gas, time: config.genesis_time, _chainId: 1337 //temporary until Ganache v3! }; diff --git a/packages/core/lib/commands/unbox.js b/packages/core/lib/commands/unbox.js index 13347e539ac..83f52e67aaa 100644 --- a/packages/core/lib/commands/unbox.js +++ b/packages/core/lib/commands/unbox.js @@ -35,7 +35,7 @@ const command = { "that exist in the directory.", }, ], - allowedGlobalOptions: [] + allowedGlobalOptions: ["quiet"] }, async run(options) { const Config = require("@truffle/config"); diff --git a/packages/core/lib/config-migration.js b/packages/core/lib/config-migration.js new file mode 100644 index 00000000000..53037a5e3fb --- /dev/null +++ b/packages/core/lib/config-migration.js @@ -0,0 +1,66 @@ +const OS = require("os"); +const path = require("path"); +const fse = require("fs-extra"); +const Conf = require("conf"); +const { promisify } = require("util"); +const copy = require("./copy"); +const TruffleConfig = require("@truffle/config"); +const debugModule = require("debug"); +const debug = debugModule("core:config-migration"); + +const CURRENT_CONFIG_VERSION = 1; + +module.exports = { + oldTruffleDataDirectory: path.join(OS.homedir(), ".config", "truffle"), + + needsMigrated: function () { + const conf = new Conf({ projectName: "truffle" }); + if (conf.get("version") === CURRENT_CONFIG_VERSION) return false; + const oldConfig = path.join(this.oldTruffleDataDirectory, "config.json"); + if (fse.existsSync(oldConfig) && oldConfig !== conf.path) { + // we are on Windows or a Mac + return true; + } else { + // we are on Linux or previous config doesn't exist and we don't need to + // perform a migration - current version set to designates success + conf.set("version", CURRENT_CONFIG_VERSION); + return false; + } + }, + + migrateTruffleDataIfNecessary: async function () { + if (!this.needsMigrated()) return; + debug("Truffle files need to be migrated"); + const conf = this.migrateGlobalConfig(); + debug("successfully migrated global config"); + const folders = ["compilers", ".db"]; + for (const folder of folders) { + await this.migrateFolder(folder); + debug("successfully migrated folder: %o", folder); + } + // set version to current only after migration is complete to designate success + conf.set("version", CURRENT_CONFIG_VERSION); + }, + + migrateGlobalConfig: function () { + const conf = new Conf({ projectName: "truffle" }); + const oldSettings = require(path.join( + this.oldTruffleDataDirectory, + "config.json" + )); + for (const key in oldSettings) { + conf.set(key, oldSettings[key]); + } + return conf; + }, + + migrateFolder: async function (folderName) { + const targetPath = path.join(this.oldTruffleDataDirectory, folderName); + // use conf to determine the new Truffle folder as it uses OS-appropriate locations + const conf = new Conf({ projectName: "truffle" }); + const destinationPath = path.join(TruffleConfig.getTruffleDataDirectory(), folderName); + if (fse.existsSync(targetPath)) { + await promisify(copy)(targetPath, destinationPath, {}); + } + } +}; diff --git a/packages/core/lib/testing/TestRunner.js b/packages/core/lib/testing/TestRunner.js index 7b85c35e2c8..5d9e72a11ad 100644 --- a/packages/core/lib/testing/TestRunner.js +++ b/packages/core/lib/testing/TestRunner.js @@ -126,6 +126,7 @@ class TestRunner { } function printEvent(decoding, indentation = 0, initialPrefix = "") { + debug("raw event: %O", decoding); const anonymousPrefix = decoding.kind === "anonymous" ? " " : ""; const className = decoding.definedIn @@ -150,7 +151,7 @@ class TestRunner { )})`; return namePrefix + indexedPrefix + displayValue + typeString + ","; }); - { + if (eventArgs.length > 0) { const len = eventArgs.length - 1; eventArgs[len] = eventArgs[len].slice(0, -1); // remove the final comma } diff --git a/packages/core/package.json b/packages/core/package.json index 1df6260b264..69ed3cc051a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "5.4.6", + "version": "5.4.14", "bin": { "truffle": "./cli.js", "truffle-exec": "./exec.js" @@ -21,38 +21,38 @@ "test": "mocha ./test/** ./test/**/*" }, "dependencies": { - "@truffle/artifactor": "^4.0.118", - "@truffle/box": "^2.1.24", - "@truffle/codec": "^0.11.10", - "@truffle/compile-solidity": "^5.3.17", - "@truffle/config": "^1.3.4", - "@truffle/contract": "^4.3.30", - "@truffle/debug-utils": "^5.1.10", - "@truffle/debugger": "^9.1.11", - "@truffle/decoder": "^5.0.2", - "@truffle/deployer": "^3.2.39", - "@truffle/environment": "^0.2.67", + "@truffle/artifactor": "^4.0.126", + "@truffle/box": "^2.1.30", + "@truffle/codec": "^0.11.17", + "@truffle/compile-solidity": "^5.3.25", + "@truffle/config": "^1.3.10", + "@truffle/contract": "^4.3.38", + "@truffle/debug-utils": "^5.1.18", + "@truffle/debugger": "^9.1.19", + "@truffle/decoder": "^5.0.10", + "@truffle/deployer": "^3.2.47", + "@truffle/environment": "^0.2.75", "@truffle/error": "^0.0.14", "@truffle/expect": "^0.0.18", - "@truffle/fetch-and-compile": "^0.1.2", - "@truffle/interface-adapter": "^0.5.4", - "@truffle/migrate": "^3.2.39", + "@truffle/fetch-and-compile": "^0.1.10", + "@truffle/interface-adapter": "^0.5.8", + "@truffle/migrate": "^3.2.47", "@truffle/plugins": "^0.2.3", "@truffle/preserve": "^0.2.4", "@truffle/preserve-fs": "^0.2.4", "@truffle/preserve-to-buckets": "^0.2.4", "@truffle/preserve-to-filecoin": "^0.2.4", "@truffle/preserve-to-ipfs": "^0.2.4", - "@truffle/provider": "^0.2.37", - "@truffle/provisioner": "^0.2.27", - "@truffle/require": "^2.0.72", - "@truffle/resolver": "^7.0.24", - "@truffle/source-fetcher": "^0.5.6", - "@truffle/workflow-compile": "^3.2.25", + "@truffle/provider": "^0.2.42", + "@truffle/provisioner": "^0.2.33", + "@truffle/require": "^2.0.78", + "@truffle/resolver": "^7.0.32", + "@truffle/source-fetcher": "^0.5.9", + "@truffle/workflow-compile": "^3.2.33", "chai": "^4.2.0", "colors": "^1.4.0", "command-exists": "^1.2.8", - "configstore": "^4.0.0", + "conf": "^10.0.2", "cpr": "^3.0.1", "debug": "^4.3.1", "del": "^2.2.0", @@ -77,8 +77,8 @@ "spawn-args": "^0.1.0", "tmp": "^0.2.1", "universal-analytics": "^0.4.17", - "web3": "1.5.2", - "web3-utils": "1.5.2", + "web3": "1.5.3", + "web3-utils": "1.5.3", "xregexp": "^4.2.4", "yargs": "^8.0.2" }, diff --git a/packages/core/test/lib/config-migrations.js b/packages/core/test/lib/config-migrations.js new file mode 100644 index 00000000000..6aef9f8efe9 --- /dev/null +++ b/packages/core/test/lib/config-migrations.js @@ -0,0 +1,28 @@ +const migrationUtils = require("../../lib/config-migration"); +const { + migrateTruffleDataIfNecessary, + needsMigrated, + oldTruffleDataDirectory, +} = migrationUtils; +const assert = require("assert"); +const path = require("path"); +const sinon = require("sinon"); +const fse = require("fs-extra"); +const oldConfigPath = path.join(oldTruffleDataDirectory, "config.json"); + +describe("global config migrations", function () { + describe("needsMigrated", function () { + describe("when the user has no old-style data dir", function () { + beforeEach(function () { + sinon.stub(fse, "existsSync").withArgs(oldConfigPath).returns(false); + }); + afterEach(function () { + fse.existsSync.restore(); + }); + + it("returns false", function () { + assert.equal(migrationUtils.needsMigrated(), false); + }); + }); + }); +}); diff --git a/packages/core/test/lib/mnemonics/mnemonic.js b/packages/core/test/lib/mnemonics/mnemonic.js index 4d565d20220..21486a853bb 100644 --- a/packages/core/test/lib/mnemonics/mnemonic.js +++ b/packages/core/test/lib/mnemonics/mnemonic.js @@ -1,41 +1,27 @@ const assert = require("chai").assert; const sinon = require("sinon"); const accountsInfo = require("../../../lib/mnemonics/mnemonic"); -const Configstore = require("configstore"); +const Conf = require("conf"); +let conf; describe("mnemonic", function() { - beforeEach(() => { - sinon - .stub(Configstore.prototype, "get") - .returns( - "candy maple cake sugar pudding cream honey rich smooth crumble sweet treat" - ); - sinon.stub(Configstore.prototype, "set"); - }); - afterEach(() => { - Configstore.prototype.get.restore(); - Configstore.prototype.set.restore(); - }); describe("#getOrGenerateMnemonic", function() { - it("checks user-level configuration for mnemonic and creates one if one is not present", function() { - let mnemonic = accountsInfo.getOrGenerateMnemonic(); - sinon.assert.calledOnce(Configstore.prototype.get); - assert.exists(mnemonic); - assert.isString(mnemonic); - assert.equal(mnemonic, Configstore.prototype.get("mnemonic")); + it("returns the mnemonic set in the config", function() { + const result = accountsInfo.getOrGenerateMnemonic(); + assert.exists(result); + assert.isString(result); }); }); describe("#getAccountsInfo", function() { it("returns public keys, private keys, and mnemonic for default user account", function() { - let defaultNumAddresses = 10; - let accounts = accountsInfo.getAccountsInfo(defaultNumAddresses); + const defaultNumAddresses = 10; + const accounts = accountsInfo.getAccountsInfo(defaultNumAddresses); assert.exists(accounts); assert.isObject(accounts); assert.isArray(accounts.accounts); assert.lengthOf(accounts.accounts, defaultNumAddresses); assert.isArray(accounts.privateKeys); assert.isString(accounts.mnemonic); - sinon.assert.calledOnce(Configstore.prototype.get); }); }); }); diff --git a/packages/core/test/lib/services/analytics/google-analytics.js b/packages/core/test/lib/services/analytics/google-analytics.js index f1321417ae9..09a73c804f2 100644 --- a/packages/core/test/lib/services/analytics/google-analytics.js +++ b/packages/core/test/lib/services/analytics/google-analytics.js @@ -5,22 +5,22 @@ const sinon = require("sinon"); const analytics = require("../../../../lib/services/analytics/google"); const inquirer = require("inquirer"); const configCommand = require("../../../../lib/commands/config"); -const Configstore = require("configstore"); +const Conf = require("conf"); describe("analytics", function() { beforeEach(() => { sinon.stub(inquirer, "prompt").returns({ then: () => 1 }); sinon.stub(Config, "getUserConfig").returns(true); - sinon.stub(Configstore.prototype, "get").returns(false); - sinon.stub(Configstore.prototype, "set"); + sinon.stub(Conf.prototype, "get").returns(false); + sinon.stub(Conf.prototype, "set"); sinon.stub(analytics, "setUserConfigViaPrompt").resolves(); sinon.stub(ua.Visitor.prototype, "_enqueue"); }); afterEach(() => { inquirer.prompt.restore(); Config.getUserConfig.restore(); - Configstore.prototype.get.restore(); - Configstore.prototype.set.restore(); + Conf.prototype.get.restore(); + Conf.prototype.set.restore(); analytics.setUserConfigViaPrompt.restore(); ua.Visitor.prototype._enqueue.restore(); sinon.restore(); @@ -28,8 +28,8 @@ describe("analytics", function() { describe("#setUserId", function() { it("sets a userId if one does not exist", function() { analytics.setUserId(); - sinon.assert.calledOnce(Configstore.prototype.get); - sinon.assert.calledOnce(Configstore.prototype.set); + sinon.assert.calledOnce(Conf.prototype.get); + sinon.assert.calledOnce(Conf.prototype.set); }); }); describe("#setAnalytics", function() { @@ -49,15 +49,15 @@ describe("analytics", function() { }); it("sets user-level configuration of enableAnalytics to true if passed true", function() { analytics.setAnalytics(true); - sinon.assert.calledTwice(Configstore.prototype.set); - let stubArg = Configstore.prototype.set.getCall(1).args[0] + sinon.assert.calledTwice(Conf.prototype.set); + let stubArg = Conf.prototype.set.getCall(1).args[0] .enableAnalytics; assert.equal(stubArg, true); }); it("sets user-level configuration of enableAnalytics to false if passed false", function() { analytics.setAnalytics(false); - sinon.assert.calledOnce(Configstore.prototype.set); - let stubArg = Configstore.prototype.set.getCall(0).args[0] + sinon.assert.calledOnce(Conf.prototype.set); + let stubArg = Conf.prototype.set.getCall(0).args[0] .enableAnalytics; assert.equal(stubArg, false); }); @@ -71,7 +71,7 @@ describe("analytics", function() { describe("#checkIfAnalyticsEnabled", function() { it("checks the user-level config to see if analytics are enabled", function() { analytics.checkIfAnalyticsEnabled(); - sinon.assert.calledOnce(Configstore.prototype.get); + sinon.assert.calledOnce(Conf.prototype.get); }); }); describe("#setPersistentAnalyticsData", function() { diff --git a/packages/core/test/migrate.js b/packages/core/test/migrate.js index 0dffcf70691..72e58b19191 100644 --- a/packages/core/test/migrate.js +++ b/packages/core/test/migrate.js @@ -22,7 +22,7 @@ describe("migrate", function () { }); function createProviderAndSetNetworkConfig(network) { - var provider = Ganache.provider({ seed: network, gasLimit: config.gas }); + var provider = Ganache.provider({ seed: network }); var web3 = new Web3(provider); return web3.eth.getAccounts().then(accs => { return web3.eth.net.getId().then(network_id => { diff --git a/packages/db-kit/package.json b/packages/db-kit/package.json index 6f9d0cddbd8..41517b5b945 100644 --- a/packages/db-kit/package.json +++ b/packages/db-kit/package.json @@ -1,13 +1,13 @@ { "name": "@truffle/db-kit", - "version": "0.1.27", + "version": "0.1.35", "description": "Utility belt for Truffle and @truffle/db", "keywords": [ "smart-contract", "truffle" ], "author": "g. nicholas d'andrea ", - "homepage": "https://github.com/trufflesuite/truffle#readme", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/db-kit#readme", "license": "MIT", "main": "dist/src/index.js", "directories": { @@ -55,14 +55,14 @@ "url": "https://github.com/trufflesuite/truffle/issues" }, "dependencies": { - "@truffle/codec": "^0.11.10", - "@truffle/compile-common": "^0.7.16", - "@truffle/compile-solidity": "^5.3.17", - "@truffle/config": "^1.3.4", - "@truffle/db": "^0.5.26", - "@truffle/decoder": "^5.0.2", - "@truffle/environment": "^0.2.67", - "@truffle/fetch-and-compile": "^0.1.2", + "@truffle/codec": "^0.11.17", + "@truffle/compile-common": "^0.7.22", + "@truffle/compile-solidity": "^5.3.25", + "@truffle/config": "^1.3.10", + "@truffle/db": "^0.5.34", + "@truffle/decoder": "^5.0.10", + "@truffle/environment": "^0.2.75", + "@truffle/fetch-and-compile": "^0.1.10", "ink": "^3.0.8", "ink-big-text": "^1.2.0", "ink-divider": "^3.0.0", diff --git a/packages/db-loader/package.json b/packages/db-loader/package.json index 14fa19f3d83..28d91cda365 100644 --- a/packages/db-loader/package.json +++ b/packages/db-loader/package.json @@ -3,7 +3,7 @@ "description": "Utility for loading @truffle/db", "license": "MIT", "author": "tyler feickert ", - "homepage": "https://github.com/trufflesuite/truffle/blob/develop/packages/db-loader/README.md", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/db-loader#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", @@ -12,7 +12,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "0.0.5", + "version": "0.0.13", "main": "dist/index.js", "keywords": [ "ethereum", @@ -30,7 +30,7 @@ "prepare": "tsc" }, "optionalDependencies": { - "@truffle/db": "^0.5.26" + "@truffle/db": "^0.5.34" }, "devDependencies": { "typescript": "^4.1.4" diff --git a/packages/db/package.json b/packages/db/package.json index 1ba96cb5620..acd63fd9cc4 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -3,7 +3,7 @@ "description": "Smart contract data aggregation", "license": "MIT", "author": "g. nicholas d'andrea ", - "homepage": "https://github.com/trufflesuite/truffle#readme", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/db#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", @@ -12,7 +12,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "0.5.26", + "version": "0.5.34", "main": "dist/src/index.js", "files": [ "dist", @@ -37,9 +37,9 @@ }, "dependencies": { "@truffle/abi-utils": "^0.2.4", - "@truffle/code-utils": "^1.2.29", - "@truffle/config": "^1.3.4", - "@truffle/resolver": "^7.0.24", + "@truffle/code-utils": "^1.2.30", + "@truffle/config": "^1.3.10", + "@truffle/resolver": "^7.0.32", "apollo-server": "^2.18.2", "debug": "^4.3.1", "fs-extra": "^9.1.0", @@ -55,11 +55,11 @@ "pouchdb-adapter-node-websql": "^7.0.0", "pouchdb-debug": "^7.1.1", "pouchdb-find": "^7.0.0", - "web3-utils": "1.5.2" + "web3-utils": "1.5.3" }, "devDependencies": { "@gql2ts/from-schema": "^2.0.0-4", - "@truffle/compile-common": "^0.7.16", + "@truffle/compile-common": "^0.7.22", "@truffle/contract-schema": "^3.4.3", "@types/debug": "^4.1.5", "@types/express": "^4.16.0", @@ -87,7 +87,7 @@ "typedoc-neo-theme": "^1.1.0", "typescript": "^4.1.4", "typescript-transform-paths": "^2.1.0", - "web3": "1.5.2" + "web3": "1.5.3" }, "keywords": [ "database", diff --git a/packages/debug-utils/package.json b/packages/debug-utils/package.json index 5558c21c105..a1c2ad03657 100644 --- a/packages/debug-utils/package.json +++ b/packages/debug-utils/package.json @@ -12,18 +12,18 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "5.1.10", + "version": "5.1.18", "main": "index.js", "scripts": { "prepare": "exit 0" }, "dependencies": { - "@truffle/codec": "^0.11.10", + "@truffle/codec": "^0.11.17", "@trufflesuite/chromafi": "^2.2.2", "bn.js": "^5.1.3", "chalk": "^2.4.2", "debug": "^4.3.1", - "highlightjs-solidity": "^1.2.2" + "highlightjs-solidity": "^2.0.1" }, "devDependencies": { "chai": "^4.2.0", diff --git a/packages/debugger/lib/ast/sagas/index.js b/packages/debugger/lib/ast/sagas/index.js index 6208c1c89b7..0b83e8df39c 100644 --- a/packages/debugger/lib/ast/sagas/index.js +++ b/packages/debugger/lib/ast/sagas/index.js @@ -50,6 +50,7 @@ function* handleEnter(sourceId, sourceIndex, node, pointer, parentId) { case "ContractDefinition": case "StructDefinition": case "EnumDefinition": + case "UserDefinedValueTypeDefinition": debug("%s recording type %o", pointer, node); yield* data.defineType(node, sourceId); break; diff --git a/packages/debugger/lib/data/sagas/index.js b/packages/debugger/lib/data/sagas/index.js index 4078d8f113d..5dae3d4d6d7 100644 --- a/packages/debugger/lib/data/sagas/index.js +++ b/packages/debugger/lib/data/sagas/index.js @@ -990,6 +990,8 @@ function* decodeMappingKeyCore(indexDefinition, keyDefinition) { const indexReference = (currentAssignments[fullIndexId] || {}).ref; + debug("indexDefinition.nodeType: %o", indexDefinition.nodeType); + debug("indexDefinition.kind: %o", indexDefinition.kind); if (Codec.Ast.Utils.isSimpleConstant(indexDefinition)) { //while the main case is the next one, where we look for a prior //assignment, we need this case (and need it first) for two reasons: @@ -1068,7 +1070,11 @@ function* decodeMappingKeyCore(indexDefinition, keyDefinition) { //(note that this case is last for a reason; if this were earlier, it //would catch *non*-silent type conversions, which we want to just read //off the stack) - else if (indexDefinition.kind === "typeConversion") { + else if ( + indexDefinition.nodeType === "FunctionCall" && + indexDefinition.kind === "typeConversion" + ) { + debug("type conversion case"); indexDefinition = indexDefinition.arguments[0]; } //...also prior to 0.5.0, unary + was legal, which needs to be accounted @@ -1077,18 +1083,33 @@ function* decodeMappingKeyCore(indexDefinition, keyDefinition) { indexDefinition.nodeType === "UnaryOperation" && indexDefinition.operator === "+" ) { + debug("unary + case"); indexDefinition = indexDefinition.subExpression; } + //...and starting in 0.8.8, we'd better handle wrap and unwrap as well for + //the same reason! + else if ( + indexDefinition.nodeType === "FunctionCall" && + indexDefinition.kind === "functionCall" && + ["wrap", "unwrap"].includes( + Codec.Ast.Utils.functionClass(indexDefinition.expression) + ) + ) { + debug("wrap/unwrap case"); + indexDefinition = indexDefinition.arguments[0]; + } //otherwise, we've just totally failed to decode it, so we mark //indexValue as null (as distinct from undefined) to indicate this. In //the future, we should be able to decode all mapping keys, but we're //not quite there yet, sorry (because we can't yet handle all constant //state variables) else { + debug("we failed"); return null; } + debug("retrying"); //now, as mentioned, retry in the typeConversion case - //(or unary + case) + //(or unary + case, or wrap/unwrap case) } } @@ -1099,9 +1120,11 @@ export function* reset() { export function* recordAllocations() { const contracts = yield select(data.views.contractAllocationInfo); const referenceDeclarations = yield select(data.views.referenceDeclarations); + const userDefinedTypesByCompilation = + yield select(data.views.userDefinedTypesByCompilation); const userDefinedTypes = yield select(data.views.userDefinedTypes); const storageAllocations = Codec.Storage.Allocate.getStorageAllocations( - userDefinedTypes + userDefinedTypesByCompilation ); const memoryAllocations = Codec.Memory.Allocate.getMemoryAllocations( userDefinedTypes diff --git a/packages/debugger/lib/data/selectors/index.js b/packages/debugger/lib/data/selectors/index.js index 6c2170877bd..b1dbc3bc7ca 100644 --- a/packages/debugger/lib/data/selectors/index.js +++ b/packages/debugger/lib/data/selectors/index.js @@ -246,41 +246,49 @@ const data = createSelectorTree({ }, /** - * data.views.userDefinedTypes - * user-defined types for passing to the decoder - * NOTE: *not* grouped by compilation or anything, this is flat + * data.views.userDefinedTypesByCompilation */ - userDefinedTypes: createLeaf( + userDefinedTypesByCompilation: createLeaf( [ "/info/userDefinedTypes", "./referenceDeclarations", "./scopes/inlined", solidity.views.sources ], - (userDefinedTypes, referenceDeclarations, scopes, sources) => - Object.assign( - {}, - ...userDefinedTypes.map(({ sourceId, id }) => { - debug("id: %d", id); - debug("sourceId: %s", sourceId); - debug("scope: %o", scopes[sourceId][id]); - const node = scopes[sourceId][id].definition; - debug("node: %o", node); - const { compilationId, compiler, internal } = sources[sourceId]; - debug("compilationId: %s", compilationId); - if (internal) { - return {}; //just to be sure, we assume generated sources don't define types - } - const type = Codec.Ast.Import.definitionToStoredType( - node, - compilationId, + (userDefinedTypes, referenceDeclarations, scopes, sources) => { + let typesByCompilation = {}; + for (const { sourceId, id } of userDefinedTypes) { + const node = scopes[sourceId][id].definition; + const { compilationId, compiler, internal } = sources[sourceId]; + if (internal) { + continue; //just to be sure, we assume generated sources don't define types + } + const type = Codec.Ast.Import.definitionToStoredType( + node, + compilationId, + compiler, + referenceDeclarations[compilationId] + ); + if (!typesByCompilation[compilationId]) { + typesByCompilation[compilationId] = { compiler, - referenceDeclarations[compilationId] - ); - debug("type: %o", type); - return { [type.id]: type }; - }) - ) + types: {} + }; + } + typesByCompilation[compilationId].types[type.id] = type; + } + return typesByCompilation; + } + ), + + /** + * data.views.userDefinedTypes + * user-defined types for passing to the decoder + * NOTE: *not* grouped by compilation or anything, this is flat + */ + userDefinedTypes: createLeaf( + ["./userDefinedTypesByCompilation"], + Codec.Format.Types.forgetCompilations ), /** diff --git a/packages/debugger/lib/evm/reducers.js b/packages/debugger/lib/evm/reducers.js index da5bbb15e16..441ad8acffa 100644 --- a/packages/debugger/lib/evm/reducers.js +++ b/packages/debugger/lib/evm/reducers.js @@ -94,7 +94,8 @@ const DEFAULT_BLOCK = { gaslimit: new BN(0), number: new BN(0), timestamp: new BN(0), - chainid: new BN(0) + chainid: new BN(0), + basefee: new BN(0) }; function block(state = DEFAULT_BLOCK, action) { diff --git a/packages/debugger/lib/web3/sagas/index.js b/packages/debugger/lib/web3/sagas/index.js index fa7119588de..7d7da2a7ab9 100644 --- a/packages/debugger/lib/web3/sagas/index.js +++ b/packages/debugger/lib/web3/sagas/index.js @@ -74,7 +74,10 @@ function* fetchTransactionInfo(adapter, { txHash }) { gaslimit: new BN(block.gasLimit), number: new BN(block.number), timestamp: new BN(block.timestamp), - chainid: new BN(chainId) //key is lowercase because that's what Solidity does + chainid: new BN(chainId), //key is lowercase because that's what Solidity does + basefee: new BN(parseInt(block.baseFeePerGas)) //will be 0 if pre-London [new BN(NaN) yields 0] + //note we need parseInt on basefee because some web3 versions return it as a hex string, + //and BN doesn't allow for hex strings as input }; if (tx.to != null) { diff --git a/packages/debugger/package.json b/packages/debugger/package.json index 53db5b25ed0..9b15e61ae60 100644 --- a/packages/debugger/package.json +++ b/packages/debugger/package.json @@ -12,7 +12,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "9.1.11", + "version": "9.1.19", "main": "dist/debugger.js", "scripts": { "build": "webpack --config webpack/webpack.config.js", @@ -25,8 +25,8 @@ }, "dependencies": { "@truffle/abi-utils": "^0.2.4", - "@truffle/codec": "^0.11.10", - "@truffle/source-map-utils": "^1.3.54", + "@truffle/codec": "^0.11.17", + "@truffle/source-map-utils": "^1.3.61", "bn.js": "^5.1.3", "debug": "^4.3.1", "json-pointer": "^0.6.0", @@ -40,15 +40,15 @@ "remote-redux-devtools": "^0.5.12", "reselect-tree": "^1.3.4", "semver": "^7.3.4", - "web3": "1.5.2", - "web3-eth-abi": "1.5.2" + "web3": "1.5.3", + "web3-eth-abi": "1.5.3" }, "devDependencies": { - "@truffle/artifactor": "^4.0.118", - "@truffle/box": "^2.1.24", - "@truffle/migrate": "^3.2.39", - "@truffle/resolver": "^7.0.24", - "@truffle/workflow-compile": "^3.2.25", + "@truffle/artifactor": "^4.0.126", + "@truffle/box": "^2.1.30", + "@truffle/migrate": "^3.2.47", + "@truffle/resolver": "^7.0.32", + "@truffle/workflow-compile": "^3.2.33", "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-plugin-transform-object-rest-spread": "^6.26.0", diff --git a/packages/debugger/test/data/global.js b/packages/debugger/test/data/global.js index dc2df502294..42453f99b7a 100644 --- a/packages/debugger/test/data/global.js +++ b/packages/debugger/test/data/global.js @@ -189,7 +189,7 @@ describe("Globally-available variables", function () { assert.equal(variables.this, variables._this); assert.deepEqual(variables.msg, variables._msg); assert.deepEqual(variables.tx, variables._tx); - assert.deepEqual(variables.block, variables._block); + assert.deepEqual(variables.block, withBaseFeeZero(variables._block)); }); it("Gets globals correctly in nested call", async function () { @@ -215,7 +215,7 @@ describe("Globally-available variables", function () { assert.equal(variables.this, variables._this); assert.deepEqual(variables.msg, variables._msg); assert.deepEqual(variables.tx, variables._tx); - assert.deepEqual(variables.block, variables._block); + assert.deepEqual(variables.block, withBaseFeeZero(variables._block)); }); it("Gets globals correctly in static call", async function () { @@ -241,7 +241,7 @@ describe("Globally-available variables", function () { assert.equal(variables.this, variables.__this); assert.deepEqual(variables.msg, variables.__msg); assert.deepEqual(variables.tx, variables.__tx); - assert.deepEqual(variables.block, variables.__block); + assert.deepEqual(variables.block, withBaseFeeZero(variables.__block)); }); it("Gets globals correctly in library call", async function () { @@ -260,13 +260,15 @@ describe("Globally-available variables", function () { }); await bugger.continueUntilBreakpoint(); + debug("variables: %O", await bugger.variables()); + const variables = Codec.Format.Utils.Inspect.unsafeNativizeVariables( await bugger.variables() ); assert.deepEqual(variables.msg, variables.__msg); assert.deepEqual(variables.tx, variables.__tx); - assert.deepEqual(variables.block, variables.__block); + assert.deepEqual(variables.block, withBaseFeeZero(variables.__block)); }); it("Gets globals correctly in simple creation", async function () { @@ -285,7 +287,7 @@ describe("Globally-available variables", function () { assert.equal(variables.this, variables._this); assert.deepEqual(variables.msg, variables._msg); assert.deepEqual(variables.tx, variables._tx); - assert.deepEqual(variables.block, variables._block); + assert.deepEqual(variables.block, withBaseFeeZero(variables._block)); }); it("Gets globals correctly in nested creation", async function () { @@ -311,7 +313,7 @@ describe("Globally-available variables", function () { assert.equal(variables.this, variables._this); assert.deepEqual(variables.msg, variables._msg); assert.deepEqual(variables.tx, variables._tx); - assert.deepEqual(variables.block, variables._block); + assert.deepEqual(variables.block, withBaseFeeZero(variables._block)); }); it("Gets globals correctly in failed CREATE2", async function () { @@ -337,6 +339,14 @@ describe("Globally-available variables", function () { assert.equal(variables.this, variables._this); assert.deepEqual(variables.msg, variables._msg); assert.deepEqual(variables.tx, variables._tx); - assert.deepEqual(variables.block, variables._block); + assert.deepEqual(variables.block, withBaseFeeZero(variables._block)); }); }); + +//HACK for testing until Ganache supports london +function withBaseFeeZero(block) { + return { + ...block, + basefee: 0 + }; +} diff --git a/packages/debugger/test/data/immutable.js b/packages/debugger/test/data/immutable.js index 267f9c0725d..12f048369ec 100644 --- a/packages/debugger/test/data/immutable.js +++ b/packages/debugger/test/data/immutable.js @@ -13,7 +13,7 @@ import * as Codec from "@truffle/codec"; import solidity from "lib/solidity/selectors"; const __IMMUTABLE = ` -pragma solidity ^0.8.0; +pragma solidity ^0.8.8; contract Base { int8 immutable base = -37; @@ -24,11 +24,14 @@ contract ImmutableTest is Base { Red, Green, Blue } + type MyInt is int8; + Color immutable background; bool immutable truth; address immutable self; bytes1 immutable secret; uint8 immutable trulySecret; + MyInt immutable obscured; event Done(); @@ -38,6 +41,7 @@ contract ImmutableTest is Base { self = address(this); secret = 0x88; trulySecret = 23; + obscured = MyInt.wrap(-1); emit Done(); //BREAK CONSTRUCTOR } @@ -53,6 +57,7 @@ contract ImmutableTest is Base { emit Bool(truth); emit Address(self); emit Byte(secret); + emit Number(MyInt.unwrap(obscured)); emit Done(); //BREAK DEPLOYED } } @@ -107,7 +112,8 @@ describe("Immutable state variables", function () { background: "ImmutableTest.Color.Blue", truth: true, self: address, - secret: "0x88" + secret: "0x88", + obscured: -1 }; assert.deepInclude(variables, expectedResult); @@ -144,7 +150,8 @@ describe("Immutable state variables", function () { truth: true, self: address, secret: "0x88", - trulySecret: 23 + trulySecret: 23, + obscured: -1 }; assert.deepInclude(variables, expectedResult); diff --git a/packages/debugger/test/data/more-decoding.js b/packages/debugger/test/data/more-decoding.js index a7cdca22ce6..b79be966238 100644 --- a/packages/debugger/test/data/more-decoding.js +++ b/packages/debugger/test/data/more-decoding.js @@ -74,7 +74,7 @@ contract ContainersTest { `; const __KEYSANDBYTES = ` -pragma solidity ^0.8.0; +pragma solidity ^0.8.8; contract ElementaryTest { @@ -82,6 +82,8 @@ contract ElementaryTest { enum Ternary { Red, Green, Blue } + type MyInt is int8; + //storage variables to be tested mapping(bool => bool) boolMap; mapping(bytes1 => bytes1) byteMap; @@ -92,6 +94,7 @@ contract ElementaryTest { mapping(address => address) addressMap; mapping(ElementaryTest => ElementaryTest) contractMap; mapping(Ternary => Ternary) enumMap; + mapping(MyInt => MyInt) wrapMap; //constant state variables to try as mapping keys uint constant two = 2; @@ -126,6 +129,8 @@ contract ElementaryTest { enumMap[Ternary.Blue] = Ternary.Blue; + wrapMap[MyInt.wrap(-2)] = MyInt.wrap(-2); + emit Done(); //break here } } @@ -393,6 +398,7 @@ describe("Further Decoding", function () { addressMap: { [address]: address }, contractMap: { [address]: address }, enumMap: { "ElementaryTest.Ternary.Blue": "ElementaryTest.Ternary.Blue" }, + wrapMap: { "-2": -2 }, oneByte: "0xff", severalBytes: ["0xff"] }; diff --git a/packages/debugger/test/helpers.js b/packages/debugger/test/helpers.js index 4c3b69edd7b..cb98f9adbed 100644 --- a/packages/debugger/test/helpers.js +++ b/packages/debugger/test/helpers.js @@ -26,10 +26,10 @@ export async function prepareContracts(provider, sources = {}, migrations) { config.compilers = { solc: { - version: "0.8.4", + version: "0.8.9", settings: { optimizer: { enabled: false, runs: 200 }, - evmVersion: "istanbul" + evmVersion: "london" } } }; diff --git a/packages/debugger/test/stacktrace.js b/packages/debugger/test/stacktrace.js index 4c2914498ae..b045e092e03 100644 --- a/packages/debugger/test/stacktrace.js +++ b/packages/debugger/test/stacktrace.js @@ -328,18 +328,19 @@ describe("Stack tracing", function () { undefined, "run1", "runInternal", - undefined + undefined, + "panic_error_0x51" ]); let contractNames = report.map(({ contractName }) => contractName); assert.isUndefined(contractNames[contractNames.length - 1]); - contractNames.pop(); - assert(contractNames.every(name => name === "StacktraceTest")); + assert.isUndefined(contractNames[contractNames.length - 2]); + assert(contractNames.slice(0,-2).every(name => name === "StacktraceTest")); let addresses = report.map(({ address }) => address); assert(addresses.every(address => address === instance.address)); let status = report[report.length - 1].status; assert.isFalse(status); - let location = report[report.length - 2].location; //note, -2 because of undefined on top - let prevLocation = report[report.length - 3].location; //similar + let location = report[report.length - 3].location; //note, -2 because of panic & undefined on top + let prevLocation = report[report.length - 4].location; //similar assert.strictEqual(location.sourceRange.lines.start.line, failLine); assert.strictEqual(prevLocation.sourceRange.lines.start.line, callLine); }); diff --git a/packages/decoder/lib/decoders.ts b/packages/decoder/lib/decoders.ts index f78ac397f57..6841f535c2c 100644 --- a/packages/decoder/lib/decoders.ts +++ b/packages/decoder/lib/decoders.ts @@ -53,6 +53,7 @@ export class ProjectDecoder { private contractsAndContexts: AbiData.Allocate.ContractAndContexts[] = []; private referenceDeclarations: { [compilationId: string]: Ast.AstNodes }; + private userDefinedTypesByCompilation: Format.Types.TypesByCompilationAndId; private userDefinedTypes: Format.Types.TypesById; private allocations: Evm.AllocationInfo; @@ -78,6 +79,7 @@ export class ProjectDecoder { ({ definitions: this.referenceDeclarations, + typesByCompilation: this.userDefinedTypesByCompilation, types: this.userDefinedTypes } = Compilations.Utils.collectUserDefinedTypesAndTaggedOutputs(this.compilations)); @@ -93,7 +95,7 @@ export class ProjectDecoder { this.userDefinedTypes ); this.allocations.storage = Storage.Allocate.getStorageAllocations( - this.userDefinedTypes + this.userDefinedTypesByCompilation ); //not used by project decoder itself, but used by contract decoder this.allocations.calldata = AbiData.Allocate.getCalldataAllocations( allocationInfo, @@ -1707,7 +1709,10 @@ export class ContractInstanceDecoder { break; case "mapping": let keyType = parentType.keyType; - if (keyType.typeClass === "enum") { + if ( + keyType.typeClass === "enum" || + keyType.typeClass === "userDefinedValueType" + ) { keyType = ( Format.Types.fullType(keyType, this.userDefinedTypes) ); diff --git a/packages/decoder/lib/utils.ts b/packages/decoder/lib/utils.ts index a82396e9920..5c6a5122e0d 100644 --- a/packages/decoder/lib/utils.ts +++ b/packages/decoder/lib/utils.ts @@ -7,7 +7,7 @@ import BN from "bn.js"; import type * as Codec from "@truffle/codec"; //Function for wrapping a value as an ElementaryValue -//(note: assumes any enum types are the full type) +//(note: assumes any enum types & UDVTs are the full type) //WARNING: this function does not check its inputs! Please check before using! //How to use: //numbers may be BN, number, or numeric string @@ -116,6 +116,8 @@ export function wrapElementaryValue( numericAsBN: numeric } }; + case "userDefinedValueType": + return wrapElementaryValue(value, dataType.underlyingType); //fixed and ufixed are not handled for now! } } diff --git a/packages/decoder/package.json b/packages/decoder/package.json index 52a0658ba5d..64368c82782 100644 --- a/packages/decoder/package.json +++ b/packages/decoder/package.json @@ -3,7 +3,7 @@ "description": "A decoder and encoder for Solidity variables of all sorts", "license": "MIT", "author": "Mike Seese and Harry Altman", - "homepage": "https://github.com/trufflesuite/truffle#readme", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/decoder#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", @@ -12,7 +12,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "5.0.2", + "version": "5.0.10", "main": "dist/index.js", "directories": { "lib": "lib" @@ -26,19 +26,19 @@ "types": "dist/index.d.ts", "dependencies": { "@truffle/abi-utils": "^0.2.4", - "@truffle/codec": "^0.11.10", - "@truffle/compile-common": "^0.7.16", - "@truffle/source-map-utils": "^1.3.54", + "@truffle/codec": "^0.11.17", + "@truffle/compile-common": "^0.7.22", + "@truffle/source-map-utils": "^1.3.61", "bn.js": "^5.1.3", "debug": "^4.3.1", - "web3": "1.5.2" + "web3": "1.5.3" }, "devDependencies": { - "@truffle/config": "^1.3.4", + "@truffle/config": "^1.3.10", "@truffle/contract-schema": "^3.4.3", - "@truffle/migrate": "^3.2.39", - "@truffle/provider": "^0.2.37", - "@truffle/workflow-compile": "^3.2.25", + "@truffle/migrate": "^3.2.47", + "@truffle/provider": "^0.2.42", + "@truffle/workflow-compile": "^3.2.33", "@types/big.js": "^4.0.5", "@types/bn.js": "^4.11.4", "@types/debug": "^4.1.5", diff --git a/packages/decoder/test/current/contracts/CompatibleTest.sol b/packages/decoder/test/current/contracts/CompatibleTest.sol index 5ab6e1bec74..067312d938e 100644 --- a/packages/decoder/test/current/contracts/CompatibleTest.sol +++ b/packages/decoder/test/current/contracts/CompatibleTest.sol @@ -1,5 +1,5 @@ //SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.8; pragma experimental ABIEncoderV2; contract CompatibleNativizeTest { @@ -9,6 +9,8 @@ contract CompatibleNativizeTest { string y; } + type MyBool is bool; + event String(string z); event TwoStrings(string w, string z); event StringPair(Pair z); @@ -40,4 +42,12 @@ contract CompatibleNativizeTest { function returnFunction() public view returns (function() external) { return this.emitString; } + + function returnBytes() public pure returns (bytes memory) { + return hex""; + } + + function returnCustom() public pure returns (MyBool) { + return MyBool.wrap(true); + } } diff --git a/packages/decoder/test/current/contracts/DecodingSample.sol b/packages/decoder/test/current/contracts/DecodingSample.sol index 60ce21f7f17..6d3cc8f8fcb 100644 --- a/packages/decoder/test/current/contracts/DecodingSample.sol +++ b/packages/decoder/test/current/contracts/DecodingSample.sol @@ -1,7 +1,10 @@ //SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.8; contract DecodingSample { + + type MyInt is int8; + enum E { EnumValZero, EnumValOne, @@ -31,11 +34,14 @@ contract DecodingSample { bytes varBytes; E varEnum; S varStructS; + MyInt varCustom1; + MyInt varCustom2; mapping(uint => uint) varMapping; mapping(address => uint) varAddressMapping; mapping(DecodingSample => uint) varContractMapping; mapping(E => uint) varEnumMapping; + mapping(MyInt => MyInt) varWrapMapping; uint immutable immutableUint; @@ -84,6 +90,8 @@ contract DecodingSample { varStructS.structS2.structTwoDynamicArrayUint[0] = 4; varStructS.structS2.structTwoDynamicArrayUint[1] = 8; varStructS.structS2.structTwoDynamicArrayUint[2] = 12; + varCustom1 = MyInt.wrap(-1); + varCustom2 = MyInt.wrap(-2); immutableUint = 16; @@ -132,6 +140,7 @@ contract DecodingSample { varEnumMapping[E.EnumValTwo] = 2; varEnumMapping[E.EnumValThree] = 3; varEnumMapping[E.EnumValFour] = 4; + varWrapMapping[MyInt.wrap(-3)] = MyInt.wrap(-3); functionInternal = example; } diff --git a/packages/decoder/test/current/contracts/DowngradeTest.sol b/packages/decoder/test/current/contracts/DowngradeTest.sol index 798baec8b34..341fec49e88 100644 --- a/packages/decoder/test/current/contracts/DowngradeTest.sol +++ b/packages/decoder/test/current/contracts/DowngradeTest.sol @@ -1,5 +1,5 @@ //SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.8; pragma experimental ABIEncoderV2; contract DowngradeTestParent { @@ -10,9 +10,11 @@ contract DowngradeTest is DowngradeTestParent { //structs; enums; contracts; address payable; functions + type MyInt is int16; + struct Pair { uint x; - uint y; + MyInt y; } struct AsymmetricTriple { @@ -72,13 +74,13 @@ contract DowngradeTest is DowngradeTestParent { } function returnsStuff() public pure returns (Pair memory, Ternary) { - return (Pair(107, 683), Ternary.No); + return (Pair(107, MyInt.wrap(683)), Ternary.No); } error CustomError(Pair pair); function throwCustom() public pure { - revert CustomError(Pair(1, 2)); + revert CustomError(Pair(1, MyInt.wrap(2))); } } diff --git a/packages/decoder/test/current/contracts/WireTest.sol b/packages/decoder/test/current/contracts/WireTest.sol index 95bade7f298..24b9656847a 100644 --- a/packages/decoder/test/current/contracts/WireTest.sol +++ b/packages/decoder/test/current/contracts/WireTest.sol @@ -1,5 +1,5 @@ //SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; +pragma solidity ^0.8.8; pragma experimental ABIEncoderV2; contract WireTestParent { @@ -36,6 +36,8 @@ enum GlobalEnum { contract WireTest is WireTestParent, WireTestAbstract { + type MyInt is int8; + function notImplemented() public { emit Done(); } //just a dummy function, not @@ -70,10 +72,10 @@ contract WireTest is WireTestParent, WireTestAbstract { Yes, No, MaybeSo } - event EmitStuff(Triple, address[2], string[]); + event EmitStuff(Triple, address[2], string[], MyInt); - function emitStuff(Triple memory p, address[2] memory precompiles, string[] memory strings) public { - emit EmitStuff(p, precompiles, strings); + function emitStuff(Triple memory p, address[2] memory precompiles, string[] memory strings, MyInt x) public { + emit EmitStuff(p, precompiles, strings, x); } event MoreStuff(WireTest, uint[] data); @@ -167,8 +169,16 @@ contract WireTest is WireTestParent, WireTestAbstract { mapping(string => Triple[]) public deepStruct; mapping(string => string)[] public deepString; - function returnsStuff() public pure returns (Triple memory, Ternary) { - return (Triple(-1, 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef, hex"deadbeef"), Ternary.No); + function returnsStuff() public pure returns (Triple memory, Ternary, MyInt) { + return ( + Triple( + -1, + 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef, + hex"deadbeef" + ), + Ternary.No, + MyInt.wrap(-1) + ); } function overriddenReturn() public pure override returns (uint) { diff --git a/packages/decoder/test/current/test/compatible-nativize.js b/packages/decoder/test/current/test/compatible-nativize.js index 87bcd2c856f..8bd7f621fcc 100644 --- a/packages/decoder/test/current/test/compatible-nativize.js +++ b/packages/decoder/test/current/test/compatible-nativize.js @@ -25,7 +25,7 @@ describe("nativize (ethers format)", function () { }); before("Prepare contracts and artifacts", async function () { - this.timeout(30000); + this.timeout(45000); const prepared = await prepareContracts(provider, path.resolve(__dirname, "..")); abstractions = prepared.abstractions; @@ -75,7 +75,9 @@ describe("nativize (ethers format)", function () { z: keyedArray, __length__: 1 }, - returnFunction: instance.address.toLowerCase() + emitStringSelector + returnFunction: instance.address.toLowerCase() + emitStringSelector, + returnBytes: null, + returnCustom: true }; expected.returnStringPair.w = "hello"; expected.returnStringPair.z = "goodbye"; diff --git a/packages/decoder/test/current/test/decoding-test.js b/packages/decoder/test/current/test/decoding-test.js index 52f83278ab7..b6a39b894d5 100644 --- a/packages/decoder/test/current/test/decoding-test.js +++ b/packages/decoder/test/current/test/decoding-test.js @@ -43,6 +43,7 @@ describe("State variable decoding", function () { await decoder.watchMappingKey("varEnumMapping", "EnumValTwo"); await decoder.watchMappingKey("varEnumMapping", "3"); await decoder.watchMappingKey("varEnumMapping", 4); + await decoder.watchMappingKey("varWrapMapping", -3); const initialState = await decoder.state(); const initialVariables = await decoder.variables(); @@ -66,6 +67,8 @@ describe("State variable decoding", function () { assert.equal(variables.varBytes, "0x01030307"); assert.equal(typeof variables.varEnum, "string"); assert.equal(variables.varEnum, "DecodingSample.E.EnumValTwo"); + assert.equal(variables.varCustom1, -1); + assert.equal(variables.varCustom2, -2); const struct = variables.varStructS; validateStructS(struct, [ @@ -134,6 +137,7 @@ describe("State variable decoding", function () { assert.equal(variables.varEnumMapping["DecodingSample.E.EnumValTwo"], 2); assert.equal(variables.varEnumMapping["DecodingSample.E.EnumValThree"], 3); assert.equal(variables.varEnumMapping["DecodingSample.E.EnumValFour"], 4); + assert.equal(variables.varWrapMapping[-3], -3); assert.equal( variables.functionExternal, diff --git a/packages/decoder/test/current/test/downgrade-test.js b/packages/decoder/test/current/test/downgrade-test.js index 4fae2f030f2..3a6b7f66cae 100644 --- a/packages/decoder/test/current/test/downgrade-test.js +++ b/packages/decoder/test/current/test/downgrade-test.js @@ -411,11 +411,11 @@ function verifyAbiDecoding(decoding, address) { assert.lengthOf(decoding.arguments, 4); //we'll skip verifying the names as well - //first argument: {{x: 7, y: 5}, z: 3} + //first argument: {{x: 7, y: -5}, z: 3} assert.strictEqual(decoding.arguments[0].value.type.typeClass, "tuple"); assert.deepEqual( Codec.Format.Utils.Inspect.unsafeNativize(decoding.arguments[0].value), - [[7, 5], 3] + [[7, -5], 3] ); //second argument: No (i.e. 1) assert.strictEqual(decoding.arguments[1].value.type.typeClass, "uint"); @@ -478,7 +478,7 @@ async function runTestBody( let deployedContract = await abstractions.DowngradeTest.new(); let address = deployedContract.address; - let result = await deployedContract.run([[7, 5], 3], 1, address, address); + let result = await deployedContract.run([[7, -5], 3], 1, address, address); let resultHash = result.tx; let resultTx = await web3.eth.getTransaction(resultHash); let resultLog = result.receipt.rawLogs[0]; @@ -505,7 +505,7 @@ async function runTestBody( //still getting it. weird. well, whatever... try { await deployedContract.causeTrouble(); - } catch (_) { + } catch { //do nothing, get the result a different way } //HACK diff --git a/packages/decoder/test/current/test/wire-test.js b/packages/decoder/test/current/test/wire-test.js index eb0cc5ed4f1..f2bcbb4fd76 100644 --- a/packages/decoder/test/current/test/wire-test.js +++ b/packages/decoder/test/current/test/wire-test.js @@ -71,7 +71,8 @@ describe("Over-the-wire decoding", function () { "0x0000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000002" ], - ["hello", "hi", "hooblypoob"] + ["hello", "hi", "hooblypoob"], + -1 ]; let emitStuff = await deployedContract.emitStuff(...emitStuffArgs); let emitStuffHash = emitStuff.tx; @@ -131,6 +132,7 @@ describe("Over-the-wire decoding", function () { ); assert.strictEqual(constructorDecoding.kind, "constructor"); + assert.strictEqual(constructorDecoding.decodingMode, "full"); assert.strictEqual(constructorDecoding.class.typeName, "WireTest"); assert.lengthOf(constructorDecoding.arguments, 3); assert.strictEqual(constructorDecoding.arguments[0].name, "status"); @@ -156,9 +158,10 @@ describe("Over-the-wire decoding", function () { ); assert.strictEqual(emitStuffDecoding.kind, "function"); + assert.strictEqual(emitStuffDecoding.decodingMode, "full"); assert.strictEqual(emitStuffDecoding.abi.name, "emitStuff"); assert.strictEqual(emitStuffDecoding.class.typeName, "WireTest"); - assert.lengthOf(emitStuffDecoding.arguments, 3); + assert.lengthOf(emitStuffDecoding.arguments, 4); assert.strictEqual(emitStuffDecoding.arguments[0].name, "p"); assert.deepEqual( Codec.Format.Utils.Inspect.unsafeNativize( @@ -180,8 +183,16 @@ describe("Over-the-wire decoding", function () { ), emitStuffArgs[2] ); + assert.strictEqual(emitStuffDecoding.arguments[3].name, "x"); + assert.strictEqual( + Codec.Format.Utils.Inspect.unsafeNativize( + emitStuffDecoding.arguments[3].value + ), + emitStuffArgs[3] + ); assert.strictEqual(moreStuffDecoding.kind, "function"); + assert.strictEqual(moreStuffDecoding.decodingMode, "full"); assert.strictEqual(moreStuffDecoding.abi.name, "moreStuff"); assert.strictEqual(moreStuffDecoding.class.typeName, "WireTest"); assert.lengthOf(moreStuffDecoding.arguments, 2); @@ -201,6 +212,7 @@ describe("Over-the-wire decoding", function () { ); assert.strictEqual(globalTestDecoding.kind, "function"); + assert.strictEqual(globalTestDecoding.decodingMode, "full"); assert.strictEqual(globalTestDecoding.abi.name, "globalTest"); assert.strictEqual(globalTestDecoding.class.typeName, "WireTest"); assert.lengthOf(globalTestDecoding.arguments, 2); @@ -220,6 +232,7 @@ describe("Over-the-wire decoding", function () { ); assert.strictEqual(inheritedDecoding.kind, "function"); + assert.strictEqual(inheritedDecoding.decodingMode, "full"); assert.strictEqual(inheritedDecoding.abi.name, "inherited"); assert.strictEqual(inheritedDecoding.class.typeName, "WireTest"); //NOT WireTestParent assert.lengthOf(inheritedDecoding.arguments, 1); @@ -232,6 +245,7 @@ describe("Over-the-wire decoding", function () { ); assert.strictEqual(defaultConstructorDecoding.kind, "constructor"); + assert.strictEqual(defaultConstructorDecoding.decodingMode, "full"); assert.strictEqual( defaultConstructorDecoding.class.typeName, "WireTestParent" @@ -239,6 +253,7 @@ describe("Over-the-wire decoding", function () { assert.isEmpty(defaultConstructorDecoding.arguments); assert.strictEqual(getterDecoding1.kind, "function"); + assert.strictEqual(getterDecoding1.decodingMode, "full"); assert.strictEqual(getterDecoding1.abi.name, "deepStruct"); assert.strictEqual(getterDecoding1.class.typeName, "WireTest"); assert.lengthOf(getterDecoding1.arguments, 2); @@ -258,6 +273,7 @@ describe("Over-the-wire decoding", function () { ); assert.strictEqual(getterDecoding2.kind, "function"); + assert.strictEqual(getterDecoding2.decodingMode, "full"); assert.strictEqual(getterDecoding2.abi.name, "deepString"); assert.strictEqual(getterDecoding2.class.typeName, "WireTest"); assert.lengthOf(getterDecoding2.arguments, 2); @@ -366,6 +382,7 @@ describe("Over-the-wire decoding", function () { let dangerEventDecoding = dangerEventDecodings[0]; assert.strictEqual(constructorEventDecoding.kind, "event"); + assert.strictEqual(constructorEventDecoding.decodingMode, "full"); assert.strictEqual(constructorEventDecoding.class.typeName, "WireTest"); assert.strictEqual(constructorEventDecoding.definedIn.typeName, "WireTest"); assert.strictEqual(constructorEventDecoding.abi.name, "ConstructorEvent"); @@ -393,10 +410,11 @@ describe("Over-the-wire decoding", function () { ); assert.strictEqual(emitStuffEventDecoding.kind, "event"); + assert.strictEqual(emitStuffEventDecoding.decodingMode, "full"); assert.strictEqual(emitStuffEventDecoding.abi.name, "EmitStuff"); assert.strictEqual(emitStuffEventDecoding.class.typeName, "WireTest"); assert.strictEqual(emitStuffEventDecoding.definedIn.typeName, "WireTest"); - assert.lengthOf(emitStuffEventDecoding.arguments, 3); + assert.lengthOf(emitStuffEventDecoding.arguments, 4); assert.isUndefined(emitStuffEventDecoding.arguments[0].name); assert.deepEqual( Codec.Format.Utils.Inspect.unsafeNativize( @@ -418,8 +436,16 @@ describe("Over-the-wire decoding", function () { ), emitStuffArgs[2] ); + assert.isUndefined(emitStuffEventDecoding.arguments[3].name); + assert.strictEqual( + Codec.Format.Utils.Inspect.unsafeNativize( + emitStuffEventDecoding.arguments[3].value + ), + emitStuffArgs[3] + ); assert.strictEqual(moreStuffEventDecoding.kind, "event"); + assert.strictEqual(moreStuffEventDecoding.decodingMode, "full"); assert.strictEqual(moreStuffEventDecoding.abi.name, "MoreStuff"); assert.strictEqual(moreStuffEventDecoding.class.typeName, "WireTest"); assert.strictEqual(moreStuffEventDecoding.definedIn.typeName, "WireTest"); @@ -440,6 +466,7 @@ describe("Over-the-wire decoding", function () { ); assert.strictEqual(globalTestEventDecoding.kind, "event"); + assert.strictEqual(globalTestEventDecoding.decodingMode, "full"); assert.strictEqual(globalTestEventDecoding.abi.name, "Globals"); assert.strictEqual(globalTestEventDecoding.class.typeName, "WireTest"); assert.strictEqual(globalTestEventDecoding.definedIn.typeName, "WireTest"); @@ -460,6 +487,7 @@ describe("Over-the-wire decoding", function () { ); assert.strictEqual(inheritedEventDecoding.kind, "event"); + assert.strictEqual(inheritedEventDecoding.decodingMode, "full"); assert.strictEqual(inheritedEventDecoding.abi.name, "Done"); assert.strictEqual(inheritedEventDecoding.class.typeName, "WireTest"); assert.strictEqual( @@ -469,6 +497,7 @@ describe("Over-the-wire decoding", function () { assert.isEmpty(inheritedEventDecoding.arguments); assert.strictEqual(indexTestEventDecoding.kind, "event"); + assert.strictEqual(indexTestEventDecoding.decodingMode, "full"); assert.strictEqual(indexTestEventDecoding.abi.name, "HasIndices"); assert.strictEqual(indexTestEventDecoding.class.typeName, "WireTest"); assert.strictEqual(indexTestEventDecoding.definedIn.typeName, "WireTest"); @@ -509,6 +538,7 @@ describe("Over-the-wire decoding", function () { ); assert.strictEqual(libraryTestEventDecoding.kind, "event"); + assert.strictEqual(libraryTestEventDecoding.decodingMode, "full"); assert.strictEqual(libraryTestEventDecoding.abi.name, "LibraryEvent"); assert.strictEqual( libraryTestEventDecoding.class.typeName, @@ -528,6 +558,7 @@ describe("Over-the-wire decoding", function () { ); assert.strictEqual(dangerEventDecoding.kind, "event"); + assert.strictEqual(dangerEventDecoding.decodingMode, "full"); assert.strictEqual(dangerEventDecoding.abi.name, "Danger"); assert.lengthOf(dangerEventDecoding.arguments, 1); assert.isUndefined(dangerEventDecoding.arguments[0].name); @@ -930,7 +961,7 @@ describe("Over-the-wire decoding", function () { let decoding = decodings[0]; assert.strictEqual(decoding.kind, "return"); assert.strictEqual(decoding.decodingMode, "full"); - assert.lengthOf(decoding.arguments, 2); + assert.lengthOf(decoding.arguments, 3); assert.deepEqual( Codec.Format.Utils.Inspect.unsafeNativize(decoding.arguments[0].value), { @@ -943,6 +974,10 @@ describe("Over-the-wire decoding", function () { Codec.Format.Utils.Inspect.unsafeNativize(decoding.arguments[1].value), "WireTest.Ternary.No" ); + assert.strictEqual( + Codec.Format.Utils.Inspect.unsafeNativize(decoding.arguments[2].value), + -1 + ); //now: let's try decoding a self-destruct :D let sdAbiEntry = WireTest.abi.find( diff --git a/packages/decoder/test/current/truffle-config.js b/packages/decoder/test/current/truffle-config.js index 244ab4490c4..e90d008aebc 100644 --- a/packages/decoder/test/current/truffle-config.js +++ b/packages/decoder/test/current/truffle-config.js @@ -56,7 +56,7 @@ module.exports = { // Configure your compilers compilers: { solc: { - version: "0.8.4" // Fetch exact version from solc-bin (default: truffle's version) + version: "0.8.9" // Fetch exact version from solc-bin (default: truffle's version) // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) // settings: { // See the solidity docs for advice about optimization and evmVersion // optimizer: { diff --git a/packages/deployer/package.json b/packages/deployer/package.json index b7997a1b7aa..216d91ca485 100644 --- a/packages/deployer/package.json +++ b/packages/deployer/package.json @@ -12,7 +12,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "3.2.39", + "version": "3.2.47", "main": "index.js", "scripts": { "prepare": "exit 0", @@ -22,19 +22,19 @@ "@ensdomains/ens": "^0.4.0", "@ensdomains/ensjs": "^2.0.1", "@ensdomains/resolver": "^0.2.0", - "@truffle/contract": "^4.3.30", + "@truffle/contract": "^4.3.38", "@truffle/expect": "^0.0.18", "emittery": "^0.4.1", "eth-ens-namehash": "^2.0.8", - "web3-utils": "1.5.2" + "web3-utils": "1.5.3" }, "devDependencies": { - "@truffle/reporters": "^2.0.4", - "@truffle/workflow-compile": "^3.2.25", + "@truffle/reporters": "^2.0.7", + "@truffle/workflow-compile": "^3.2.33", "ganache-core": "2.13.0", "mocha": "8.1.2", "sinon": "^9.0.2", - "web3": "1.5.2" + "web3": "1.5.3" }, "keywords": [ "contracts", diff --git a/packages/environment/package.json b/packages/environment/package.json index 163c8d2b07c..c42511f695e 100644 --- a/packages/environment/package.json +++ b/packages/environment/package.json @@ -13,21 +13,21 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "0.2.67", + "version": "0.2.75", "main": "index.js", "scripts": { "prepare": "exit 0" }, "dependencies": { - "@truffle/artifactor": "^4.0.118", + "@truffle/artifactor": "^4.0.126", "@truffle/error": "^0.0.14", "@truffle/expect": "^0.0.18", - "@truffle/interface-adapter": "^0.5.4", - "@truffle/resolver": "^7.0.24", + "@truffle/interface-adapter": "^0.5.8", + "@truffle/resolver": "^7.0.32", "ganache-core": "2.13.0", "node-ipc": "^9.1.1", "source-map-support": "^0.5.19", - "web3": "1.5.2" + "web3": "1.5.3" }, "devDependencies": { "debug": "^4.3.1" diff --git a/packages/events/defaultSubscribers/compile.js b/packages/events/defaultSubscribers/compile.js index 612bb748306..5e1f139b245 100644 --- a/packages/events/defaultSubscribers/compile.js +++ b/packages/events/defaultSubscribers/compile.js @@ -55,6 +55,13 @@ module.exports = { this.logger.log(`${OS.EOL} ${warnings.join()}`); } ], + "compile:infos": [ + function ({ infos }) { + if (this.quiet) return; + this.logger.log("> Compilation notices encountered:"); + this.logger.log(`${OS.EOL} ${infos.join()}`); + } + ], "compile:nothingToCompile": [ function () { if (this.quiet) return; @@ -62,6 +69,14 @@ module.exports = { `> Everything is up to date, there is nothing to compile.` ); } + ], + "compile:skipped": [ + function () { + if (this.quiet) return; + this.logger.log( + `> Compilation skipped because --compile-none option was passed.` + ); + } ] } }; diff --git a/packages/events/defaultSubscribers/obtain.js b/packages/events/defaultSubscribers/obtain.js index a52bdc7b88a..f854d4c342c 100644 --- a/packages/events/defaultSubscribers/obtain.js +++ b/packages/events/defaultSubscribers/obtain.js @@ -9,12 +9,14 @@ module.exports = { handlers: { "obtain:start": [ function() { + if (this.quiet) return; this.logger.log(`${OS.EOL}Starting obtain...`); this.logger.log(`==================${OS.EOL}`); } ], "obtain:succeed": [ function({ compiler }) { + if (this.quiet) return; const { name, version } = compiler; this.logger.log( ` > successfully downloaded and cached version ${version} ` + @@ -24,6 +26,7 @@ module.exports = { ], "obtain:fail": [ function() { + if (this.quiet) return; if (this.spinner.isSpinning) this.spinner.fail(); this.logger.log("Unbox failed!"); } @@ -31,6 +34,7 @@ module.exports = { "downloadCompiler:start": [ function({ attemptNumber }) { + if (this.quiet) return; this.spinner = this.ora({ text: `Downloading compiler. Attempt #${attemptNumber}.`, color: "red" @@ -39,12 +43,13 @@ module.exports = { ], "downloadCompiler:succeed": [ function() { + if (this.quiet) return; this.spinner.succeed(); } ], - "fetchSolcList:start": [ function({ attemptNumber }) { + if (this.quiet) return; this.spinner = this.ora({ text: `Fetching solc version list from solc-bin. Attempt #${attemptNumber}`, color: "yellow" @@ -53,11 +58,13 @@ module.exports = { ], "fetchSolcList:succeed": [ function() { + if (this.quiet) return; if (this.spinner.isSpinning) this.spinner.succeed(); } ], "fetchSolcList:fail": [ function() { + if (this.quiet) return; if (this.spinner.isSpinning) this.spinner.fail(); } ] diff --git a/packages/events/package.json b/packages/events/package.json index 15929997a68..77391df97a4 100644 --- a/packages/events/package.json +++ b/packages/events/package.json @@ -1,6 +1,6 @@ { "name": "@truffle/events", - "version": "0.0.13", + "version": "0.0.16", "description": "Event system for Truffle", "main": "index.js", "keywords": [], diff --git a/packages/external-compile/package.json b/packages/external-compile/package.json index 7de525d931a..d909ea51d2f 100644 --- a/packages/external-compile/package.json +++ b/packages/external-compile/package.json @@ -3,7 +3,7 @@ "description": "Wrapper to compile Truffle contracts with arbitrary shell command", "license": "MIT", "author": "g. nicholas d'andrea ", - "homepage": "https://github.com/trufflesuite/truffle#readme", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/external-compile#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", @@ -12,19 +12,19 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "2.0.21", + "version": "2.0.27", "main": "index.js", "scripts": { "prepare": "exit 0", "test": "mocha" }, "dependencies": { - "@truffle/config": "^1.3.4", + "@truffle/config": "^1.3.10", "@truffle/contract-schema": "^3.4.3", "@truffle/expect": "^0.0.18", "debug": "^4.3.1", "glob": "^7.1.6", - "web3-utils": "1.5.2" + "web3-utils": "1.5.3" }, "devDependencies": { "chai": "^4.2.0", diff --git a/packages/fetch-and-compile/lib/recognizer.ts b/packages/fetch-and-compile/lib/recognizer.ts index 02c68f4f701..2bd913a34d2 100644 --- a/packages/fetch-and-compile/lib/recognizer.ts +++ b/packages/fetch-and-compile/lib/recognizer.ts @@ -59,10 +59,13 @@ export class SingleRecognizer implements Recognizer { addCompiledInfo( info: FetchAndCompileResult, - _address: string, + address: string, _fetcherName: string ): void { this.compileResult = info.compileResult; this.sourceInfo = info.sourceInfo; + if (address === this.address) { //I guess? this should never be false + this.recognized = true; + } } } diff --git a/packages/fetch-and-compile/package.json b/packages/fetch-and-compile/package.json index 57078dd4a47..2b9243b4805 100644 --- a/packages/fetch-and-compile/package.json +++ b/packages/fetch-and-compile/package.json @@ -1,6 +1,6 @@ { "name": "@truffle/fetch-and-compile", - "version": "0.1.2", + "version": "0.1.10", "description": "Used to obtain external verified sources and compile them", "main": "dist/index.js", "scripts": { @@ -9,7 +9,7 @@ }, "author": "Harry Altman ", "license": "MIT", - "homepage": "https://github.com/trufflesuite/truffle#readme", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/fetch-and-compile#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", @@ -38,14 +38,14 @@ "access": "public" }, "dependencies": { - "@truffle/codec": "^0.11.10", - "@truffle/compile-solidity": "^5.3.17", - "@truffle/source-fetcher": "^0.5.6", + "@truffle/codec": "^0.11.17", + "@truffle/compile-solidity": "^5.3.25", + "@truffle/source-fetcher": "^0.5.9", "semver": "^7.3.4" }, "devDependencies": { - "@truffle/compile-common": "^0.7.16", - "@truffle/config": "^1.3.4", + "@truffle/compile-common": "^0.7.22", + "@truffle/config": "^1.3.10", "typescript": "^4.1.4" } } diff --git a/packages/hdwallet-provider/package.json b/packages/hdwallet-provider/package.json index 55397fc43e3..48d6ed7d31d 100644 --- a/packages/hdwallet-provider/package.json +++ b/packages/hdwallet-provider/package.json @@ -12,7 +12,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "1.4.3", + "version": "1.5.1", "main": "dist/index.js", "scripts": { "build": "tsc", @@ -21,12 +21,12 @@ }, "types": "dist/index.d.ts", "dependencies": { + "@ethereumjs/common": "^2.4.0", + "@ethereumjs/tx": "^3.3.0", "@trufflesuite/web3-provider-engine": "15.0.13-1", "eth-sig-util": "^3.0.1", "ethereum-cryptography": "^0.1.3", "ethereum-protocol": "^1.0.1", - "@ethereumjs/common": "^2.4.0", - "@ethereumjs/tx": "^3.3.0", "ethereumjs-util": "^6.1.0", "ethereumjs-wallet": "^1.0.1" }, diff --git a/packages/hdwallet-provider/src/index.ts b/packages/hdwallet-provider/src/index.ts index 12bf49fcbba..b5f4926da98 100644 --- a/packages/hdwallet-provider/src/index.ts +++ b/packages/hdwallet-provider/src/index.ts @@ -170,13 +170,11 @@ class HDWalletProvider { ) }; } - // Taken from https://github.com/ethers-io/ethers.js/blob/2a7ce0e72a1e0c9469e10392b0329e75e341cf18/packages/abstract-signer/src.ts/index.ts#L215 const hasEip1559 = (txParams.maxFeePerGas !== undefined || txParams.maxPriorityFeePerGas !== undefined); const tx = hasEip1559 ? FeeMarketEIP1559Transaction.fromTxData(txParams, txOptions) : Transaction.fromTxData(txParams, txOptions); - const signedTx = tx.sign(pkey as Buffer); const rawTx = `0x${signedTx.serialize().toString("hex")}`; cb(null, rawTx); diff --git a/packages/interface-adapter/lib/adapter/types.ts b/packages/interface-adapter/lib/adapter/types.ts index 8cdb0754e5e..c16ed9be2f5 100644 --- a/packages/interface-adapter/lib/adapter/types.ts +++ b/packages/interface-adapter/lib/adapter/types.ts @@ -40,7 +40,7 @@ export interface InterfaceAdapter { getBalance(address: string): Promise; getCode(address: string): Promise; getAccounts(): Promise; - estimateGas(transactionConfig: Transaction): Promise; + estimateGas(transactionConfig: Transaction, stacktrace: boolean): Promise | null; getTransactionCostReport(receipt: TransactionReceipt): Promise; displayCost(value: BN): string; } diff --git a/packages/interface-adapter/lib/adapter/web3/index.ts b/packages/interface-adapter/lib/adapter/web3/index.ts index 17eb84edcb9..6ce0fa34934 100644 --- a/packages/interface-adapter/lib/adapter/web3/index.ts +++ b/packages/interface-adapter/lib/adapter/web3/index.ts @@ -49,8 +49,20 @@ export class Web3InterfaceAdapter implements InterfaceAdapter { return this.web3.eth.getAccounts(); } - public estimateGas(transactionConfig: Transaction) { - return this.web3.eth.estimateGas(transactionConfig); + public async estimateGas(transactionConfig: Transaction, stacktrace = false) { + // web3 does not error gracefully when gas estimation fails due to a revert, + // so in cases where we want to get past this (debugging/stacktracing), we must + // catch the error and return null instead + if (stacktrace === true) { + try { + const gasEstimate = await this.web3.eth.estimateGas(transactionConfig); + return gasEstimate; + } catch { + return null; + } + } else { + return this.web3.eth.estimateGas(transactionConfig); + } } public getBlockNumber() { diff --git a/packages/interface-adapter/package.json b/packages/interface-adapter/package.json index 53db8df778b..4824d38346c 100644 --- a/packages/interface-adapter/package.json +++ b/packages/interface-adapter/package.json @@ -2,7 +2,7 @@ "name": "@truffle/interface-adapter", "description": "A library that provides an adapter layer for Truffle to interace with different types of networks/ledgers.", "license": "MIT", - "homepage": "https://github.com/trufflesuite/truffle#readme", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/interface-adapter#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "0.5.4", + "version": "0.5.8", "main": "dist/index.js", "directories": { "lib": "lib" @@ -26,7 +26,7 @@ "dependencies": { "bn.js": "^5.1.3", "ethers": "^4.0.32", - "web3": "1.5.2" + "web3": "1.5.3" }, "devDependencies": { "@types/bn.js": "^4.11.4", diff --git a/packages/migrate/package.json b/packages/migrate/package.json index bc937b37a51..57148eb50b3 100644 --- a/packages/migrate/package.json +++ b/packages/migrate/package.json @@ -12,20 +12,20 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "3.2.39", + "version": "3.2.47", "main": "index.js", "scripts": { "prepare": "exit 0", "test": "mocha ./test/* ./test/**/*" }, "dependencies": { - "@truffle/config": "^1.3.4", - "@truffle/db-loader": "^0.0.5", - "@truffle/deployer": "^3.2.39", + "@truffle/config": "^1.3.10", + "@truffle/db-loader": "^0.0.13", + "@truffle/deployer": "^3.2.47", "@truffle/expect": "^0.0.18", - "@truffle/interface-adapter": "^0.5.4", - "@truffle/reporters": "^2.0.4", - "@truffle/require": "^2.0.72", + "@truffle/interface-adapter": "^0.5.8", + "@truffle/reporters": "^2.0.7", + "@truffle/require": "^2.0.78", "emittery": "^0.4.1", "glob": "^7.1.6" }, diff --git a/packages/profiler/.gitignore b/packages/profiler/.gitignore new file mode 100644 index 00000000000..1521c8b7652 --- /dev/null +++ b/packages/profiler/.gitignore @@ -0,0 +1 @@ +dist diff --git a/packages/profiler/package.json b/packages/profiler/package.json new file mode 100644 index 00000000000..c8adb88f271 --- /dev/null +++ b/packages/profiler/package.json @@ -0,0 +1,36 @@ +{ + "name": "@truffle/profiler", + "version": "0.1.1", + "description": "Package for dealing with Solidity sources along with their Truffle artifacts", + "main": "dist/src/index.js", + "types": "dist/src/index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/trufflesuite/truffle.git", + "directory": "packages/profiler" + }, + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/profiler#readme", + "bugs": { + "url": "https://github.com/trufflesuite/truffle/issues" + }, + "license": "MIT", + "scripts": { + "build": "tsc", + "prepare": "yarn build", + "watch": "tsc -w" + }, + "devDependencies": { + "@truffle/config": "^1.3.10", + "@types/node": "12.12.21", + "ts-node": "^9.0.0", + "typescript": "^4.1.4" + }, + "dependencies": { + "@truffle/contract-sources": "^0.1.12", + "debug": "^4.3.1" + }, + "publishConfig": { + "access": "public" + }, + "gitHead": "6b84be7849142588ef2e3224d8a9d7c2ceeb6e4a" +} diff --git a/packages/compile-common/src/profiler/convertToAbsolutePaths.ts b/packages/profiler/src/convertToAbsolutePaths.ts similarity index 100% rename from packages/compile-common/src/profiler/convertToAbsolutePaths.ts rename to packages/profiler/src/convertToAbsolutePaths.ts diff --git a/packages/compile-common/src/profiler/getImports.ts b/packages/profiler/src/getImports.ts similarity index 100% rename from packages/compile-common/src/profiler/getImports.ts rename to packages/profiler/src/getImports.ts diff --git a/packages/compile-common/src/profiler/profiler.ts b/packages/profiler/src/index.ts similarity index 100% rename from packages/compile-common/src/profiler/profiler.ts rename to packages/profiler/src/index.ts diff --git a/packages/compile-common/src/profiler/isExplicitlyRelative.ts b/packages/profiler/src/isExplicitlyRelative.ts similarity index 100% rename from packages/compile-common/src/profiler/isExplicitlyRelative.ts rename to packages/profiler/src/isExplicitlyRelative.ts diff --git a/packages/compile-common/src/profiler/requiredSources.ts b/packages/profiler/src/requiredSources.ts similarity index 100% rename from packages/compile-common/src/profiler/requiredSources.ts rename to packages/profiler/src/requiredSources.ts diff --git a/packages/compile-common/src/profiler/resolveAllSources.ts b/packages/profiler/src/resolveAllSources.ts similarity index 100% rename from packages/compile-common/src/profiler/resolveAllSources.ts rename to packages/profiler/src/resolveAllSources.ts diff --git a/packages/compile-common/src/profiler/updated.ts b/packages/profiler/src/updated.ts similarity index 100% rename from packages/compile-common/src/profiler/updated.ts rename to packages/profiler/src/updated.ts diff --git a/packages/profiler/tsconfig.json b/packages/profiler/tsconfig.json new file mode 100644 index 00000000000..1a3f6b60a70 --- /dev/null +++ b/packages/profiler/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "module": "commonjs", + "esModuleInterop": true, + "declaration": true, + "target": "es2016", + "noImplicitAny": true, + "moduleResolution": "node", + "sourceMap": true, + "outDir": "dist", + "baseUrl": ".", + "lib": ["es2017"], + "paths": { + }, + "rootDir": ".", + "types": ["node"], + }, + "include": [ + "./src/**/*.ts" + ] +} diff --git a/packages/provider/index.js b/packages/provider/index.js index ccf76678332..bf1772be8c9 100644 --- a/packages/provider/index.js +++ b/packages/provider/index.js @@ -44,13 +44,14 @@ module.exports = { networkCheckTimeout = DEFAULT_NETWORK_CHECK_TIMEOUT; } const provider = this.getProvider(options); + const { host } = provider; const interfaceAdapter = createInterfaceAdapter({ provider, networkType }); return new Promise((resolve, reject) => { const noResponseFromNetworkCall = setTimeout(() => { const errorMessage = - "There was a timeout while attempting to connect to the network." + - "\n Check to see that your provider is valid.\n If you " + - "have a slow internet connection, try configuring a longer " + + "There was a timeout while attempting to connect to the network at " + host + + ".\n Check to see that your provider is valid." + + "\n If you have a slow internet connection, try configuring a longer " + "timeout in your Truffle config. Use the " + "networks[networkName].networkCheckTimeout property to do this."; throw new Error(errorMessage); @@ -64,10 +65,10 @@ module.exports = { clearTimeout(noResponseFromNetworkCall); clearTimeout(networkCheck); return resolve(true); - } catch (error) { + } catch (error) { console.log( - "> Something went wrong while attempting to connect " + - "to the network. Check your network configuration." + "> Something went wrong while attempting to connect to the " + + "network at " + host + ". Check your network configuration." ); clearTimeout(noResponseFromNetworkCall); clearTimeout(networkCheck); diff --git a/packages/provider/package.json b/packages/provider/package.json index 4274d5cd4c1..312d0094586 100644 --- a/packages/provider/package.json +++ b/packages/provider/package.json @@ -12,7 +12,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "0.2.37", + "version": "0.2.42", "main": "index.js", "scripts": { "prepare": "exit 0", @@ -21,8 +21,8 @@ "types": "./typings/index.d.ts", "dependencies": { "@truffle/error": "^0.0.14", - "@truffle/interface-adapter": "^0.5.4", - "web3": "1.5.2" + "@truffle/interface-adapter": "^0.5.8", + "web3": "1.5.3" }, "devDependencies": { "ganache-core": "2.13.0", diff --git a/packages/provisioner/package.json b/packages/provisioner/package.json index 070ba13e627..cb25e8b37e5 100644 --- a/packages/provisioner/package.json +++ b/packages/provisioner/package.json @@ -1,6 +1,6 @@ { "name": "@truffle/provisioner", - "version": "0.2.27", + "version": "0.2.33", "description": "Provision contract objects for use from multiple sources", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -35,6 +35,6 @@ "typescript": "^4.1.4" }, "dependencies": { - "@truffle/config": "^1.3.4" + "@truffle/config": "^1.3.10" } } diff --git a/packages/reporters/package.json b/packages/reporters/package.json index a15347f9327..72b971a2ed0 100644 --- a/packages/reporters/package.json +++ b/packages/reporters/package.json @@ -3,7 +3,7 @@ "description": "Reporters for Truffle modules", "license": "MIT", "author": "", - "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/provisioner#reporters", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/reporters#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", @@ -12,14 +12,14 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "2.0.4", + "version": "2.0.7", "main": "index.js", "scripts": { "prepare": "exit 0" }, "dependencies": { "ora": "^3.4.0", - "web3-utils": "1.5.2" + "web3-utils": "1.5.3" }, "publishConfig": { "access": "public" diff --git a/packages/require/package.json b/packages/require/package.json index 77667bb4fcb..22cc1c68a3a 100644 --- a/packages/require/package.json +++ b/packages/require/package.json @@ -12,16 +12,16 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "2.0.72", + "version": "2.0.78", "main": "require.js", "scripts": { "prepare": "exit 0", "test": "mocha" }, "dependencies": { - "@truffle/config": "^1.3.4", + "@truffle/config": "^1.3.10", "@truffle/expect": "^0.0.18", - "@truffle/interface-adapter": "^0.5.4", + "@truffle/interface-adapter": "^0.5.8", "original-require": "^1.0.1" }, "devDependencies": { diff --git a/packages/resolver/package.json b/packages/resolver/package.json index 0c9cb0f6a4e..0ea8b2ee515 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -12,7 +12,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "7.0.24", + "version": "7.0.32", "main": "dist/lib/index.js", "files": [ "dist", @@ -27,10 +27,10 @@ }, "types": "dist/lib/index.d.ts", "dependencies": { - "@truffle/contract": "^4.3.30", + "@truffle/contract": "^4.3.38", "@truffle/contract-sources": "^0.1.12", "@truffle/expect": "^0.0.18", - "@truffle/provisioner": "^0.2.27", + "@truffle/provisioner": "^0.2.33", "abi-to-sol": "^0.2.0", "debug": "^4.3.1", "detect-installed": "^2.0.4", diff --git a/packages/source-fetcher/package.json b/packages/source-fetcher/package.json index 302fa033536..16342a3b1f8 100644 --- a/packages/source-fetcher/package.json +++ b/packages/source-fetcher/package.json @@ -3,7 +3,7 @@ "description": "Fetches verified source code from services such as Etherscan", "license": "MIT", "author": "Harry Altman ", - "homepage": "https://github.com/trufflesuite/truffle#readme", + "homepage": "https://github.com/trufflesuite/truffle/tree/master/packages/source-fetcher#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", @@ -12,7 +12,7 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "0.5.6", + "version": "0.5.9", "main": "dist/index.js", "files": [ "dist" @@ -29,7 +29,7 @@ "async-retry": "^1.3.1", "axios": "^0.21.1", "debug": "^4.3.1", - "web3-utils": "1.5.2" + "web3-utils": "1.5.3" }, "devDependencies": { "@types/async-retry": "^1.4.3", diff --git a/packages/source-map-utils/index.js b/packages/source-map-utils/index.js index 48769832025..43558846b5c 100644 --- a/packages/source-map-utils/index.js +++ b/packages/source-map-utils/index.js @@ -202,14 +202,16 @@ var SourceMapUtils = { .filter(instruction => instruction.name === "JUMPDEST") .map(instruction => { debug("instruction %O", instruction); - let sourceIndex = instruction.file; + const sourceIndex = instruction.file; //first off, a special case: if the file is -1, check for designated //invalid and if it's not that give up //(designated invalid gets file -1 in some Solidity versions) if (sourceIndex === -1) { if ( SourceMapUtils.isDesignatedInvalid( - instructions.slice(instruction.index) + instructions, + instruction.index, + overlapFunctions ) ) { //designated invalid, include it @@ -224,13 +226,13 @@ var SourceMapUtils = { } } //now we proceed with the normal case - let findOverlappingRange = overlapFunctions[sourceIndex]; - let ast = asts[sourceIndex]; + const findOverlappingRange = overlapFunctions[sourceIndex]; + const ast = asts[sourceIndex]; if (!ast) { //if we can't get the ast... filter it out I guess return {}; } - let range = SourceMapUtils.getSourceRange(instruction); + const range = SourceMapUtils.getSourceRange(instruction); let { node, pointer } = SourceMapUtils.findRange( findOverlappingRange, range.start, @@ -244,7 +246,10 @@ var SourceMapUtils = { //except for the designated invalid function if ( SourceMapUtils.isDesignatedInvalid( - instructions.slice(instruction.index) + instructions, + instruction.index, + overlapFunctions, + node ) ) { //designated invalid, include it @@ -380,11 +385,16 @@ var SourceMapUtils = { return [start, start + length]; }, - //takes an array of instructions (as returned by parseCode) - //and asks: is the start of this instruction array the + //takes an array of instructions & an index into it + //and asks: is this index the start of this instruction array the //start of a Solidity designated invalid function? //i.e. what an uninitialized internal function pointer jumps to? - isDesignatedInvalid: function (instructions) { + isDesignatedInvalid: function ( + instructions, + index, + overlapFunctions, + node = undefined + ) { const oldSequence = [{ name: "JUMPDEST" }, { name: "INVALID" }]; const panicSelector = Web3Utils.soliditySha3({ type: "string", @@ -408,11 +418,13 @@ var SourceMapUtils = { { name: "REVERT" } ]; - const checkAgainstTemplate = (instructions, template) => { - for (let index = 0; index < template.length; index++) { - const instruction = instructions[index]; - const comparison = template[index]; - if (!instruction || instruction.name !== comparison.name) { + const checkAgainstTemplate = (instructions, index, template) => { + for (let offset = 0; offset < template.length; offset++) { + const instruction = instructions[index + offset]; + const comparison = template[offset]; + if ( + !instruction || instruction.name !== comparison.name + ) { return false; } if ( @@ -425,10 +437,86 @@ var SourceMapUtils = { return true; }; - return ( - checkAgainstTemplate(instructions, oldSequence) || - checkAgainstTemplate(instructions, newSequence) - ); + //gets the final pushdata in a JUMPDEST, PUSH, [PUSH,] JUMP sequence; + //returns null if the code is not of that form + const getIndirectAddress = (instructions, startingIndex) => { + let index = startingIndex; + if (instructions[index].name !== "JUMPDEST") { + return null; + } + index++; + while (instructions[index].name.match(/^PUSH\d*/)) { + index++; + if (index > startingIndex + 3) { + //check: are there more than 2 PUSHes? + return null; + } + } + if (instructions[index].name === "JUMP") { + if (index === startingIndex + 1) { + //check: was there at least one push? + return null; + } + index--; + return parseInt(instructions[index].pushData); + } else { + return null; + } + }; + + //if it matches either direct template, return true + if ( + checkAgainstTemplate(instructions, index, oldSequence) || + checkAgainstTemplate(instructions, index, newSequence) + ) { + return true; + } + + //if it's panic_error_0x51, return true + if ( + node && + node.nodeType === "YulFunctionDefinition" && + node.name === "panic_error_0x51" + ) { + return true; + } + + //otherwise, check if it's indirect for the new template + //(or for panic_error_0x51) + const jumpAddress = getIndirectAddress(instructions, index); + if (jumpAddress !== null) { + const jumpIndex = instructions.findIndex( + instruction => instruction.pc === jumpAddress + ); + if (checkAgainstTemplate(instructions, jumpIndex, newSequence)) { + return true; + } + debug("indirect: %O", instructions.slice(index, index + 4)); + debug("jumpAddress: %d", jumpAddress); + debug("jumpIndex: %d", jumpIndex); + debug("instr count: %d", instructions.length); + const jumpInstruction = instructions[jumpIndex]; + const jumpFile = jumpInstruction.file; + if (jumpFile !== -1) { + const findOverlappingRange = overlapFunctions[jumpFile]; + const range = SourceMapUtils.getSourceRange(jumpInstruction); + const { node: jumpNode } = SourceMapUtils.findRange( + findOverlappingRange, + range.start, + range.length + ); + if ( + jumpNode && + jumpNode.nodeType === "YulFunctionDefinition" && + jumpNode.name === "panic_error_0x51" + ) { + return true; + } + } + } + + //otherwise, return false + return false; } }; diff --git a/packages/source-map-utils/package.json b/packages/source-map-utils/package.json index aef2c7c1a4a..2dfd2a2fa76 100644 --- a/packages/source-map-utils/package.json +++ b/packages/source-map-utils/package.json @@ -12,18 +12,18 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "1.3.54", + "version": "1.3.61", "main": "index.js", "scripts": { "prepare": "exit 0" }, "dependencies": { - "@truffle/code-utils": "^1.2.29", - "@truffle/codec": "^0.11.10", + "@truffle/code-utils": "^1.2.30", + "@truffle/codec": "^0.11.17", "debug": "^4.3.1", "json-pointer": "^0.6.0", "node-interval-tree": "^1.3.3", - "web3-utils": "1.5.2" + "web3-utils": "1.5.3" }, "keywords": [ "contracts", diff --git a/packages/truffle/package.json b/packages/truffle/package.json index ba3e6333c1d..9b8469752e3 100644 --- a/packages/truffle/package.json +++ b/packages/truffle/package.json @@ -3,7 +3,7 @@ "description": "Truffle - Simple development framework for Ethereum", "license": "MIT", "author": "consensys.net", - "homepage": "https://github.com/trufflesuite/truffle/", + "homepage": "https://github.com/trufflesuite/truffle#readme", "repository": { "type": "git", "url": "https://github.com/trufflesuite/truffle.git", @@ -12,16 +12,15 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "5.4.6", + "version": "5.4.14", "main": "./build/library.bundled.js", "bin": { "truffle": "./build/cli.bundled.js" }, "scripts": { "analyze": "./scripts/analyze.sh", - "build": "yarn build:patch && yarn build:cli", + "build": "yarn build:cli", "build:cli": "node --max-old-space-size=8192 ./node_modules/webpack/bin/webpack --config ./webpack.config.js", - "build:patch": "node ./scripts/patchHighlightJsSolidity.js", "postinstall": "node ./scripts/postinstall.js", "prepare": "yarn build", "publish:byoc": "node ./scripts/prereleaseVersion.js byoc-safe byoc", @@ -32,25 +31,25 @@ "test:raw": "NO_BUILD=true mocha" }, "optionalDependencies": { - "@truffle/db": "^0.5.26", + "@truffle/db": "^0.5.34", "@truffle/preserve-fs": "^0.2.4", "@truffle/preserve-to-buckets": "^0.2.4", "@truffle/preserve-to-filecoin": "^0.2.4", "@truffle/preserve-to-ipfs": "^0.2.4" }, "dependencies": { - "@truffle/db-loader": "^0.0.5", - "@truffle/debugger": "^9.1.11", + "@truffle/db-loader": "^0.0.13", + "@truffle/debugger": "^9.1.19", "app-module-path": "^2.2.0", "mocha": "8.1.2", "original-require": "^1.0.1" }, "devDependencies": { - "@truffle/box": "^2.1.24", - "@truffle/config": "^1.3.4", - "@truffle/contract": "^4.3.30", - "@truffle/core": "^5.4.6", - "@truffle/interface-adapter": "^0.5.4", + "@truffle/box": "^2.1.30", + "@truffle/config": "^1.3.10", + "@truffle/contract": "^4.3.38", + "@truffle/core": "^5.4.14", + "@truffle/interface-adapter": "^0.5.8", "clean-webpack-plugin": "^3.0.0", "copy-webpack-plugin": "^7.0.0", "eslint": "^5.7.0", @@ -66,7 +65,7 @@ "shebang-loader": "0.0.1", "stream-buffers": "^3.0.1", "tmp": "^0.2.1", - "web3": "1.5.2", + "web3": "1.5.3", "webpack": "^5.21.2", "webpack-bundle-analyzer": "^3.0.3", "webpack-cli": "^4.5.0", diff --git a/packages/truffle/scripts/patchHighlightJsSolidity.js b/packages/truffle/scripts/patchHighlightJsSolidity.js deleted file mode 100644 index d641e47d08f..00000000000 --- a/packages/truffle/scripts/patchHighlightJsSolidity.js +++ /dev/null @@ -1,32 +0,0 @@ -const fs = require("fs"); -const path = require("path"); - -// The highlightjs-solidity package contains code that exposes a bug -// in webpack 5 (at least, what I believe to be a bug). This is a -// hack to remove the offending line that we can call before -// running webpack. - -const hljsSolidityPath = path.join( - __dirname, - "..", // truffle - "..", // packages - "..", // root - "node_modules", - "highlightjs-solidity", - "solidity.js" -); - -const offendingCode = - "var module = module ? module : {}; // shim for browser use"; -var hljsSolidityCode; - -try { - hljsSolidityCode = fs.readFileSync(hljsSolidityPath, "utf-8"); -} catch (e) { - console.log("Error reading file: " + hljsSolidityPath); - console.log("Did you forget `yarn bootstrap`?"); - console.log(e.stack); - process.exit(1); // exit with error code -} -hljsSolidityCode = hljsSolidityCode.replace(offendingCode, ""); -fs.writeFileSync(hljsSolidityPath, hljsSolidityCode, "utf-8"); diff --git a/packages/truffle/test/scenarios/commands/install.js b/packages/truffle/test/scenarios/commands/install.js index f6c60dbe45c..bcf8d06c61f 100644 --- a/packages/truffle/test/scenarios/commands/install.js +++ b/packages/truffle/test/scenarios/commands/install.js @@ -19,5 +19,5 @@ describe("truffle install [ @standalone ]", () => { path.join(config.working_directory, "installed_contracts") ); assert(theInstallDirExists); - }).timeout(30000); + }).timeout(45000); }); diff --git a/packages/truffle/test/scenarios/commands/obtain.js b/packages/truffle/test/scenarios/commands/obtain.js new file mode 100644 index 00000000000..058138fcaa8 --- /dev/null +++ b/packages/truffle/test/scenarios/commands/obtain.js @@ -0,0 +1,63 @@ +const MemoryLogger = require("../MemoryLogger"); +const CommandRunner = require("../commandRunner"); +const Config = require("@truffle/config"); +const fse = require("fs-extra"); +const path = require("path"); +const assert = require("assert"); +const sandbox = require("../sandbox"); + +let logger, config, project, expectedPath; + +describe("truffle obtain", function () { + project = path.join(__dirname, "../../sources/obtain"); + + beforeEach(async function () { + expectedPath = path.join( + Config.getTruffleDataDirectory(), + "compilers", + "node_modules", + "soljson-v0.7.2+commit.51b20bc0.js" + ); + this.timeout(10000); + config = await sandbox.create(project); + logger = new MemoryLogger(); + config.logger = logger; + }); + + it("fetches the solc version specified", async function () { + this.timeout(70000); + // ensure the compiler does not yet exist + try { + fse.unlinkSync(expectedPath); + } catch (error) { + // unlink throws when file doesn't exist + if (error.code !== "ENOENT") { + throw error; + } + } + await CommandRunner.run("obtain --solc=0.7.2", config); + assert(fse.statSync(expectedPath), "The compiler was not obtained!"); + fse.unlinkSync(expectedPath); + }); + + it("respects the `quiet` option", async function () { + this.timeout(70000); + // ensure the compiler does not yet exist + try { + fse.unlinkSync(expectedPath); + } catch (error) { + // unlink throws when file doesn't exist + if (error.code !== "ENOENT") { + throw error; + } + } + await CommandRunner.run("obtain --solc=0.7.2 --quiet", config); + // logger.contents() returns false as long as nothing is written to the + // stream that is used for logging in MemoryLogger + assert( + !logger.contents(), + "The command logged to the console when it shouldn't have." + ); + fse.unlinkSync(expectedPath); + }); +}); diff --git a/packages/truffle/test/scenarios/migrations/errors.js b/packages/truffle/test/scenarios/migrations/errors.js index bfbfcb84a3b..a9afe560714 100644 --- a/packages/truffle/test/scenarios/migrations/errors.js +++ b/packages/truffle/test/scenarios/migrations/errors.js @@ -7,17 +7,17 @@ const Reporter = require("../reporter"); const sandbox = require("../sandbox"); const Web3 = require("web3"); -describe("migration errors", function() { +describe("migration errors", function () { let config; let web3; let networkId; const project = path.join(__dirname, "../../sources/migrations/error"); - const logger = new MemoryLogger(); + const logger = new MemoryLogger(true); before(done => Server.start(done)); after(done => Server.stop(done)); - before(async function() { + before(async function () { this.timeout(10000); config = await sandbox.create(project); config.network = "development"; @@ -33,7 +33,7 @@ describe("migration errors", function() { networkId = await web3.eth.net.getId(); }); - it("should error and stop", async function() { + it("should error and stop", async function () { this.timeout(70000); try { @@ -64,7 +64,7 @@ describe("migration errors", function() { } }); - it("should run from the last successfully completely migration", async function() { + it("should run from the last successfully completely migration", async function () { this.timeout(70000); try { @@ -79,7 +79,7 @@ describe("migration errors", function() { } }); - it("should run out of gas correctly", async function() { + it("should run out of gas correctly", async function () { this.timeout(70000); try { @@ -99,7 +99,7 @@ describe("migration errors", function() { } }); - it("should expose the reason string if available [ @ganache ]", async function() { + it("should expose the reason string if available [ @ganache ]", async function () { this.timeout(70000); try { @@ -114,7 +114,7 @@ describe("migration errors", function() { } }); - it("should error on insufficient funds correctly [ @ganache ]", async function() { + it("should error on insufficient funds correctly [ @ganache ]", async function () { this.timeout(70000); try { @@ -131,22 +131,22 @@ describe("migration errors", function() { } }); - it("should error on insufficient funds correctly [ @geth ]", async function() { + it("should error on insufficient funds correctly [ @geth ]", async function () { this.timeout(70000); try { - await CommandRunner.run("migrate -f 6", config); + await CommandRunner.run("migrate -f 10", config); assert(false, "This should have thrown."); } catch (_error) { const output = logger.contents(); console.log(output); - assert(output.includes("6_migrations_funds.js")); + assert(output.includes("10_migrations_funds_geth.js")); assert(output.includes("Deploying 'Example'")); assert(output.includes("insufficient funds")); } }); - it("should error if user tries to use batch syntax", async function() { + it("should error if user tries to use batch syntax", async function () { this.timeout(70000); try { @@ -161,7 +161,7 @@ describe("migration errors", function() { } }); - it("should error if there are js errors in the migrations script (sync)", async function() { + it("should error if there are js errors in the migrations script (sync)", async function () { this.timeout(70000); try { @@ -175,7 +175,7 @@ describe("migration errors", function() { } }); - it("should error if there are js errors in the migrations script (async)", async function() { + it("should error if there are js errors in the migrations script (async)", async function () { this.timeout(70000); try { diff --git a/packages/truffle/test/sources/migrations/error/migrations/10_migrations_funds_geth.js b/packages/truffle/test/sources/migrations/error/migrations/10_migrations_funds_geth.js new file mode 100644 index 00000000000..6160f86e2ae --- /dev/null +++ b/packages/truffle/test/sources/migrations/error/migrations/10_migrations_funds_geth.js @@ -0,0 +1,19 @@ +const Example = artifacts.require("Example"); + +module.exports = async function (deployer, network, accounts) { + const emptyAccount = accounts[7]; + let balance = await web3.eth.getBalance(emptyAccount); + const { baseFeePerGas } = await web3.eth.getBlock("latest"); + // This transaction drains `emptyAccount` of all funds + // 21,000 gas to send ether + const priceOfGas = 21000 * baseFeePerGas; + + await web3.eth.sendTransaction({ + to: accounts[0], + from: emptyAccount, + value: balance - priceOfGas, + gasPrice: baseFeePerGas + }); + + await deployer.deploy(Example, { from: emptyAccount }); +}; diff --git a/packages/truffle/test/sources/migrations/error/migrations/6_migrations_funds.js b/packages/truffle/test/sources/migrations/error/migrations/6_migrations_funds.js index 2201e4d3b9f..314d2692c98 100644 --- a/packages/truffle/test/sources/migrations/error/migrations/6_migrations_funds.js +++ b/packages/truffle/test/sources/migrations/error/migrations/6_migrations_funds.js @@ -1,3 +1,4 @@ + const Example = artifacts.require("Example"); module.exports = async function(deployer, network, accounts) { diff --git a/packages/truffle/test/sources/obtain/truffle-config.js b/packages/truffle/test/sources/obtain/truffle-config.js new file mode 100644 index 00000000000..f053ebf7976 --- /dev/null +++ b/packages/truffle/test/sources/obtain/truffle-config.js @@ -0,0 +1 @@ +module.exports = {}; diff --git a/packages/workflow-compile/index.js b/packages/workflow-compile/index.js index eaddb83e637..9850f581775 100644 --- a/packages/workflow-compile/index.js +++ b/packages/workflow-compile/index.js @@ -74,7 +74,11 @@ const WorkflowCompile = { .filter(compiler => compiler); if (contracts.length === 0 && config.events) { - config.events.emit("compile:nothingToCompile"); + if (config.compileNone || config["compile-none"]) { + config.events.emit("compile:skipped"); + } else { + config.events.emit("compile:nothingToCompile"); + } } if (config.events) { diff --git a/packages/workflow-compile/legacy/index.js b/packages/workflow-compile/legacy/index.js index 4063cd64348..ce98034c164 100644 --- a/packages/workflow-compile/legacy/index.js +++ b/packages/workflow-compile/legacy/index.js @@ -57,7 +57,11 @@ const WorkflowCompile = { ); if (numberOfCompiledContracts === 0 && config.events) { - config.events.emit("compile:nothingToCompile"); + if (config.compileNone || config["compile-none"]) { + config.events.emit("compile:skipped"); + } else { + config.events.emit("compile:nothingToCompile"); + } } if (config.events) { diff --git a/packages/workflow-compile/package.json b/packages/workflow-compile/package.json index c716cc773fb..7475f671671 100644 --- a/packages/workflow-compile/package.json +++ b/packages/workflow-compile/package.json @@ -12,22 +12,22 @@ "bugs": { "url": "https://github.com/trufflesuite/truffle/issues" }, - "version": "3.2.25", + "version": "3.2.33", "main": "index.js", "scripts": { "prepare": "exit 0", "test": "mocha" }, "dependencies": { - "@truffle/artifactor": "^4.0.118", - "@truffle/compile-common": "^0.7.16", - "@truffle/compile-solidity": "^5.3.17", - "@truffle/compile-vyper": "^3.1.21", - "@truffle/config": "^1.3.4", - "@truffle/db-loader": "^0.0.5", + "@truffle/artifactor": "^4.0.126", + "@truffle/compile-common": "^0.7.22", + "@truffle/compile-solidity": "^5.3.25", + "@truffle/compile-vyper": "^3.1.29", + "@truffle/config": "^1.3.10", + "@truffle/db-loader": "^0.0.13", "@truffle/expect": "^0.0.18", - "@truffle/external-compile": "^2.0.21", - "@truffle/resolver": "^7.0.24", + "@truffle/external-compile": "^2.0.27", + "@truffle/resolver": "^7.0.32", "fs-extra": "^9.1.0" }, "devDependencies": { diff --git a/scripts/ci.sh b/scripts/ci.sh index 78d5e513f50..e3a846603e7 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -10,7 +10,7 @@ run_geth() { -p 8545:8545 \ -p 8546:8546 \ -p 30303:30303 \ - ethereum/client-go:v1.10.3 \ + ethereum/client-go:stable \ --http \ --http.addr '0.0.0.0' \ --http.port 8545 \ @@ -39,7 +39,7 @@ if [ "$INTEGRATION" = true ]; then elif [ "$GETH" = true ]; then sudo apt install -y jq - docker pull ethereum/client-go:v1.10.3 + docker pull ethereum/client-go:stable run_geth sleep 30 lerna run --scope truffle test --stream -- --exit diff --git a/scripts/geth.sh b/scripts/geth.sh index 5784542b9d6..19080b213f6 100755 --- a/scripts/geth.sh +++ b/scripts/geth.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -docker pull ethereum/client-go:v1.10.3 +docker pull ethereum/client-go:stable docker run \ -v /$PWD/scripts:/scripts \ @@ -8,7 +8,7 @@ docker run \ -p 8545:8545 \ -p 8546:8546 \ -p 30303:30303 \ - ethereum/client-go:v1.10.3 \ + ethereum/client-go:stable \ --http \ --http.addr '0.0.0.0' \ --http.port 8545 \ diff --git a/scripts/npm-access.js b/scripts/npm-access.js index 37d49cb5250..562465d6f54 100644 --- a/scripts/npm-access.js +++ b/scripts/npm-access.js @@ -6,7 +6,15 @@ const getPkgPermissions = userOrOrg => { return JSON.parse(stringResponse); }; -const orgs = ["trufflesuite", "truffle"]; +const getMonorepoPackages = () => { + const pkgs = execSync('lerna ls') + .toString() + .split("\n") + .filter(ln => !/^lerna/.test(ln)); + return new Set(pkgs); +} + +const orgs = ["truffle"]; for (let org of orgs) { const permissions = getPkgPermissions(org); @@ -19,8 +27,14 @@ for (let org of orgs) { const username = getNpmUsername(); const userPermissionsObject = getPkgPermissions(username); + const monoPkgs = getMonorepoPackages(); for (const pkg in permissions) { + // skip perm checks if package not in monorepo + if (!monoPkgs.has(pkg)) { + continue + } + if (!userPermissionsObject[pkg]) throw new Error(`You don't have permissions to publish ${pkg}`); if (permissions[pkg] !== userPermissionsObject[pkg]) diff --git a/yarn.lock b/yarn.lock index 73625521df7..82ace2584e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4339,6 +4339,13 @@ dependencies: "@types/lodash" "*" +"@types/lodash.pick@^4.4.6": + version "4.4.6" + resolved "https://registry.yarnpkg.com/@types/lodash.pick/-/lodash.pick-4.4.6.tgz#ae4e8f109e982786313bb6aac4b1a73aefa6e9be" + integrity sha512-u8bzA16qQ+8dY280z3aK7PoWb3fzX5ATJ0rJB6F+uqchOX2VYF02Aqa+8aYiHiHgPzQiITqCgeimlyKFy4OA6g== + dependencies: + "@types/lodash" "*" + "@types/lodash.sum@^4.0.6": version "4.0.6" resolved "https://registry.yarnpkg.com/@types/lodash.sum/-/lodash.sum-4.0.6.tgz#acae9c8b24390a974667565acf17288e98dcdb8e" @@ -5591,6 +5598,13 @@ ajv-errors@^1.0.0: resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== +ajv-formats@^2.0.2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" @@ -5641,6 +5655,16 @@ ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.0.0, ajv@^8.1.0: + version "8.6.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571" + integrity sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -6367,6 +6391,11 @@ atomic-sleep@^1.0.0: resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== +atomically@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/atomically/-/atomically-1.7.0.tgz#c07a0458432ea6dbc9a3506fffa424b48bccaafe" + integrity sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w== + author-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450" @@ -9013,6 +9042,22 @@ concat-stream@^2.0.0: readable-stream "^3.0.2" typedarray "^0.0.6" +conf@^10.0.2: + version "10.0.2" + resolved "https://registry.yarnpkg.com/conf/-/conf-10.0.2.tgz#2e0e89fb85ec2c6fba1efce652d7561ed0b70084" + integrity sha512-iyy4ArqyQ/yrzNASNBN+jaylu53JRuq0ztvL6KAWYHj4iN56BVuhy2SrzEEHBodNbacZr2Pd/4nWhoAwc66T1g== + dependencies: + ajv "^8.1.0" + ajv-formats "^2.0.2" + atomically "^1.7.0" + debounce-fn "^4.0.0" + dot-prop "^6.0.1" + env-paths "^2.2.1" + json-schema-typed "^7.0.3" + onetime "^5.1.2" + pkg-up "^3.1.0" + semver "^7.3.5" + config-chain@^1.1.11: version "1.1.12" resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" @@ -9021,18 +9066,6 @@ config-chain@^1.1.11: ini "^1.3.4" proto-list "~1.2.1" -configstore@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-4.0.0.tgz#5933311e95d3687efb592c528b922d9262d227e7" - integrity sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ== - dependencies: - dot-prop "^4.1.0" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - unique-string "^1.0.0" - write-file-atomic "^2.0.0" - xdg-basedir "^3.0.0" - configstore@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" @@ -9457,11 +9490,6 @@ crypto-js@^3.1.9-1: resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.1.9-1.tgz#fda19e761fc077e01ffbfdc6e9fdfc59e8806cd8" integrity sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg= -crypto-random-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" - integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= - crypto-random-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" @@ -9652,6 +9680,13 @@ de-indent@^1.0.2: resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0= +debounce-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/debounce-fn/-/debounce-fn-4.0.0.tgz#ed76d206d8a50e60de0dd66d494d82835ffe61c7" + integrity sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ== + dependencies: + mimic-fn "^3.0.0" + debounce@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131" @@ -10411,7 +10446,7 @@ dot-prop@^3.0.0: dependencies: is-obj "^1.0.0" -dot-prop@^4.1.0, dot-prop@^4.2.0: +dot-prop@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== @@ -10425,6 +10460,13 @@ dot-prop@^5.2.0: dependencies: is-obj "^2.0.0" +dot-prop@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083" + integrity sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA== + dependencies: + is-obj "^2.0.0" + double-ended-queue@2.1.0-0: version "2.1.0-0" resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" @@ -10795,6 +10837,11 @@ env-paths@^2.2.0: resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== +env-paths@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + envinfo@^7.7.3: version "7.7.4" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.7.4.tgz#c6311cdd38a0e86808c1c9343f667e4267c4a320" @@ -14463,10 +14510,10 @@ highlight.js@^10.4.1: resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.4.1.tgz#d48fbcf4a9971c4361b3f95f302747afe19dbad0" integrity sha512-yR5lWvNz7c85OhVAEAeFhVCc/GV4C30Fjzc/rCP0aCWzc1UUOPUk55dK/qdwTZHBvMZo+eZ2jpk62ndX/xMFlg== -highlightjs-solidity@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/highlightjs-solidity/-/highlightjs-solidity-1.2.2.tgz#049a050c0d8009c99b373537a4e66bf55366de51" - integrity sha512-+cZ+1+nAO5Pi6c70TKuMcPmwqLECxiYhnQc1MxdXckK94zyWFMNZADzu98ECNlf5xCRdNh+XKp+eklmRU+Dniw== +highlightjs-solidity@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/highlightjs-solidity/-/highlightjs-solidity-2.0.1.tgz#ee1beb6f353d4503aa3a011bbb86577976365b59" + integrity sha512-9YY+HQpXMTrF8HgRByjeQhd21GXAz2ktMPTcs6oWSj5HJR52fgsNoelMOmgigwcpt9j4tu4IVSaWaJB2n2TbvQ== hkts@^0.3.1: version "0.3.1" @@ -17987,6 +18034,16 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-schema-typed@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/json-schema-typed/-/json-schema-typed-7.0.3.tgz#23ff481b8b4eebcd2ca123b4fa0409e66469a2d9" + integrity sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A== + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -19560,7 +19617,7 @@ lodash.partition@^4.6.0: resolved "https://registry.yarnpkg.com/lodash.partition/-/lodash.partition-4.6.0.tgz#a38e46b73469e0420b0da1212e66d414be364ba4" integrity sha1-o45GtzRp4EILDaEhLmbUFL42S6Q= -lodash.pick@^4.2.1: +lodash.pick@^4.2.1, lodash.pick@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= @@ -20481,6 +20538,11 @@ mimic-fn@^2.0.0, mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-fn@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-3.1.0.tgz#65755145bbf3e36954b949c16450427451d5ca74" + integrity sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ== + mimic-response@^1.0.0, mimic-response@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" @@ -22922,6 +22984,13 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pkg-up@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== + dependencies: + find-up "^3.0.0" + please-upgrade-node@^3.1.1, please-upgrade-node@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" @@ -25236,6 +25305,13 @@ semver@^7.3.4: dependencies: lru-cache "^6.0.0" +semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + semver@~5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" @@ -27972,13 +28048,6 @@ unique-stream@^2.0.2: json-stable-stringify-without-jsonify "^1.0.1" through2-filter "^3.0.0" -unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" - integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= - dependencies: - crypto-random-string "^1.0.0" - unique-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" @@ -28551,10 +28620,10 @@ web3-bzz@1.3.0: swarm-js "^0.1.40" underscore "1.9.1" -web3-bzz@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.5.2.tgz#a04feaa19462cff6d5a8c87dad1aca4619d9dfc8" - integrity sha512-W/sPCdA+XQ9duUYKHAwf/g69cbbV8gTCRsa1MpZwU7spXECiyJ2EvD/QzAZ+UpJk3GELXFF/fUByeZ3VRQKF2g== +web3-bzz@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.5.3.tgz#e36456905ce051138f9c3ce3623cbc73da088c2b" + integrity sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg== dependencies: "@types/node" "^12.12.6" got "9.6.0" @@ -28587,13 +28656,13 @@ web3-core-helpers@1.3.0: web3-eth-iban "1.3.0" web3-utils "1.3.0" -web3-core-helpers@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.5.2.tgz#b6bd5071ca099ba3f92dfafb552eed2b70af2795" - integrity sha512-U7LJoeUdQ3aY9t5gU7t/1XpcApsWm+4AcW5qKl/44ZxD44w0Dmsq1c5zJm3GuLr/a9MwQfXK4lpmvxVQWHHQRg== +web3-core-helpers@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz#099030235c477aadf39a94199ef40092151d563c" + integrity sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw== dependencies: - web3-eth-iban "1.5.2" - web3-utils "1.5.2" + web3-eth-iban "1.5.3" + web3-utils "1.5.3" web3-core-method@1.2.1: version "1.2.1" @@ -28630,17 +28699,17 @@ web3-core-method@1.3.0: web3-core-subscriptions "1.3.0" web3-utils "1.3.0" -web3-core-method@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.5.2.tgz#d1d602657be1000a29d11e3ca3bf7bc778dea9a5" - integrity sha512-/mC5t9UjjJoQmJJqO5nWK41YHo+tMzFaT7Tp7jDCQsBkinE68KsUJkt0jzygpheW84Zra0DVp6q19gf96+cugg== +web3-core-method@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.5.3.tgz#6cff97ed19fe4ea2e9183d6f703823a079f5132c" + integrity sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg== dependencies: "@ethereumjs/common" "^2.4.0" "@ethersproject/transactions" "^5.0.0-beta.135" - web3-core-helpers "1.5.2" - web3-core-promievent "1.5.2" - web3-core-subscriptions "1.5.2" - web3-utils "1.5.2" + web3-core-helpers "1.5.3" + web3-core-promievent "1.5.3" + web3-core-subscriptions "1.5.3" + web3-utils "1.5.3" web3-core-promievent@1.2.1: version "1.2.1" @@ -28664,10 +28733,10 @@ web3-core-promievent@1.3.0: dependencies: eventemitter3 "4.0.4" -web3-core-promievent@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.5.2.tgz#2dc9fe0e5bbeb7c360fc1aac5f12b32d9949a59b" - integrity sha512-5DacbJXe98ozSor7JlkTNCy6G8945VunRRkPxMk98rUrg60ECVEM/vuefk1atACzjQsKx6tmLZuHxbJQ64TQeQ== +web3-core-promievent@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz#3f11833c3dc6495577c274350b61144e0a4dba01" + integrity sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg== dependencies: eventemitter3 "4.0.4" @@ -28704,16 +28773,16 @@ web3-core-requestmanager@1.3.0: web3-providers-ipc "1.3.0" web3-providers-ws "1.3.0" -web3-core-requestmanager@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.5.2.tgz#43ccc00779394c941b28e6e07e217350fd1ded71" - integrity sha512-oRVW9OrAsXN2JIZt68OEg1Mb1A9a/L3JAGMv15zLEFEnJEGw0KQsGK1ET2kvZBzvpFd5G0EVkYCnx7WDe4HSNw== +web3-core-requestmanager@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz#b339525815fd40e3a2a81813c864ddc413f7b6f7" + integrity sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg== dependencies: util "^0.12.0" - web3-core-helpers "1.5.2" - web3-providers-http "1.5.2" - web3-providers-ipc "1.5.2" - web3-providers-ws "1.5.2" + web3-core-helpers "1.5.3" + web3-providers-http "1.5.3" + web3-providers-ipc "1.5.3" + web3-providers-ws "1.5.3" web3-core-subscriptions@1.2.1: version "1.2.1" @@ -28742,13 +28811,13 @@ web3-core-subscriptions@1.3.0: underscore "1.9.1" web3-core-helpers "1.3.0" -web3-core-subscriptions@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.5.2.tgz#8eaebde44f81fc13c45b555c4422fe79393da9cf" - integrity sha512-hapI4rKFk22yurtIv0BYvkraHsM7epA4iI8Np+HuH6P9DD0zj/llaps6TXLM9HyacLBRwmOLZmr+pHBsPopUnQ== +web3-core-subscriptions@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz#d7d69c4caad65074212028656e9dc56ca5c2159d" + integrity sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA== dependencies: eventemitter3 "4.0.4" - web3-core-helpers "1.5.2" + web3-core-helpers "1.5.3" web3-core@1.2.1: version "1.2.1" @@ -28786,18 +28855,18 @@ web3-core@1.3.0: web3-core-requestmanager "1.3.0" web3-utils "1.3.0" -web3-core@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.5.2.tgz#ca2b9b1ed3cf84d48b31c9bb91f7628f97cfdcd5" - integrity sha512-sebMpQbg3kbh3vHUbHrlKGKOxDWqjgt8KatmTBsTAWj/HwWYVDzeX+2Q84+swNYsm2DrTBVFlqTErFUwPBvyaA== +web3-core@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.5.3.tgz#59f8728b27c8305b349051326aa262b9b7e907bf" + integrity sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ== dependencies: "@types/bn.js" "^4.11.5" "@types/node" "^12.12.6" bignumber.js "^9.0.0" - web3-core-helpers "1.5.2" - web3-core-method "1.5.2" - web3-core-requestmanager "1.5.2" - web3-utils "1.5.2" + web3-core-helpers "1.5.3" + web3-core-method "1.5.3" + web3-core-requestmanager "1.5.3" + web3-utils "1.5.3" web3-eth-abi@1.2.1: version "1.2.1" @@ -28826,13 +28895,13 @@ web3-eth-abi@1.3.0: underscore "1.9.1" web3-utils "1.3.0" -web3-eth-abi@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.5.2.tgz#b627eada967f39ae4657ddd61b693cb00d55cb29" - integrity sha512-P3bJbDR5wib4kWGfVeBKBVi27T+AiHy4EJxYM6SMNbpm3DboLDdisu9YBd6INMs8rzxgnprBbGmmyn4jKIDKAA== +web3-eth-abi@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz#5aea9394d797f99ca0d9bd40c3417eb07241c96c" + integrity sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg== dependencies: "@ethersproject/abi" "5.0.7" - web3-utils "1.5.2" + web3-utils "1.5.3" web3-eth-accounts@1.2.1: version "1.2.1" @@ -28885,10 +28954,10 @@ web3-eth-accounts@1.3.0: web3-core-method "1.3.0" web3-utils "1.3.0" -web3-eth-accounts@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.5.2.tgz#cf506c21037fa497fe42f1f055980ce4acf83731" - integrity sha512-F8mtzxgEhxfLc66vPi0Gqd6mpscvvk7Ua575bsJ1p9J2X/VtuKgDgpWcU4e4LKeROQ+ouCpAG9//0j9jQuij3A== +web3-eth-accounts@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz#076c816ff4d68c9dffebdc7fd2bfaddcfc163d77" + integrity sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw== dependencies: "@ethereumjs/common" "^2.3.0" "@ethereumjs/tx" "^3.2.1" @@ -28897,10 +28966,10 @@ web3-eth-accounts@1.5.2: ethereumjs-util "^7.0.10" scrypt-js "^3.0.1" uuid "3.3.2" - web3-core "1.5.2" - web3-core-helpers "1.5.2" - web3-core-method "1.5.2" - web3-utils "1.5.2" + web3-core "1.5.3" + web3-core-helpers "1.5.3" + web3-core-method "1.5.3" + web3-utils "1.5.3" web3-eth-contract@1.2.1: version "1.2.1" @@ -28946,19 +29015,19 @@ web3-eth-contract@1.3.0: web3-eth-abi "1.3.0" web3-utils "1.3.0" -web3-eth-contract@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.5.2.tgz#ffbd799fd01e36596aaadefba323e24a98a23c2f" - integrity sha512-4B8X/IPFxZCTmtENpdWXtyw5fskf2muyc3Jm5brBQRb4H3lVh1/ZyQy7vOIkdphyaXu4m8hBLHzeyKkd37mOUg== +web3-eth-contract@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz#12b03a4a16ce583a945f874bea2ff2fb4c5b81ad" + integrity sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg== dependencies: "@types/bn.js" "^4.11.5" - web3-core "1.5.2" - web3-core-helpers "1.5.2" - web3-core-method "1.5.2" - web3-core-promievent "1.5.2" - web3-core-subscriptions "1.5.2" - web3-eth-abi "1.5.2" - web3-utils "1.5.2" + web3-core "1.5.3" + web3-core-helpers "1.5.3" + web3-core-method "1.5.3" + web3-core-promievent "1.5.3" + web3-core-subscriptions "1.5.3" + web3-eth-abi "1.5.3" + web3-utils "1.5.3" web3-eth-ens@1.2.1: version "1.2.1" @@ -29004,19 +29073,19 @@ web3-eth-ens@1.3.0: web3-eth-contract "1.3.0" web3-utils "1.3.0" -web3-eth-ens@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.5.2.tgz#ecb3708f0e8e2e847e9d89e8428da12c30bba6a4" - integrity sha512-/UrLL42ZOCYge+BpFBdzG8ICugaRS4f6X7PxJKO+zAt+TwNgBpjuWfW/ZYNcuqJun/ZyfcTuj03TXqA1RlNhZQ== +web3-eth-ens@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz#ef6eee1ddf32b1ff9536fc7c599a74f2656bafe1" + integrity sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw== dependencies: content-hash "^2.5.2" eth-ens-namehash "2.0.8" - web3-core "1.5.2" - web3-core-helpers "1.5.2" - web3-core-promievent "1.5.2" - web3-eth-abi "1.5.2" - web3-eth-contract "1.5.2" - web3-utils "1.5.2" + web3-core "1.5.3" + web3-core-helpers "1.5.3" + web3-core-promievent "1.5.3" + web3-eth-abi "1.5.3" + web3-eth-contract "1.5.3" + web3-utils "1.5.3" web3-eth-iban@1.2.1: version "1.2.1" @@ -29042,13 +29111,13 @@ web3-eth-iban@1.3.0: bn.js "^4.11.9" web3-utils "1.3.0" -web3-eth-iban@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.5.2.tgz#f390ad244ef8a6c94de7c58736b0b80a484abc8e" - integrity sha512-C04YDXuSG/aDwOHSX+HySBGb0KraiAVt+/l1Mw7y/fCUrKC/K0yYzMYqY/uYOcvLtepBPsC4ZfUYWUBZ2PO8Vg== +web3-eth-iban@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz#91b1475893a877b10eac1de5cce6eb379fb81b5d" + integrity sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw== dependencies: bn.js "^4.11.9" - web3-utils "1.5.2" + web3-utils "1.5.3" web3-eth-personal@1.2.1: version "1.2.1" @@ -29085,17 +29154,17 @@ web3-eth-personal@1.3.0: web3-net "1.3.0" web3-utils "1.3.0" -web3-eth-personal@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.5.2.tgz#043335a19ab59e119ba61e3bd6c3b8cde8120490" - integrity sha512-nH5N2GiVC0C5XeMEKU16PeFP3Hb3hkPvlR6Tf9WQ+pE+jw1c8eaXBO1CJQLr15ikhUF3s94ICyHcfjzkDsmRbA== +web3-eth-personal@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz#4ebe09e9a77dd49d23d93b36b36cfbf4a6dae713" + integrity sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew== dependencies: "@types/node" "^12.12.6" - web3-core "1.5.2" - web3-core-helpers "1.5.2" - web3-core-method "1.5.2" - web3-net "1.5.2" - web3-utils "1.5.2" + web3-core "1.5.3" + web3-core-helpers "1.5.3" + web3-core-method "1.5.3" + web3-net "1.5.3" + web3-utils "1.5.3" web3-eth@1.2.1: version "1.2.1" @@ -29154,23 +29223,23 @@ web3-eth@1.3.0: web3-net "1.3.0" web3-utils "1.3.0" -web3-eth@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.5.2.tgz#0f6470df60a2a7d04df4423ca7721db8ed5ad72b" - integrity sha512-DwWQ6TCOUqvYyo7T20S7HpQDPveNHNqOn2Q2F3E8ZFyEjmqT4XsGiwvm08kB/VgQ4e/ANyq/i8PPFSYMT8JKHg== - dependencies: - web3-core "1.5.2" - web3-core-helpers "1.5.2" - web3-core-method "1.5.2" - web3-core-subscriptions "1.5.2" - web3-eth-abi "1.5.2" - web3-eth-accounts "1.5.2" - web3-eth-contract "1.5.2" - web3-eth-ens "1.5.2" - web3-eth-iban "1.5.2" - web3-eth-personal "1.5.2" - web3-net "1.5.2" - web3-utils "1.5.2" +web3-eth@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.5.3.tgz#d7d1ac7198f816ab8a2088c01e0bf1eda45862fe" + integrity sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q== + dependencies: + web3-core "1.5.3" + web3-core-helpers "1.5.3" + web3-core-method "1.5.3" + web3-core-subscriptions "1.5.3" + web3-eth-abi "1.5.3" + web3-eth-accounts "1.5.3" + web3-eth-contract "1.5.3" + web3-eth-ens "1.5.3" + web3-eth-iban "1.5.3" + web3-eth-personal "1.5.3" + web3-net "1.5.3" + web3-utils "1.5.3" web3-net@1.2.1: version "1.2.1" @@ -29199,14 +29268,14 @@ web3-net@1.3.0: web3-core-method "1.3.0" web3-utils "1.3.0" -web3-net@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.5.2.tgz#58915d7e2dad025d2a08f02c865f3abe61c48eff" - integrity sha512-VEc9c+jfoERhbJIxnx0VPlQDot8Lm4JW/tOWFU+ekHgIiu2zFKj5YxhURIth7RAbsaRsqCb79aE+M0eI8maxVQ== +web3-net@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.5.3.tgz#545fee49b8e213b0c55cbe74ffd0295766057463" + integrity sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ== dependencies: - web3-core "1.5.2" - web3-core-method "1.5.2" - web3-utils "1.5.2" + web3-core "1.5.3" + web3-core-method "1.5.3" + web3-utils "1.5.3" web3-provider-engine@14.2.1: version "14.2.1" @@ -29258,12 +29327,12 @@ web3-providers-http@1.3.0: web3-core-helpers "1.3.0" xhr2-cookies "1.1.0" -web3-providers-http@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.5.2.tgz#94f95fe5572ca54aa2c2ffd42c63956436c9eb0a" - integrity sha512-dUNFJc9IMYDLZnkoQX3H4ZjvHjGO6VRVCqrBrdh84wPX/0da9dOA7DwIWnG0Gv3n9ybWwu5JHQxK4MNQ444lyA== +web3-providers-http@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.5.3.tgz#74f170fc3d79eb7941d9fbc34e2a067d61ced0b2" + integrity sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw== dependencies: - web3-core-helpers "1.5.2" + web3-core-helpers "1.5.3" xhr2-cookies "1.1.0" web3-providers-ipc@1.2.1: @@ -29293,13 +29362,13 @@ web3-providers-ipc@1.3.0: underscore "1.9.1" web3-core-helpers "1.3.0" -web3-providers-ipc@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.5.2.tgz#68a516883c998eeddf60df4cead77baca4fb4aaa" - integrity sha512-SJC4Sivt4g9LHKlRy7cs1jkJgp7bjrQeUndE6BKs0zNALKguxu6QYnzbmuHCTFW85GfMDjhvi24jyyZHMnBNXQ== +web3-providers-ipc@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz#4bd7f5e445c2f3c2595fce0929c72bb879320a3f" + integrity sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg== dependencies: oboe "2.1.5" - web3-core-helpers "1.5.2" + web3-core-helpers "1.5.3" web3-providers-ws@1.2.1: version "1.2.1" @@ -29330,13 +29399,13 @@ web3-providers-ws@1.3.0: web3-core-helpers "1.3.0" websocket "^1.0.32" -web3-providers-ws@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.5.2.tgz#d336a93ed608b40cdcadfadd1f1bc8d32ea046e0" - integrity sha512-xy9RGlyO8MbJDuKv2vAMDkg+en+OvXG0CGTCM2BTl6l1vIdHpCa+6A/9KV2rK8aU9OBZ7/Pf+Y19517kHVl9RA== +web3-providers-ws@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz#eec6cfb32bb928a4106de506f13a49070a21eabf" + integrity sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg== dependencies: eventemitter3 "4.0.4" - web3-core-helpers "1.5.2" + web3-core-helpers "1.5.3" websocket "^1.0.32" web3-shh@1.2.1: @@ -29369,15 +29438,15 @@ web3-shh@1.3.0: web3-core-subscriptions "1.3.0" web3-net "1.3.0" -web3-shh@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.5.2.tgz#a72a3d903c0708a004db94a72d934a302d880aea" - integrity sha512-wOxOcYt4Sa0AHAI8gG7RulCwVuVjSRS/M/AbFsea3XfJdN6sU13/syY7OdZNjNYuKjYTzxKYrd3dU/K2iqffVw== +web3-shh@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.5.3.tgz#3c04aa4cda9ba0b746d7225262401160f8e38b13" + integrity sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q== dependencies: - web3-core "1.5.2" - web3-core-method "1.5.2" - web3-core-subscriptions "1.5.2" - web3-net "1.5.2" + web3-core "1.5.3" + web3-core-method "1.5.3" + web3-core-subscriptions "1.5.3" + web3-net "1.5.3" web3-utils@1.2.1: version "1.2.1" @@ -29434,10 +29503,10 @@ web3-utils@1.3.0: underscore "1.9.1" utf8 "3.0.0" -web3-utils@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.5.2.tgz#150982dcb1918ffc54eba87528e28f009ebc03aa" - integrity sha512-quTtTeQJHYSxAwIBOCGEcQtqdVcFWX6mCFNoqnp+mRbq+Hxbs8CGgO/6oqfBx4OvxIOfCpgJWYVHswRXnbEu9Q== +web3-utils@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.5.3.tgz#e914c9320cd663b2a09a5cb920ede574043eb437" + integrity sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q== dependencies: bn.js "^4.11.9" eth-lib "0.2.8" @@ -29487,18 +29556,18 @@ web3@1.2.11: web3-shh "1.2.11" web3-utils "1.2.11" -web3@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/web3/-/web3-1.5.2.tgz#736ca2f39048c63964203dd811f519400973e78d" - integrity sha512-aapKLdO8t7Cos6tZLeeQUtCJvTiPMlLcHsHHDLSBZ/VaJEucSTxzun32M8sp3BmF4waDEmhY+iyUM1BKvtAcVQ== +web3@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.5.3.tgz#11882679453c645bf33620fbc255a243343075aa" + integrity sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w== dependencies: - web3-bzz "1.5.2" - web3-core "1.5.2" - web3-eth "1.5.2" - web3-eth-personal "1.5.2" - web3-net "1.5.2" - web3-shh "1.5.2" - web3-utils "1.5.2" + web3-bzz "1.5.3" + web3-core "1.5.3" + web3-eth "1.5.3" + web3-eth-personal "1.5.3" + web3-net "1.5.3" + web3-shh "1.5.3" + web3-utils "1.5.3" web3@^1.2.1: version "1.3.0" @@ -30118,11 +30187,6 @@ ws@^7.2.3: resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA== -xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" - integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= - xdg-basedir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"