UNPKG

@0xfutbol/id

Version:

React component library with shared providers for 0xFutbol ID

229 lines (228 loc) 9.51 kB
'use strict';var index=require('./index-gEYw6hWC.js');require('react'),require('react/jsx-runtime'),require('@0xfutbol/id-sign'),require('react-use'),require('@0xfutbol/constants'),require('thirdweb'),require('@matchain/matchid-sdk-react'),require('@tanstack/react-query'),require('@matchain/matchid-sdk-react/index.css'),require('react-dom');/** * Retrieves the value stored at a specific position in the storage of a contract. * @param request - The EIP1193 request function. * @param params - The parameters for the eth_getStorageAt method. * @returns A promise that resolves to the value stored at the specified position. * @rpc * @example * ```ts * import { getRpcClient, eth_getStorageAt } from "thirdweb/rpc"; * const rpcRequest = getRpcClient({ client, chain }); * const storageValue = await eth_getStorageAt(rpcRequest, { * address: "0x...", * position: 0n, * }); * ``` */ async function eth_getStorageAt(request, params) { return await request({ method: "eth_getStorageAt", params: [ index.d(params.address), params.position, params.blockTag ?? "latest", ], }); }/** * Extracts the implementation address from a given bytecode string if it matches any of the known minimal proxy patterns. * @param bytecode The bytecode string to extract the implementation address from. * @returns The implementation address as a string if a match is found, otherwise undefined. * @example * ```ts * import { extractMinimalProxyImplementationAddress } from "thirdweb/utils"; * const bytecode = "0x363d3d373d3d3d363d73..."; * const implementationAddress = extractMinimalProxyImplementationAddress(bytecode); * ``` * @utils */ function extractMinimalProxyImplementationAddress(bytecode) { if (!bytecode.startsWith("0x")) { // biome-ignore lint/style/noParameterAssign: perf bytecode = `0x${bytecode}`; } // EIP-1167 clone minimal proxy - https://eips.ethereum.org/EIPS/eip-1167 if (bytecode.startsWith("0x363d3d373d3d3d363d73")) { const implementationAddress = bytecode.slice(22, 62); return `0x${implementationAddress}`; } // Minimal Proxy with receive() from 0xSplits - https://github.com/0xSplits/splits-contracts/blob/c7b741926ec9746182d0d1e2c4c2046102e5d337/contracts/libraries/Clones.sol if (bytecode.startsWith("0x36603057343d5230")) { // +40 = size of addr const implementationAddress = bytecode.slice(122, 122 + 40); return `0x${implementationAddress}`; } // 0age's minimal proxy - https://medium.com/coinmonks/the-more-minimal-proxy-5756ae08ee48 if (bytecode.startsWith("0x3d3d3d3d363d3d37363d73")) { // +40 = size of addr const implementationAddress = bytecode.slice(24, 24 + 40); return `0x${implementationAddress}`; } // vyper's minimal proxy (uniswap v1) - https://etherscan.io/address/0x09cabec1ead1c0ba254b09efb3ee13841712be14#code if (bytecode.startsWith("0x366000600037611000600036600073")) { const implementationAddress = bytecode.slice(32, 32 + 40); return `0x${implementationAddress}`; } if (bytecode.startsWith("0x36600080376020600036600073")) { const implementationAddress = bytecode.slice(28, 28 + 40); return `0x${implementationAddress}`; } // EIP-7511 minimal proxy with PUSH0 opcode - https://eips.ethereum.org/EIPS/eip-7511 if (bytecode.startsWith("0x365f5f375f5f365f73")) { const implementationAddress = bytecode.slice(20, 60); return `0x${implementationAddress}`; } // EIP-7702 - https://eips.ethereum.org/EIPS/eip-7702#abstract if (bytecode.length === 48 && bytecode.startsWith("0xef0100")) { const implementationAddress = bytecode.slice(8, 48); return `0x${implementationAddress}`; } return undefined; }// TODO: move to const exports const AddressZero = "0x0000000000000000000000000000000000000000"; const ZERO_BYTES32 = "0x0000000000000000000000000000000000000000000000000000000000000000"; /** * Resolves the implementation address and bytecode for a given proxy contract. * @param contract The contract to resolve the implementation for. * @returns A promise that resolves to an object containing the implementation address and bytecode. * @example * ```ts * import { resolveImplementation } from "thirdweb"; * const implementation = await resolveImplementation(contract); * ``` * @contract */ async function resolveImplementation( // biome-ignore lint/suspicious/noExplicitAny: TODO: fix any contract) { const [originalBytecode, beacon] = await Promise.all([ index.cM(contract), getBeaconFromStorageSlot(contract), ]); // check minimal proxy first synchronously const minimalProxyImplementationAddress = extractMinimalProxyImplementationAddress(originalBytecode); if (minimalProxyImplementationAddress) { return { address: minimalProxyImplementationAddress, bytecode: await index.cM(index.at({ ...contract, address: minimalProxyImplementationAddress, })), }; } // check other proxy types let implementationAddress; if (beacon && beacon !== AddressZero) { // In case of a BeaconProxy, it is setup as BeaconProxy --> Beacon --> Implementation // Hence we replace the proxy address with Beacon address, and continue further resolving below // biome-ignore lint/style/noParameterAssign: we purposefully mutate the contract object here contract = index.at({ ...contract, address: beacon, }); implementationAddress = await getImplementationFromContractCall(contract); } else { implementationAddress = await getImplementationFromStorageSlot(contract); } if (implementationAddress && index.cN(implementationAddress) && implementationAddress !== AddressZero) { const implementationBytecode = await index.cM({ ...contract, address: implementationAddress, }); // return the original contract bytecode if the implementation bytecode is empty if (implementationBytecode === "0x") { return { address: contract.address, bytecode: originalBytecode, }; } return { address: implementationAddress, bytecode: implementationBytecode, }; } return { address: contract.address, bytecode: originalBytecode }; } async function getBeaconFromStorageSlot( // biome-ignore lint/suspicious/noExplicitAny: TODO: fix any contract) { /** * The storage slot of the Beacon as defined in EIP-1967 * See https://eips.ethereum.org/EIPS/eip-1967#beacon-contract-address * * bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) */ const rpcRequest = index.f({ client: contract.client, chain: contract.chain, }); try { const proxyStorage = await eth_getStorageAt(rpcRequest, { address: contract.address, position: "0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50", }); return `0x${proxyStorage.slice(-40)}`; } catch { return undefined; } } async function getImplementationFromStorageSlot( // biome-ignore lint/suspicious/noExplicitAny: TODO: fix any contract) { const rpcRequest = index.f({ client: contract.client, chain: contract.chain, }); try { const proxyStoragePromises = [ eth_getStorageAt(rpcRequest, { address: contract.address, position: "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc", }), eth_getStorageAt(rpcRequest, { address: contract.address, position: // keccak256("matic.network.proxy.implementation") - used in polygon USDT proxy: https://polygonscan.com/address/0xc2132d05d31c914a87c6611c10748aeb04b58e8f#code "0xbaab7dbf64751104133af04abc7d9979f0fda3b059a322a8333f533d3f32bf7f", }), eth_getStorageAt(rpcRequest, { address: contract.address, position: // keccak256("org.zeppelinos.proxy.implementation") - e.g. base USDC proxy: https://basescan.org/address/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913#code "0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3", }), ]; const proxyStorages = await Promise.all(proxyStoragePromises); const proxyStorage = proxyStorages.find((storage) => storage !== ZERO_BYTES32); return proxyStorage ? `0x${proxyStorage.slice(-40)}` : AddressZero; } catch { return undefined; } } const UPGRADEABLE_PROXY_ABI = { type: "function", name: "implementation", inputs: [], outputs: [ { type: "address", name: "", internalType: "address", }, ], stateMutability: "view", }; async function getImplementationFromContractCall( // biome-ignore lint/suspicious/noExplicitAny: TODO: fix any contract) { try { return await index.P({ contract, method: UPGRADEABLE_PROXY_ABI }); } catch { return undefined; } }exports.resolveImplementation=resolveImplementation;//# sourceMappingURL=resolveImplementation-3PTFaS7f.js.map