UNPKG

@g4g/eth-gas-reporter

Version:

Mocha reporter which shows gas used per unit test.

72 lines (63 loc) 2.85 kB
const ethers = require("ethers"); /** * Example of a method that resolves the contract names of method calls routed through * an EtherRouter style contract. This function gets bound to the `this` property of * eth-gas-reporter's ProxyResolver class and inherits its resources including * helpers to match methods to contracts and a way of making synchronous calls to the client. * * Helper methods of this type receive a web3 transaction object representing a tx the reporter * could not deterministically associate with any contract. They rely on your knowledge * of a proxy contract's API to derive the correct contract name. * * Returns contract name matching the resolved address. * @param {Object} transaction result of web3.eth.getTransaction * @return {String} contract name */ function etherRouter(transaction) { let contractAddress; let contractName; try { const ABI = ["function resolver()", "function lookup(bytes4 sig)"]; const iface = new ethers.utils.Interface(ABI); // The tx passed to this method had input data which didn't map to any methods on // the contract it was sent to. It's possible the tx's `to` address points to // an EtherRouter contract which is designed to forward calls. We'll grab the // method signature and ask the router if it knows who the intended recipient is. const signature = transaction.input.slice(0, 10); // EtherRouter has a public state variable called `resolver()` which stores the // address of a contract which maps method signatures to their parent contracts. // Lets fetch it .... const resolverAddress = this.sync.call( { to: transaction.to, data: iface.functions.resolver.encode([]) }, transaction.blockNumber ); // Now we'll call the Resolver's `lookup(sig)` method to get the address of the contract // our tx was actually getting forwarded to. contractAddress = this.sync.call( { to: ethers.utils.hexStripZeros(resolverAddress), data: iface.functions.lookup.encode([signature]) }, transaction.blockNumber ); // Don't forget this is all a bit speculative... } catch (err) { this.unresolvedCalls++; return; } // With the correct address, we can use the ProxyResolver class's // data.getNameByAddress and/or resolveByDeployedBytecode methods // (both are available in this scope, bound to `this`) to derive // the target contract's name. if (contractAddress) { contractAddress = ethers.utils.hexStripZeros(contractAddress); contractName = this.data.getNameByAddress(contractAddress); // Try to resolve by deployedBytecode if (contractName) return contractName; else return this.resolveByDeployedBytecode(contractAddress); } } module.exports = etherRouter;