Trap CALL_EXCEPTION errors when resolving ENS entries (#1690).
This commit is contained in:
parent
8277f5a62a
commit
91951dc825
@ -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") ])
|
||||
};
|
||||
|
||||
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<Resolver> {
|
||||
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<string> {
|
||||
@ -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<string>): Promise<string> {
|
||||
|
@ -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"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user