diff --git a/packages/providers/src.ts/base-provider.ts b/packages/providers/src.ts/base-provider.ts index 740cd659e8..9928b6add9 100644 --- a/packages/providers/src.ts/base-provider.ts +++ b/packages/providers/src.ts/base-provider.ts @@ -250,19 +250,23 @@ export class Resolver implements EnsResolver { } async _fetchBytes(selector: string, parameters?: string): Promise { - // keccak256("addr(bytes32,uint256)") const transaction = { to: this.address, data: hexConcat([ selector, namehash(this.name), (parameters || "0x") ]) }; - const result = await this.provider.call(transaction); - if (result === "0x") { return null; } + try { + const result = await this.provider.call(transaction); + if (result === "0x") { return null; } - const offset = BigNumber.from(hexDataSlice(result, 0, 32)).toNumber(); - const length = BigNumber.from(hexDataSlice(result, offset, offset + 32)).toNumber(); - return hexDataSlice(result, offset + 32, offset + 32 + length); + const offset = BigNumber.from(hexDataSlice(result, 0, 32)).toNumber(); + const length = BigNumber.from(hexDataSlice(result, offset, offset + 32)).toNumber(); + return hexDataSlice(result, offset + 32, offset + 32 + length); + } catch (error) { + if (error.code === Logger.errors.CALL_EXCEPTION) { return null; } + return null; + } } _getAddress(coinType: number, hexBytes: string): string { @@ -332,17 +336,22 @@ export class Resolver implements EnsResolver { // If Ethereum, use the standard `addr(bytes32)` if (coinType === 60) { - // keccak256("addr(bytes32)") - const transaction = { - to: this.address, - data: ("0x3b3b57de" + namehash(this.name).substring(2)) - }; - const hexBytes = await this.provider.call(transaction); + try { + // keccak256("addr(bytes32)") + const transaction = { + to: this.address, + data: ("0x3b3b57de" + namehash(this.name).substring(2)) + }; + const hexBytes = await this.provider.call(transaction); - // No address - if (hexBytes === "0x" || hexBytes === HashZero) { return null; } + // No address + if (hexBytes === "0x" || hexBytes === HashZero) { return null; } - return this.provider.formatter.callAddress(hexBytes); + return this.provider.formatter.callAddress(hexBytes); + } catch (error) { + if (error.code === Logger.errors.CALL_EXCEPTION) { return null; } + throw error; + } } // keccak256("addr(bytes32,uint256") @@ -1499,9 +1508,14 @@ export class BaseProvider extends Provider implements EnsProvider { async getResolver(name: string): Promise { - const address = await this._getResolver(name); - if (address == null) { return null; } - return new Resolver(this, address, name); + try { + const address = await this._getResolver(name); + if (address == null) { return null; } + return new Resolver(this, address, name); + } catch (error) { + if (error.code === Logger.errors.CALL_EXCEPTION) { return null; } + return null; + } } async _getResolver(name: string): Promise { @@ -1523,7 +1537,12 @@ export class BaseProvider extends Provider implements EnsProvider { data: ("0x0178b8bf" + namehash(name).substring(2)) }; - return this.formatter.callAddress(await this.call(transaction)); + try { + return this.formatter.callAddress(await this.call(transaction)); + } catch (error) { + if (error.code === Logger.errors.CALL_EXCEPTION) { return null; } + throw error; + } } async resolveName(name: string | Promise): Promise { diff --git a/packages/providers/src.ts/etherscan-provider.ts b/packages/providers/src.ts/etherscan-provider.ts index ec32ba1985..8f96ecb1a9 100644 --- a/packages/providers/src.ts/etherscan-provider.ts +++ b/packages/providers/src.ts/etherscan-provider.ts @@ -98,8 +98,18 @@ function checkError(method: string, error: any, transaction: any): any { // incompatibility; maybe for v6 consider forwarding reverts as errors if (method === "call" && error.code === Logger.errors.SERVER_ERROR) { const e = error.error; - if (e && e.message.match("reverted") && isHexString(e.data)) { - return e.data; + + // Etherscan keeps changing their string + if (e && (e.message.match(/reverted/i) || e.message.match(/VM execution error/i))) { + // Etherscan prefixes the data like "Reverted 0x1234" + let data = e.data; + if (data) { data = "0x" + data.replace(/^.*0x/i, ""); } + + if (isHexString(data)) { return data; } + + logger.throwError("missing revert data in call exception", Logger.errors.CALL_EXCEPTION, { + error, data: "0x" + }); } } diff --git a/packages/providers/src.ts/json-rpc-provider.ts b/packages/providers/src.ts/json-rpc-provider.ts index c5d0b44e35..8633e17a50 100644 --- a/packages/providers/src.ts/json-rpc-provider.ts +++ b/packages/providers/src.ts/json-rpc-provider.ts @@ -30,6 +30,10 @@ function checkError(method: string, error: any, params: any): any { if (e && e.message.match("reverted") && isHexString(e.data)) { return e.data; } + + logger.throwError("missing revert data in call exception", Logger.errors.CALL_EXCEPTION, { + error, data: "0x" + }); } let message = error.message;