|
| 1 | +import { Interface } from '@ethersproject/abi'; |
| 2 | +import { multicall1, multicall2, multicall3 } from './abis'; |
| 3 | +import { Options } from './models'; |
| 4 | +import { networks } from './networks'; |
| 5 | +import { Address, Mapping, Network } from './types'; |
| 6 | + |
| 7 | +// Checks if the provided address is a valid multicall address in our network definitions |
| 8 | +const constructWithAddress = (address: Address): Mapping => { |
| 9 | + let mapping: Mapping = { |
| 10 | + found: false, |
| 11 | + address: networks['1']['multicall3'], |
| 12 | + network: 1, |
| 13 | + interface: new Interface(multicall3), |
| 14 | + abi: multicall3, |
| 15 | + }; |
| 16 | + |
| 17 | + // Iterate over the networks |
| 18 | + for (const network in networks) { |
| 19 | + // If we have a match, return the network |
| 20 | + const networkObject: Mapping = networkToMapping( |
| 21 | + parseInt(network), |
| 22 | + networks[network], |
| 23 | + address |
| 24 | + ); |
| 25 | + if (networkObject.found) { |
| 26 | + mapping = networkObject; |
| 27 | + break; |
| 28 | + } |
| 29 | + } |
| 30 | + |
| 31 | + return mapping; |
| 32 | +}; |
| 33 | + |
| 34 | +// Attempts to construct a mapping from a network object with the provided multicall address |
| 35 | +const networkToMapping = ( |
| 36 | + network: Network, |
| 37 | + networkObject: object, |
| 38 | + address: Address |
| 39 | +): Mapping => { |
| 40 | + let mapping: Mapping = { |
| 41 | + found: false, |
| 42 | + address: networks['1']['multicall3'], |
| 43 | + network: 1, |
| 44 | + interface: new Interface(multicall3), |
| 45 | + abi: multicall3, |
| 46 | + }; |
| 47 | + |
| 48 | + if (networkObject['multicall3'].toLowerCase() == address.toLowerCase()) { |
| 49 | + mapping = { |
| 50 | + found: true, |
| 51 | + address: networkObject['multicall3'], |
| 52 | + network, |
| 53 | + interface: new Interface(multicall3), |
| 54 | + abi: multicall3, |
| 55 | + }; |
| 56 | + } else if ( |
| 57 | + networkObject['multicall2'].toLowerCase() == address.toLowerCase() |
| 58 | + ) { |
| 59 | + mapping = { |
| 60 | + found: true, |
| 61 | + address: networkObject['multicall2'], |
| 62 | + network, |
| 63 | + interface: new Interface(multicall2), |
| 64 | + abi: multicall2, |
| 65 | + }; |
| 66 | + } else if ( |
| 67 | + networkObject['multicall'].toLowerCase() == address.toLowerCase() |
| 68 | + ) { |
| 69 | + mapping = { |
| 70 | + found: true, |
| 71 | + address: networks[network.toString()]['multicall'], |
| 72 | + network, |
| 73 | + interface: new Interface(multicall1), |
| 74 | + abi: multicall1, |
| 75 | + }; |
| 76 | + } |
| 77 | + |
| 78 | + return mapping; |
| 79 | +}; |
| 80 | + |
| 81 | +// Maps Multicall address string to an Interface generated from our stored ABIs |
| 82 | +// Network defaults to 1 (mainnet) if multicall address isn't found |
| 83 | +// If an inconsistency is found between the network and multicall address string, |
| 84 | +// the multicall address is first checked, then we will default to the multicall |
| 85 | +// instance of the provided network |
| 86 | +const abiMap = (options?: Options): Mapping => { |
| 87 | + // Craft the default mapping |
| 88 | + let mapping: Mapping = { |
| 89 | + found: false, |
| 90 | + address: networks['1']['multicall3'], |
| 91 | + network: 1, |
| 92 | + interface: new Interface(multicall3), |
| 93 | + abi: multicall3, |
| 94 | + }; |
| 95 | + |
| 96 | + // If we have options |
| 97 | + if (options) { |
| 98 | + // Deconstruct our option parameters |
| 99 | + const { address, network } = options; |
| 100 | + |
| 101 | + if (network) { |
| 102 | + const networkObject: object = networks[network.toString()]; |
| 103 | + |
| 104 | + // If we have a network, let's check if we have a multicall address |
| 105 | + if (networkObject) { |
| 106 | + // Try to get multicall with address |
| 107 | + const foundMulticall = networkToMapping( |
| 108 | + network, |
| 109 | + networkObject, |
| 110 | + address || '0x0' // if no address, 0x0 shouldn't work |
| 111 | + ); |
| 112 | + if (foundMulticall.found) { |
| 113 | + mapping = foundMulticall; |
| 114 | + } else { |
| 115 | + // The network didn't contain the expected multicall address |
| 116 | + // Check if networks contains the address |
| 117 | + const validatedNetwork: Mapping = constructWithAddress( |
| 118 | + address || '0x0' |
| 119 | + ); |
| 120 | + |
| 121 | + // If the address isn't found, we can use the network |
| 122 | + if (!validatedNetwork.found) { |
| 123 | + // Grab the most up to date multicall address |
| 124 | + if (networkObject['multicall3']) { |
| 125 | + mapping = { |
| 126 | + found: true, |
| 127 | + address: networkObject['multicall3'], |
| 128 | + network, |
| 129 | + interface: new Interface(multicall3), |
| 130 | + abi: multicall3, |
| 131 | + }; |
| 132 | + } else if (networkObject['multicall2']) { |
| 133 | + mapping = { |
| 134 | + found: true, |
| 135 | + address: networkObject['multicall2'], |
| 136 | + network, |
| 137 | + interface: new Interface(multicall2), |
| 138 | + abi: multicall2, |
| 139 | + }; |
| 140 | + } else if (networkObject['multicall1']) { |
| 141 | + mapping = { |
| 142 | + found: true, |
| 143 | + address: networkObject['multicall1'], |
| 144 | + network, |
| 145 | + interface: new Interface(multicall1), |
| 146 | + abi: multicall1, |
| 147 | + }; |
| 148 | + } else { |
| 149 | + // We have to use the default since none of the network multicalls are defined |
| 150 | + // This should really never happen |
| 151 | + } |
| 152 | + } else { |
| 153 | + // Otherwise, use the address |
| 154 | + mapping = validatedNetwork; |
| 155 | + } |
| 156 | + } |
| 157 | + } else { |
| 158 | + // No network, try to find multicall address and use it |
| 159 | + mapping = constructWithAddress(address || '0x0'); |
| 160 | + } |
| 161 | + } else { |
| 162 | + // No network, try to find multicall address and use it |
| 163 | + mapping = constructWithAddress(address || '0x0'); |
| 164 | + } |
| 165 | + } |
| 166 | + |
| 167 | + // Return the constructed mapping |
| 168 | + return mapping; |
| 169 | +}; |
| 170 | + |
| 171 | +export default abiMap; |
| 172 | +export { Mapping, abiMap, constructWithAddress, networkToMapping }; |
0 commit comments