Trap CALL_EXCEPTION errors when resolving ENS entries (#1690).

This commit is contained in:
Richard Moore 2021-06-21 23:25:37 -04:00
parent 8277f5a62a
commit 91951dc825
No known key found for this signature in database
GPG Key ID: 665176BE8E9DC651
3 changed files with 54 additions and 21 deletions

View File

@ -250,19 +250,23 @@ export class Resolver implements EnsResolver {
}
async _fetchBytes(selector: string, parameters?: string): Promise<string> {
// keccak256("addr(bytes32,uint256)")
const transaction = {
to: this.address,
data: hexConcat([ selector, namehash(this.name), (parameters || "0x") ])
};
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);
} catch (error) {
if (error.code === Logger.errors.CALL_EXCEPTION) { return null; }
return null;
}
}
_getAddress(coinType: number, hexBytes: string): string {
@ -332,6 +336,7 @@ export class Resolver implements EnsResolver {
// If Ethereum, use the standard `addr(bytes32)`
if (coinType === 60) {
try {
// keccak256("addr(bytes32)")
const transaction = {
to: this.address,
@ -343,6 +348,10 @@ export class Resolver implements EnsResolver {
if (hexBytes === "0x" || hexBytes === HashZero) { return null; }
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<Resolver> {
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<string> {
@ -1523,7 +1537,12 @@ export class BaseProvider extends Provider implements EnsProvider {
data: ("0x0178b8bf" + namehash(name).substring(2))
};
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<string>): Promise<string> {

View File

@ -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"
});
}
}

View File

@ -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;