dequanto 0.2.37 → 0.2.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/hardhat.config.js +10 -1
- package/lib/cjs/abi/$abiCoder.js +1 -1
- package/lib/cjs/abi/$abiCoder.js.map +1 -1
- package/lib/cjs/abi/Logger.js +1 -1
- package/lib/cjs/abi/abi-coder-packed.js +3 -3
- package/lib/cjs/abi/abi-coder.js +16 -16
- package/lib/cjs/abi/coders/abstract-coder.js +31 -31
- package/lib/cjs/abi/coders/abstract-coder.js.map +1 -1
- package/lib/cjs/abi/fragments.js +90 -90
- package/lib/cjs/abi/fragments.js.map +1 -1
- package/lib/cjs/blocks/BlockDateResolver.js +9 -9
- package/lib/cjs/blocks/BlockDateResolver.js.map +1 -1
- package/lib/cjs/class/PackedRanges.js +46 -46
- package/lib/cjs/class/PackedRanges.js.map +1 -1
- package/lib/cjs/clients/ClientEventsStream.js +1 -1
- package/lib/cjs/clients/ClientEventsStream.js.map +1 -1
- package/lib/cjs/clients/ClientPool.js +23 -23
- package/lib/cjs/clients/ClientPool.js.map +1 -1
- package/lib/cjs/clients/WalletClient.js +3 -3
- package/lib/cjs/clients/WalletClient.js.map +1 -1
- package/lib/cjs/clients/Web3Client.js +14 -14
- package/lib/cjs/clients/Web3Client.js.map +1 -1
- package/lib/cjs/clients/Web3ClientFactory.js +1 -1
- package/lib/cjs/clients/Web3ClientFactory.js.map +1 -1
- package/lib/cjs/clients/compatibility/Web3.js +2 -2
- package/lib/cjs/clients/compatibility/Web3.js.map +1 -1
- package/lib/cjs/clients/handlers/RateLimitGuard.js +16 -16
- package/lib/cjs/clients/handlers/RateLimitGuard.js.map +1 -1
- package/lib/cjs/clients/model/PromiEventWrap.js +1 -1
- package/lib/cjs/clients/model/PromiEventWrap.js.map +1 -1
- package/lib/cjs/clients/utils/$web3Abi.js +2 -2
- package/lib/cjs/clients/utils/$web3Abi.js.map +1 -1
- package/lib/cjs/clients/utils/ClientErrorUtil.js +4 -0
- package/lib/cjs/clients/utils/ClientErrorUtil.js.map +1 -1
- package/lib/cjs/config/Config.js.map +1 -1
- package/lib/cjs/contracts/Contract.js +1 -1
- package/lib/cjs/contracts/Contract.js.map +1 -1
- package/lib/cjs/contracts/ContractAbiProvider.js +6 -6
- package/lib/cjs/contracts/ContractAbiProvider.js.map +1 -1
- package/lib/cjs/contracts/ContractBase.js +10 -10
- package/lib/cjs/contracts/ContractBase.js.map +1 -1
- package/lib/cjs/contracts/ContractProvider.js +1 -1
- package/lib/cjs/contracts/ContractProvider.js.map +1 -1
- package/lib/cjs/contracts/ContractReader.js +5 -5
- package/lib/cjs/contracts/ContractReader.js.map +1 -1
- package/lib/cjs/contracts/ContractWriter.js +4 -4
- package/lib/cjs/contracts/ContractWriter.js.map +1 -1
- package/lib/cjs/contracts/deploy/ContractDeployer.js +4 -4
- package/lib/cjs/contracts/deploy/ContractDeployer.js.map +1 -1
- package/lib/cjs/contracts/deploy/Deployments.js +68 -26
- package/lib/cjs/contracts/deploy/Deployments.js.map +1 -1
- package/lib/cjs/contracts/deploy/proxy/$proxyDeploy.js +13 -13
- package/lib/cjs/contracts/deploy/proxy/$proxyDeploy.js.map +1 -1
- package/lib/cjs/contracts/deploy/proxy/ProxyDeployment.js +58 -25
- package/lib/cjs/contracts/deploy/proxy/ProxyDeployment.js.map +1 -1
- package/lib/cjs/contracts/deploy/storage/DeploymentsStorage.js +15 -14
- package/lib/cjs/contracts/deploy/storage/DeploymentsStorage.js.map +1 -1
- package/lib/cjs/contracts/utils/AbiDeserializer.js +4 -4
- package/lib/cjs/contracts/utils/AbiDeserializer.js.map +1 -1
- package/lib/cjs/contracts/utils/ContractBaseUtils.js +3 -3
- package/lib/cjs/contracts/utils/ContractBaseUtils.js.map +1 -1
- package/lib/cjs/evm/OpcodesWalker.js +1 -1
- package/lib/cjs/evm/OpcodesWalker.js.map +1 -1
- package/lib/cjs/explorer/BlockchainExplorer.js +1 -1
- package/lib/cjs/explorer/BlockchainExplorer.js.map +1 -1
- package/lib/cjs/explorer/BlockchainExplorerFactory.js +1 -1
- package/lib/cjs/explorer/BlockchainExplorerStorage.js +12 -12
- package/lib/cjs/explorer/BlockchainExplorerStorage.js.map +1 -1
- package/lib/cjs/explorer/Evmscan.js +1 -1
- package/lib/cjs/explorer/verifiers/FsHtmlVerifier.js +7 -7
- package/lib/cjs/explorer/verifiers/FsHtmlVerifier.js.map +1 -1
- package/lib/cjs/flashbots/FlashbotWeb3Client.js +1 -1
- package/lib/cjs/flashbots/FlashbotWeb3Client.js.map +1 -1
- package/lib/cjs/gen/Generator.js +15 -0
- package/lib/cjs/gen/Generator.js.map +1 -1
- package/lib/cjs/hardhat/HardhatProvider.js +7 -7
- package/lib/cjs/hardhat/HardhatProvider.js.map +1 -1
- package/lib/cjs/indexer/BlocksTxIndexer.js +2 -2
- package/lib/cjs/indexer/BlocksTxIndexer.js.map +1 -1
- package/lib/cjs/indexer/EventsIndexer.js +11 -11
- package/lib/cjs/indexer/EventsIndexer.js.map +1 -1
- package/lib/cjs/indexer/PendingTxIndexer.js +2 -2
- package/lib/cjs/indexer/PendingTxIndexer.js.map +1 -1
- package/lib/cjs/indexer/handlers/BlocksWalker.js +9 -9
- package/lib/cjs/indexer/handlers/BlocksWalker.js.map +1 -1
- package/lib/cjs/indexer/handlers/TxQueueLoader.js +1 -1
- package/lib/cjs/indexer/storage/FsEventsIndexerStore.js +3 -3
- package/lib/cjs/indexer/storage/FsEventsIndexerStore.js.map +1 -1
- package/lib/cjs/indexer/storage/FsEventsStoreUtils.js +1 -1
- package/lib/cjs/indexer/storage/FsEventsStoreUtils.js.map +1 -1
- package/lib/cjs/json/JsonArrayMultiStore.js +1 -1
- package/lib/cjs/json/JsonArrayMultiStore.js.map +1 -1
- package/lib/cjs/json/JsonStoreFs.js +1 -1
- package/lib/cjs/json/JsonStoreFs.js.map +1 -1
- package/lib/cjs/rpc/$rpc.js +2 -2
- package/lib/cjs/rpc/$rpc.js.map +1 -1
- package/lib/cjs/rpc/Rpc.js +2 -2
- package/lib/cjs/rpc/RpcBase.js +2 -2
- package/lib/cjs/rpc/RpcBase.js.map +1 -1
- package/lib/cjs/rpc/RpcContract.js +4 -3
- package/lib/cjs/rpc/RpcContract.js.map +1 -1
- package/lib/cjs/rpc/RpcSubscription.js +1 -1
- package/lib/cjs/rpc/RpcSubscription.js.map +1 -1
- package/lib/cjs/rpc/transports/compatibility/EIP1193Transport.js +4 -4
- package/lib/cjs/rpc/transports/compatibility/EIP1193Transport.js.map +1 -1
- package/lib/cjs/rpc/transports/compatibility/Web3Transport.js +1 -1
- package/lib/cjs/rpc/transports/compatibility/Web3Transport.js.map +1 -1
- package/lib/cjs/services/TimelockService/TimelockService.js +2 -2
- package/lib/cjs/services/TimelockService/TimelockServiceFallbackSafe.js +2 -2
- package/lib/cjs/solidity/SlotsDump.js +1 -1
- package/lib/cjs/solidity/SlotsDump.js.map +1 -1
- package/lib/cjs/solidity/SlotsParser/MappingSettersResolver.js +3 -3
- package/lib/cjs/solidity/SlotsParser/MappingSettersResolver.js.map +1 -1
- package/lib/cjs/solidity/SlotsParser/SourceFile.js +3 -3
- package/lib/cjs/solidity/SlotsParser/SourceFile.js.map +1 -1
- package/lib/cjs/solidity/SolidityParser.js +1 -1
- package/lib/cjs/solidity/SolidityParser.js.map +1 -1
- package/lib/cjs/solidity/SourceCodeProvider.js +1 -1
- package/lib/cjs/solidity/SourceCodeProvider.js.map +1 -1
- package/lib/cjs/solidity/storage/Accessor.js +1 -1
- package/lib/cjs/solidity/storage/Accessor.js.map +1 -1
- package/lib/cjs/solidity/storage/SlotFixedArray.js +1 -1
- package/lib/cjs/solidity/storage/SlotFixedArray.js.map +1 -1
- package/lib/cjs/solidity/storage/SlotsStorageTransport.js +3 -3
- package/lib/cjs/solidity/storage/SlotsStorageTransport.js.map +1 -1
- package/lib/cjs/solidity/storage/handlers/SlotBytesHandler.js +1 -1
- package/lib/cjs/solidity/storage/handlers/SlotBytesHandler.js.map +1 -1
- package/lib/cjs/solidity/storage/handlers/SlotDynamicArrayHandler.js +1 -1
- package/lib/cjs/solidity/storage/handlers/SlotDynamicArrayHandler.js.map +1 -1
- package/lib/cjs/solidity/storage/handlers/SlotFixedArrayHandler.js +1 -1
- package/lib/cjs/solidity/storage/handlers/SlotFixedArrayHandler.js.map +1 -1
- package/lib/cjs/solidity/storage/handlers/SlotValueConstantHandler.js +1 -1
- package/lib/cjs/solidity/storage/handlers/SlotValueConstantHandler.js.map +1 -1
- package/lib/cjs/solidity/storage/handlers/SlotValueHandler.js +1 -1
- package/lib/cjs/solidity/storage/handlers/SlotValueHandler.js.map +1 -1
- package/lib/cjs/solidity/storage/handlers/SlotValueImmutableHandler.js +4 -4
- package/lib/cjs/solidity/storage/handlers/SlotValueImmutableHandler.js.map +1 -1
- package/lib/cjs/tokens/TokenDataProvider.js +2 -2
- package/lib/cjs/tokens/TokenDataProvider.js.map +1 -1
- package/lib/cjs/tokens/TokenExchangeService.js +1 -1
- package/lib/cjs/tokens/TokenExchangeService.js.map +1 -1
- package/lib/cjs/tokens/TokenExchanges/AmmBase/V2/AmmPairV2Service.js +2 -2
- package/lib/cjs/tokens/TokenExchanges/AmmBase/V2/AmmPairV2Service.js.map +1 -1
- package/lib/cjs/tokens/TokenExchanges/AmmV2PriceQuote.js +2 -2
- package/lib/cjs/tokens/TokenExchanges/AmmV2PriceQuote.js.map +1 -1
- package/lib/cjs/tokens/TokenOracles/amm/AmmV1Oracle.js +2 -2
- package/lib/cjs/tokens/TokenOracles/amm/AmmV1Oracle.js.map +1 -1
- package/lib/cjs/tokens/TokenTransferService.js +2 -2
- package/lib/cjs/tokens/TokenTransferService.js.map +1 -1
- package/lib/cjs/tokens/TokensService.js +1 -1
- package/lib/cjs/tokens/TokensService.js.map +1 -1
- package/lib/cjs/txs/TxNonceManager.js +1 -1
- package/lib/cjs/txs/TxWriter.js +9 -0
- package/lib/cjs/txs/TxWriter.js.map +1 -1
- package/lib/cjs/txs/conditional/GasWatcherTx.js +1 -1
- package/lib/cjs/txs/conditional/GasWatcherTx.js.map +1 -1
- package/lib/cjs/txs/receipt/TxLogParser.js +1 -1
- package/lib/cjs/utils/$crypto.js +1 -1
- package/lib/cjs/utils/$crypto.js.map +1 -1
- package/lib/cjs/utils/$date.js +1 -1
- package/lib/cjs/utils/$date.js.map +1 -1
- package/lib/cjs/utils/$hex.js +1 -1
- package/lib/cjs/utils/$logger.js +1 -1
- package/lib/cjs/utils/$logger.js.map +1 -1
- package/lib/cjs/utils/$machine.js +2 -2
- package/lib/cjs/utils/$machine.js.map +1 -1
- package/lib/cjs/utils/$traces.js +1 -1
- package/lib/cjs/utils/$traces.js.map +1 -1
- package/lib/esm/abi/$abiCoder.js.map +1 -1
- package/lib/esm/abi/$abiCoder.mjs +1 -1
- package/lib/esm/abi/Logger.mjs +1 -1
- package/lib/esm/abi/abi-coder-packed.mjs +3 -3
- package/lib/esm/abi/abi-coder.mjs +16 -16
- package/lib/esm/abi/coders/abstract-coder.js.map +1 -1
- package/lib/esm/abi/coders/abstract-coder.mjs +31 -31
- package/lib/esm/abi/fragments.js.map +1 -1
- package/lib/esm/abi/fragments.mjs +90 -90
- package/lib/esm/blocks/BlockDateResolver.js.map +1 -1
- package/lib/esm/blocks/BlockDateResolver.mjs +9 -9
- package/lib/esm/class/PackedRanges.js.map +1 -1
- package/lib/esm/class/PackedRanges.mjs +46 -46
- package/lib/esm/clients/ClientEventsStream.js.map +1 -1
- package/lib/esm/clients/ClientEventsStream.mjs +1 -1
- package/lib/esm/clients/ClientPool.js.map +1 -1
- package/lib/esm/clients/ClientPool.mjs +23 -23
- package/lib/esm/clients/WalletClient.js.map +1 -1
- package/lib/esm/clients/WalletClient.mjs +3 -3
- package/lib/esm/clients/Web3Client.js.map +1 -1
- package/lib/esm/clients/Web3Client.mjs +14 -14
- package/lib/esm/clients/Web3ClientFactory.js.map +1 -1
- package/lib/esm/clients/Web3ClientFactory.mjs +1 -1
- package/lib/esm/clients/compatibility/Web3.js.map +1 -1
- package/lib/esm/clients/compatibility/Web3.mjs +2 -2
- package/lib/esm/clients/handlers/RateLimitGuard.js.map +1 -1
- package/lib/esm/clients/handlers/RateLimitGuard.mjs +16 -16
- package/lib/esm/clients/model/PromiEventWrap.js.map +1 -1
- package/lib/esm/clients/model/PromiEventWrap.mjs +1 -1
- package/lib/esm/clients/utils/$web3Abi.js.map +1 -1
- package/lib/esm/clients/utils/$web3Abi.mjs +2 -2
- package/lib/esm/clients/utils/ClientErrorUtil.js.map +1 -1
- package/lib/esm/clients/utils/ClientErrorUtil.mjs +4 -0
- package/lib/esm/config/Config.js.map +1 -1
- package/lib/esm/contracts/Contract.js.map +1 -1
- package/lib/esm/contracts/Contract.mjs +1 -1
- package/lib/esm/contracts/ContractAbiProvider.js.map +1 -1
- package/lib/esm/contracts/ContractAbiProvider.mjs +6 -6
- package/lib/esm/contracts/ContractBase.js.map +1 -1
- package/lib/esm/contracts/ContractBase.mjs +10 -10
- package/lib/esm/contracts/ContractProvider.js.map +1 -1
- package/lib/esm/contracts/ContractProvider.mjs +1 -1
- package/lib/esm/contracts/ContractReader.js.map +1 -1
- package/lib/esm/contracts/ContractReader.mjs +5 -5
- package/lib/esm/contracts/ContractWriter.js.map +1 -1
- package/lib/esm/contracts/ContractWriter.mjs +4 -4
- package/lib/esm/contracts/deploy/ContractDeployer.js.map +1 -1
- package/lib/esm/contracts/deploy/ContractDeployer.mjs +4 -4
- package/lib/esm/contracts/deploy/Deployments.js.map +1 -1
- package/lib/esm/contracts/deploy/Deployments.mjs +68 -26
- package/lib/esm/contracts/deploy/proxy/$proxyDeploy.js.map +1 -1
- package/lib/esm/contracts/deploy/proxy/$proxyDeploy.mjs +13 -13
- package/lib/esm/contracts/deploy/proxy/ProxyDeployment.js.map +1 -1
- package/lib/esm/contracts/deploy/proxy/ProxyDeployment.mjs +58 -25
- package/lib/esm/contracts/deploy/storage/DeploymentsStorage.js.map +1 -1
- package/lib/esm/contracts/deploy/storage/DeploymentsStorage.mjs +15 -14
- package/lib/esm/contracts/utils/AbiDeserializer.js.map +1 -1
- package/lib/esm/contracts/utils/AbiDeserializer.mjs +4 -4
- package/lib/esm/contracts/utils/ContractBaseUtils.js.map +1 -1
- package/lib/esm/contracts/utils/ContractBaseUtils.mjs +3 -3
- package/lib/esm/evm/OpcodesWalker.js.map +1 -1
- package/lib/esm/evm/OpcodesWalker.mjs +1 -1
- package/lib/esm/explorer/BlockchainExplorer.js.map +1 -1
- package/lib/esm/explorer/BlockchainExplorer.mjs +1 -1
- package/lib/esm/explorer/BlockchainExplorerFactory.mjs +1 -1
- package/lib/esm/explorer/BlockchainExplorerStorage.js.map +1 -1
- package/lib/esm/explorer/BlockchainExplorerStorage.mjs +12 -12
- package/lib/esm/explorer/Evmscan.mjs +1 -1
- package/lib/esm/explorer/verifiers/FsHtmlVerifier.js.map +1 -1
- package/lib/esm/explorer/verifiers/FsHtmlVerifier.mjs +7 -7
- package/lib/esm/flashbots/FlashbotWeb3Client.js.map +1 -1
- package/lib/esm/flashbots/FlashbotWeb3Client.mjs +1 -1
- package/lib/esm/gen/Generator.js.map +1 -1
- package/lib/esm/gen/Generator.mjs +15 -0
- package/lib/esm/hardhat/HardhatProvider.js.map +1 -1
- package/lib/esm/hardhat/HardhatProvider.mjs +7 -7
- package/lib/esm/indexer/BlocksTxIndexer.js.map +1 -1
- package/lib/esm/indexer/BlocksTxIndexer.mjs +2 -2
- package/lib/esm/indexer/EventsIndexer.js.map +1 -1
- package/lib/esm/indexer/EventsIndexer.mjs +11 -11
- package/lib/esm/indexer/PendingTxIndexer.js.map +1 -1
- package/lib/esm/indexer/PendingTxIndexer.mjs +2 -2
- package/lib/esm/indexer/handlers/BlocksWalker.js.map +1 -1
- package/lib/esm/indexer/handlers/BlocksWalker.mjs +9 -9
- package/lib/esm/indexer/handlers/TxQueueLoader.mjs +1 -1
- package/lib/esm/indexer/storage/FsEventsIndexerStore.js.map +1 -1
- package/lib/esm/indexer/storage/FsEventsIndexerStore.mjs +3 -3
- package/lib/esm/indexer/storage/FsEventsStoreUtils.js.map +1 -1
- package/lib/esm/indexer/storage/FsEventsStoreUtils.mjs +1 -1
- package/lib/esm/json/JsonArrayMultiStore.js.map +1 -1
- package/lib/esm/json/JsonArrayMultiStore.mjs +1 -1
- package/lib/esm/json/JsonStoreFs.js.map +1 -1
- package/lib/esm/json/JsonStoreFs.mjs +1 -1
- package/lib/esm/rpc/$rpc.js.map +1 -1
- package/lib/esm/rpc/$rpc.mjs +2 -2
- package/lib/esm/rpc/Rpc.mjs +2 -2
- package/lib/esm/rpc/RpcBase.js.map +1 -1
- package/lib/esm/rpc/RpcBase.mjs +2 -2
- package/lib/esm/rpc/RpcContract.js.map +1 -1
- package/lib/esm/rpc/RpcContract.mjs +4 -3
- package/lib/esm/rpc/RpcSubscription.js.map +1 -1
- package/lib/esm/rpc/RpcSubscription.mjs +1 -1
- package/lib/esm/rpc/transports/compatibility/EIP1193Transport.js.map +1 -1
- package/lib/esm/rpc/transports/compatibility/EIP1193Transport.mjs +4 -4
- package/lib/esm/rpc/transports/compatibility/Web3Transport.js.map +1 -1
- package/lib/esm/rpc/transports/compatibility/Web3Transport.mjs +1 -1
- package/lib/esm/services/TimelockService/TimelockService.mjs +2 -2
- package/lib/esm/services/TimelockService/TimelockServiceFallbackSafe.mjs +2 -2
- package/lib/esm/solidity/SlotsDump.js.map +1 -1
- package/lib/esm/solidity/SlotsDump.mjs +1 -1
- package/lib/esm/solidity/SlotsParser/MappingSettersResolver.js.map +1 -1
- package/lib/esm/solidity/SlotsParser/MappingSettersResolver.mjs +3 -3
- package/lib/esm/solidity/SlotsParser/SourceFile.js.map +1 -1
- package/lib/esm/solidity/SlotsParser/SourceFile.mjs +3 -3
- package/lib/esm/solidity/SolidityParser.js.map +1 -1
- package/lib/esm/solidity/SolidityParser.mjs +1 -1
- package/lib/esm/solidity/SourceCodeProvider.js.map +1 -1
- package/lib/esm/solidity/SourceCodeProvider.mjs +1 -1
- package/lib/esm/solidity/storage/Accessor.js.map +1 -1
- package/lib/esm/solidity/storage/Accessor.mjs +1 -1
- package/lib/esm/solidity/storage/SlotFixedArray.js.map +1 -1
- package/lib/esm/solidity/storage/SlotFixedArray.mjs +1 -1
- package/lib/esm/solidity/storage/SlotsStorageTransport.js.map +1 -1
- package/lib/esm/solidity/storage/SlotsStorageTransport.mjs +3 -3
- package/lib/esm/solidity/storage/handlers/SlotBytesHandler.js.map +1 -1
- package/lib/esm/solidity/storage/handlers/SlotBytesHandler.mjs +1 -1
- package/lib/esm/solidity/storage/handlers/SlotDynamicArrayHandler.js.map +1 -1
- package/lib/esm/solidity/storage/handlers/SlotDynamicArrayHandler.mjs +1 -1
- package/lib/esm/solidity/storage/handlers/SlotFixedArrayHandler.js.map +1 -1
- package/lib/esm/solidity/storage/handlers/SlotFixedArrayHandler.mjs +1 -1
- package/lib/esm/solidity/storage/handlers/SlotValueConstantHandler.js.map +1 -1
- package/lib/esm/solidity/storage/handlers/SlotValueConstantHandler.mjs +1 -1
- package/lib/esm/solidity/storage/handlers/SlotValueHandler.js.map +1 -1
- package/lib/esm/solidity/storage/handlers/SlotValueHandler.mjs +1 -1
- package/lib/esm/solidity/storage/handlers/SlotValueImmutableHandler.js.map +1 -1
- package/lib/esm/solidity/storage/handlers/SlotValueImmutableHandler.mjs +4 -4
- package/lib/esm/tokens/TokenDataProvider.js.map +1 -1
- package/lib/esm/tokens/TokenDataProvider.mjs +2 -2
- package/lib/esm/tokens/TokenExchangeService.js.map +1 -1
- package/lib/esm/tokens/TokenExchangeService.mjs +1 -1
- package/lib/esm/tokens/TokenExchanges/AmmBase/V2/AmmPairV2Service.js.map +1 -1
- package/lib/esm/tokens/TokenExchanges/AmmBase/V2/AmmPairV2Service.mjs +2 -2
- package/lib/esm/tokens/TokenExchanges/AmmV2PriceQuote.js.map +1 -1
- package/lib/esm/tokens/TokenExchanges/AmmV2PriceQuote.mjs +2 -2
- package/lib/esm/tokens/TokenOracles/amm/AmmV1Oracle.js.map +1 -1
- package/lib/esm/tokens/TokenOracles/amm/AmmV1Oracle.mjs +2 -2
- package/lib/esm/tokens/TokenTransferService.js.map +1 -1
- package/lib/esm/tokens/TokenTransferService.mjs +2 -2
- package/lib/esm/tokens/TokensService.js.map +1 -1
- package/lib/esm/tokens/TokensService.mjs +1 -1
- package/lib/esm/txs/TxNonceManager.mjs +1 -1
- package/lib/esm/txs/TxWriter.js.map +1 -1
- package/lib/esm/txs/TxWriter.mjs +9 -0
- package/lib/esm/txs/conditional/GasWatcherTx.js.map +1 -1
- package/lib/esm/txs/conditional/GasWatcherTx.mjs +1 -1
- package/lib/esm/txs/receipt/TxLogParser.mjs +1 -1
- package/lib/esm/utils/$crypto.js.map +1 -1
- package/lib/esm/utils/$crypto.mjs +1 -1
- package/lib/esm/utils/$date.js.map +1 -1
- package/lib/esm/utils/$date.mjs +1 -1
- package/lib/esm/utils/$hex.mjs +1 -1
- package/lib/esm/utils/$logger.js.map +1 -1
- package/lib/esm/utils/$logger.mjs +1 -1
- package/lib/esm/utils/$machine.js.map +1 -1
- package/lib/esm/utils/$machine.mjs +2 -2
- package/lib/esm/utils/$traces.js.map +1 -1
- package/lib/esm/utils/$traces.mjs +1 -1
- package/lib/types/abi/abi-coder-packed.d.ts +1 -1
- package/lib/types/abi/abi-coder.d.ts +13 -13
- package/lib/types/abi/coders/abstract-coder.d.ts +14 -14
- package/lib/types/abi/fragments.d.ts +95 -95
- package/lib/types/blocks/BlockDateResolver.d.ts +7 -7
- package/lib/types/class/PackedRanges.d.ts +44 -44
- package/lib/types/clients/ClientPool.d.ts +10 -10
- package/lib/types/clients/WalletClient.d.ts +2 -2
- package/lib/types/clients/Web3Client.d.ts +6 -6
- package/lib/types/clients/Web3ClientFactory.d.ts +1 -1
- package/lib/types/clients/handlers/RateLimitGuard.d.ts +5 -5
- package/lib/types/clients/model/PromiEventWrap.d.ts +1 -1
- package/lib/types/clients/utils/$web3Abi.d.ts +1 -1
- package/lib/types/clients/utils/ClientErrorUtil.d.ts +1 -0
- package/lib/types/config/Config.d.ts +3 -2
- package/lib/types/contracts/ContractBase.d.ts +4 -4
- package/lib/types/contracts/ContractReader.d.ts +2 -2
- package/lib/types/contracts/ContractWriter.d.ts +3 -3
- package/lib/types/contracts/deploy/Deployments.d.ts +20 -15
- package/lib/types/contracts/deploy/proxy/ProxyDeployment.d.ts +2 -0
- package/lib/types/contracts/deploy/storage/DeploymentsStorage.d.ts +2 -0
- package/lib/types/explorer/BlockchainExplorerFactory.d.ts +1 -1
- package/lib/types/explorer/Evmscan.d.ts +1 -1
- package/lib/types/gen/Generator.d.ts +8 -0
- package/lib/types/indexer/BlocksTxIndexer.d.ts +4 -4
- package/lib/types/indexer/EventsIndexer.d.ts +4 -4
- package/lib/types/indexer/PendingTxIndexer.d.ts +1 -1
- package/lib/types/indexer/handlers/BlocksWalker.d.ts +2 -2
- package/lib/types/indexer/storage/FsEventsIndexerStore.d.ts +4 -4
- package/lib/types/ns/providers/INsProvider.d.ts +1 -1
- package/lib/types/rpc/Rpc.d.ts +2 -2
- package/lib/types/services/TimelockService/ITimelockService.d.ts +2 -2
- package/lib/types/services/TimelockService/TimelockService.d.ts +2 -2
- package/lib/types/services/TimelockService/TimelockServiceFallbackSafe.d.ts +2 -2
- package/lib/types/solidity/SlotsParser/SourceFile.d.ts +1 -1
- package/lib/types/solidity/storage/SlotFixedArray.d.ts +1 -1
- package/lib/types/tokens/TokenDataProvider.d.ts +2 -2
- package/lib/types/tokens/TokensService.d.ts +1 -1
- package/lib/types/txs/ITxBuilderOptions.d.ts +1 -1
- package/lib/types/txs/TxNonceManager.d.ts +1 -1
- package/lib/types/txs/TxWriter.d.ts +4 -4
- package/lib/types/txs/receipt/TxLogParser.d.ts +1 -1
- package/lib/types/utils/$date.d.ts +1 -1
- package/lib/types/utils/$hex.d.ts +1 -1
- package/package.json +1 -1
- package/readme.md +105 -83
- package/src/abi/$abiCoder.ts +1 -1
- package/src/abi/Logger.ts +1 -1
- package/src/abi/abi-coder-packed.ts +3 -3
- package/src/abi/abi-coder.ts +16 -16
- package/src/abi/coders/abstract-coder.ts +36 -36
- package/src/abi/fragments.ts +137 -137
- package/src/blocks/BlockDateResolver.ts +9 -9
- package/src/bridges/hop/HopBridge.ts +1 -1
- package/src/class/PackedRanges.ts +46 -46
- package/src/clients/ClientEventsStream.ts +1 -1
- package/src/clients/ClientPool.ts +38 -38
- package/src/clients/WalletClient.ts +3 -3
- package/src/clients/Web3BatchRequests.ts +3 -3
- package/src/clients/Web3Client.ts +21 -21
- package/src/clients/Web3ClientFactory.ts +1 -1
- package/src/clients/compatibility/Web3.ts +2 -2
- package/src/clients/handlers/RateLimitGuard.ts +16 -16
- package/src/clients/interfaces/IWeb3Client.ts +2 -2
- package/src/clients/model/PromiEventWrap.ts +1 -1
- package/src/clients/utils/$web3Abi.ts +2 -2
- package/src/clients/utils/ClientErrorUtil.ts +4 -0
- package/src/config/Config.ts +4 -3
- package/src/contracts/Contract.ts +1 -1
- package/src/contracts/ContractAbiProvider.ts +6 -6
- package/src/contracts/ContractBase.ts +14 -14
- package/src/contracts/ContractProvider.ts +1 -1
- package/src/contracts/ContractReader.ts +7 -7
- package/src/contracts/ContractWriter.ts +4 -4
- package/src/contracts/deploy/ContractDeployer.ts +4 -4
- package/src/contracts/deploy/ContractDeployment.ts +1 -1
- package/src/contracts/deploy/Deployments.ts +110 -53
- package/src/contracts/deploy/proxy/$proxyDeploy.ts +14 -14
- package/src/contracts/deploy/proxy/ProxyDeployment.ts +82 -37
- package/src/contracts/deploy/storage/DeploymentsStorage.ts +21 -18
- package/src/contracts/utils/AbiDeserializer.ts +4 -4
- package/src/contracts/utils/ContractBaseUtils.ts +3 -3
- package/src/erc4337/models/UserOperation.ts +2 -2
- package/src/evm/OpcodesWalker.ts +1 -1
- package/src/explorer/BlockchainExplorer.ts +1 -1
- package/src/explorer/BlockchainExplorerFactory.ts +1 -1
- package/src/explorer/BlockchainExplorerStorage.ts +12 -12
- package/src/explorer/Evmscan.ts +1 -1
- package/src/explorer/verifiers/FsHtmlVerifier.ts +7 -7
- package/src/flashbots/FlashbotWeb3Client.ts +1 -1
- package/src/gen/Generator.ts +17 -0
- package/src/hardhat/HardhatProvider.ts +7 -7
- package/src/indexer/BlocksTxIndexer.ts +6 -6
- package/src/indexer/EventsIndexer.ts +20 -20
- package/src/indexer/PendingTxIndexer.ts +3 -3
- package/src/indexer/handlers/BlocksWalker.ts +9 -9
- package/src/indexer/handlers/TxQueueLoader.ts +1 -1
- package/src/indexer/storage/FsEventsIndexerStore.ts +9 -9
- package/src/indexer/storage/FsEventsMetaStore.ts +1 -1
- package/src/indexer/storage/FsEventsStoreUtils.ts +1 -1
- package/src/json/JsonArrayMultiStore.ts +1 -1
- package/src/json/JsonStoreFs.ts +1 -1
- package/src/ns/providers/INsProvider.ts +1 -1
- package/src/rpc/$rpc.ts +2 -2
- package/src/rpc/Rpc.ts +2 -2
- package/src/rpc/RpcBase.ts +2 -2
- package/src/rpc/RpcContract.ts +6 -6
- package/src/rpc/RpcSubscription.ts +1 -1
- package/src/rpc/transports/compatibility/EIP1193Transport.ts +4 -4
- package/src/rpc/transports/compatibility/Web3Transport.ts +1 -1
- package/src/services/TimelockService/ITimelockService.ts +2 -2
- package/src/services/TimelockService/TimelockService.ts +2 -2
- package/src/services/TimelockService/TimelockServiceFallbackSafe.ts +2 -2
- package/src/solidity/SlotsDump.ts +1 -1
- package/src/solidity/SlotsParser/MappingSettersResolver.ts +3 -3
- package/src/solidity/SlotsParser/SourceFile.ts +3 -3
- package/src/solidity/SolidityParser.ts +1 -1
- package/src/solidity/SourceCodeProvider.ts +1 -1
- package/src/solidity/storage/Accessor.spec.ts +1 -1
- package/src/solidity/storage/Accessor.ts +1 -1
- package/src/solidity/storage/SlotDynamicArray.ts +1 -1
- package/src/solidity/storage/SlotFixedArray.ts +1 -1
- package/src/solidity/storage/SlotsStorageTransport.ts +3 -3
- package/src/solidity/storage/handlers/SlotBytesHandler.ts +1 -1
- package/src/solidity/storage/handlers/SlotDynamicArrayHandler.ts +1 -1
- package/src/solidity/storage/handlers/SlotFixedArrayHandler.ts +1 -1
- package/src/solidity/storage/handlers/SlotValueConstantHandler.ts +1 -1
- package/src/solidity/storage/handlers/SlotValueHandler.ts +1 -1
- package/src/solidity/storage/handlers/SlotValueImmutableHandler.ts +4 -4
- package/src/tokens/TokenDataProvider.ts +2 -2
- package/src/tokens/TokenExchangeService.ts +1 -1
- package/src/tokens/TokenExchanges/AmmBase/V2/AmmPairV2Service.ts +2 -2
- package/src/tokens/TokenExchanges/AmmV2PriceQuote.ts +2 -2
- package/src/tokens/TokenOracles/amm/AmmV1Oracle.ts +2 -2
- package/src/tokens/TokenTransferService.ts +2 -2
- package/src/tokens/TokensService.ts +1 -1
- package/src/txs/ITxBuilderOptions.ts +1 -1
- package/src/txs/TxNonceManager.ts +1 -1
- package/src/txs/TxWriter.ts +15 -4
- package/src/txs/agents/BatchAgent.ts +1 -1
- package/src/txs/conditional/GasWatcherTx.ts +1 -1
- package/src/txs/receipt/TxLogParser.ts +1 -1
- package/src/utils/$crypto.ts +1 -1
- package/src/utils/$date.ts +1 -1
- package/src/utils/$hex.ts +1 -1
- package/src/utils/$logger.ts +1 -1
- package/src/utils/$machine.ts +2 -2
- package/src/utils/$traces.ts +1 -1
- package/src/wallets/EIP6963ProviderFactory.ts +4 -4
|
@@ -15,6 +15,9 @@ import { $proxyDeploy } from './$proxyDeploy';
|
|
|
15
15
|
import { File } from 'atma-io';
|
|
16
16
|
import { IContractWrapped } from '@dequanto/contracts/ContractClassFactory';
|
|
17
17
|
import { HardhatProvider } from '@dequanto/hardhat/HardhatProvider';
|
|
18
|
+
import { $hex } from '@dequanto/utils/$hex';
|
|
19
|
+
import { SlotsStorage } from '@dequanto/solidity/SlotsStorage';
|
|
20
|
+
import { SlotsParser } from '@dequanto/solidity/SlotsParser';
|
|
18
21
|
|
|
19
22
|
export interface IProxy extends ContractBase {
|
|
20
23
|
changeAdmin?
|
|
@@ -24,14 +27,14 @@ export interface IProxyAdmin extends ContractBase {
|
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
export interface IBeaconProxy extends ContractBase {
|
|
27
|
-
$constructor
|
|
30
|
+
$constructor(deployer: IAccount, beacon: TEth.Address, initData: TEth.Hex)
|
|
28
31
|
}
|
|
29
32
|
export interface IBeacon extends ContractBase {
|
|
30
|
-
$constructor
|
|
33
|
+
$constructor(deployer: IAccount, implementation: TEth.Address, initialOwner?: TEth.Address)
|
|
31
34
|
|
|
32
35
|
|
|
33
36
|
implementation(): Promise<TEth.Address>
|
|
34
|
-
upgradeTo
|
|
37
|
+
upgradeTo(sender: IAccount, newImplementation: TAddress)
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
interface IDeploymentCtx {
|
|
@@ -42,6 +45,8 @@ interface IDeploymentCtx {
|
|
|
42
45
|
implementation: {
|
|
43
46
|
address: TAddress
|
|
44
47
|
initData: TEth.Hex
|
|
48
|
+
migrationData: TEth.Hex
|
|
49
|
+
migrationV?: number
|
|
45
50
|
}
|
|
46
51
|
options?: {
|
|
47
52
|
skipStorageLayoutCheck?: boolean
|
|
@@ -71,7 +76,7 @@ interface IBeaconDeploymentCtx extends IDeploymentCtx {
|
|
|
71
76
|
}
|
|
72
77
|
}
|
|
73
78
|
|
|
74
|
-
// Supports OpenZeppelin proxy deployments
|
|
79
|
+
// Supports OpenZeppelin proxy deployments.
|
|
75
80
|
|
|
76
81
|
export class ProxyDeployment {
|
|
77
82
|
|
|
@@ -91,7 +96,7 @@ export class ProxyDeployment {
|
|
|
91
96
|
async ensureProxy(ctx: IProxyDeploymentCtx) {
|
|
92
97
|
$require.notEmpty(ctx.proxyId, `ProxyId for the contract is required`);
|
|
93
98
|
$require.Address(ctx.implementation?.address, `Implementation address is required`);
|
|
94
|
-
//@TODO
|
|
99
|
+
//@TODO Add support for UUPS proxies.
|
|
95
100
|
return this.ensureTransparentProxy(ctx);
|
|
96
101
|
}
|
|
97
102
|
|
|
@@ -104,7 +109,7 @@ export class ProxyDeployment {
|
|
|
104
109
|
}
|
|
105
110
|
|
|
106
111
|
|
|
107
|
-
// Supports OpenZeppelin TransparentProxy
|
|
112
|
+
// Supports OpenZeppelin TransparentProxy v4.x and v5.x.
|
|
108
113
|
protected async ensureTransparentProxy(ctx: IProxyDeploymentCtx) {
|
|
109
114
|
let {
|
|
110
115
|
proxyId,
|
|
@@ -117,7 +122,9 @@ export class ProxyDeployment {
|
|
|
117
122
|
} = deployments;
|
|
118
123
|
let {
|
|
119
124
|
address: implAddress,
|
|
120
|
-
initData
|
|
125
|
+
initData,
|
|
126
|
+
migrationData,
|
|
127
|
+
migrationV,
|
|
121
128
|
} = ctx.implementation;
|
|
122
129
|
let {
|
|
123
130
|
Proxy,
|
|
@@ -134,11 +141,11 @@ export class ProxyDeployment {
|
|
|
134
141
|
$require.notNull(ProxyAdmin, 'TransparentProxy.ProxyAdmin is required');
|
|
135
142
|
|
|
136
143
|
|
|
137
|
-
let proxyOpts = <Parameters<Deployments['ensure']>[1]>
|
|
144
|
+
let proxyOpts = <Parameters<Deployments['ensure']>[1]>{
|
|
138
145
|
id: proxyId,
|
|
139
|
-
//
|
|
146
|
+
// Do not compare contract updates after deployment, as proxies are normally not updated.
|
|
140
147
|
latest: false,
|
|
141
|
-
//
|
|
148
|
+
// Used for verification.
|
|
142
149
|
proxyFor: implAddress,
|
|
143
150
|
arguments: [
|
|
144
151
|
// address _logic, address initialOwner, bytes memory _data
|
|
@@ -148,9 +155,7 @@ export class ProxyDeployment {
|
|
|
148
155
|
|
|
149
156
|
let proxyAbi = new Proxy().abi;
|
|
150
157
|
let v = proxyAbi.some(x => x.name === 'upgradeToAndCall') || !proxyAbi.some(x => x.type === 'error') ? 'V4' : 'V5';
|
|
151
|
-
/** OpenZeppelin V5 hides admin/upgrade public methods and introduces "error" types*/
|
|
152
|
-
|
|
153
|
-
|
|
158
|
+
/** OpenZeppelin V5 hides admin/upgrade public methods and introduces "error" types. */
|
|
154
159
|
|
|
155
160
|
let hasProxy = await deployments.has(Proxy, proxyOpts);
|
|
156
161
|
let shouldUpdate = ctx.upgradeImplementation ?? true;
|
|
@@ -171,12 +176,12 @@ export class ProxyDeployment {
|
|
|
171
176
|
}
|
|
172
177
|
|
|
173
178
|
if ($address.eq(log.params.newAdmin, deployer.address)) {
|
|
174
|
-
//
|
|
179
|
+
// OpenZeppelin < 5 does not deploy AdminContract automatically.
|
|
175
180
|
let { contract } = await deployments.ensure(ProxyAdmin, {
|
|
176
181
|
id: contractProxyAdminId
|
|
177
182
|
});
|
|
178
183
|
contractProxyAdmin = contract;
|
|
179
|
-
//
|
|
184
|
+
// Make sure we upgrade.
|
|
180
185
|
|
|
181
186
|
l`Will change the EOA admin to ProxyAdmin contract`;
|
|
182
187
|
let receipt = await Interfaces.call(
|
|
@@ -187,7 +192,7 @@ export class ProxyDeployment {
|
|
|
187
192
|
);
|
|
188
193
|
|
|
189
194
|
} else {
|
|
190
|
-
//
|
|
195
|
+
// OpenZeppelin TransparentUpgradeableProxy V5 also creates the ProxyAdmin contract on proxy deployment.
|
|
191
196
|
contractProxyAdmin = new ProxyAdmin(log.params.newAdmin, client);
|
|
192
197
|
await this.store.saveDeployment(contractProxyAdmin, {
|
|
193
198
|
id: contractProxyAdminId,
|
|
@@ -196,7 +201,7 @@ export class ProxyDeployment {
|
|
|
196
201
|
}
|
|
197
202
|
} else {
|
|
198
203
|
contractProxyAdmin = await deployments.get(ProxyAdmin, { id: contractProxyAdminId });
|
|
199
|
-
$require.notNull(contractProxyAdmin, `Proxy was deployed previously, but
|
|
204
|
+
$require.notNull(contractProxyAdmin, `Proxy was deployed previously, but ProxyAdmin ${contractProxyAdminId} was not found`);
|
|
200
205
|
}
|
|
201
206
|
|
|
202
207
|
if (hasProxy) {
|
|
@@ -206,6 +211,13 @@ export class ProxyDeployment {
|
|
|
206
211
|
if ($address.eq(address, implAddress) === false) {
|
|
207
212
|
if (shouldUpdate) {
|
|
208
213
|
await this.requireCompatibleStorageLayout(proxyId, ctx);
|
|
214
|
+
if ($hex.isEmpty(migrationData) === false) {
|
|
215
|
+
let version = await Interfaces.TransparentProxy[v].contractProxy.version(contractProxy);
|
|
216
|
+
if (migrationV <= version) {
|
|
217
|
+
// Clear the migration call; this upgrade is a raw implementation upgrade.
|
|
218
|
+
migrationData = null;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
209
221
|
$logger.log(`Upgrading ProxyAdmin(${contractProxyAdmin.address}) to ${implAddress} (${v}) from ${address}`);
|
|
210
222
|
let receipt = await Interfaces.call(
|
|
211
223
|
ctx.owner ?? deployer,
|
|
@@ -213,16 +225,16 @@ export class ProxyDeployment {
|
|
|
213
225
|
Interfaces.TransparentProxy[v].contractProxyAdmin.upgradeAndCall,
|
|
214
226
|
contractProxy.address,
|
|
215
227
|
implAddress,
|
|
216
|
-
|
|
228
|
+
migrationData,
|
|
217
229
|
);
|
|
218
230
|
await this.saveStorageLayout(proxyId, ctx);
|
|
219
231
|
} else {
|
|
220
|
-
$logger.log(`
|
|
232
|
+
$logger.log(`Skipping ProxyAdmin(${contractProxyAdmin.address}) upgrade to ${implAddress} (${v}) from ${address}`);
|
|
221
233
|
}
|
|
222
234
|
}
|
|
223
235
|
}
|
|
224
236
|
if (hasProxy === false && contractProxyReceipt != null) {
|
|
225
|
-
//
|
|
237
|
+
// New proxy deployment: save the storage layout.
|
|
226
238
|
await this.saveStorageLayout(proxyId, ctx);
|
|
227
239
|
}
|
|
228
240
|
return {
|
|
@@ -232,8 +244,8 @@ export class ProxyDeployment {
|
|
|
232
244
|
}
|
|
233
245
|
}
|
|
234
246
|
|
|
235
|
-
private async getOpenzeppelinUpgradable
|
|
236
|
-
// We
|
|
247
|
+
private async getOpenzeppelinUpgradable(opts?: { proxy?: boolean, beacon?: boolean }) {
|
|
248
|
+
// We cannot compile OpenZeppelin's contracts directly from the node_modules folder, so create wrappers.
|
|
237
249
|
const baseSource = `./node_modules/@openzeppelin/contracts/proxy`;
|
|
238
250
|
const baseOutput = `./contracts/oz`;
|
|
239
251
|
const deps = {
|
|
@@ -249,8 +261,8 @@ export class ProxyDeployment {
|
|
|
249
261
|
template: `
|
|
250
262
|
import \"${deps.TransparentUpgradeableProxy}\";
|
|
251
263
|
`,
|
|
252
|
-
//install: `TransparentUpgradeableProxy,ProxyAdmin`,
|
|
253
|
-
contracts: [`TransparentUpgradeableProxy
|
|
264
|
+
// install: `TransparentUpgradeableProxy,ProxyAdmin`,
|
|
265
|
+
contracts: [`TransparentUpgradeableProxy`, `ProxyAdmin`]
|
|
254
266
|
},
|
|
255
267
|
Beacon: {
|
|
256
268
|
source: `${baseSource}/beacon/UpgradeableBeacon.sol`,
|
|
@@ -259,8 +271,8 @@ export class ProxyDeployment {
|
|
|
259
271
|
import \"${deps.UpgradeableBeacon}\";
|
|
260
272
|
import \"${deps.BeaconProxy}\";
|
|
261
273
|
`,
|
|
262
|
-
//install: `UpgradeableBeacon,BeaconProxy`,
|
|
263
|
-
contracts: [`UpgradeableBeacon
|
|
274
|
+
// install: `UpgradeableBeacon,BeaconProxy`,
|
|
275
|
+
contracts: [`UpgradeableBeacon`, `BeaconProxy`],
|
|
264
276
|
}
|
|
265
277
|
};
|
|
266
278
|
|
|
@@ -271,7 +283,7 @@ export class ProxyDeployment {
|
|
|
271
283
|
delete paths.TransparentUpgradeableProxy;
|
|
272
284
|
}
|
|
273
285
|
|
|
274
|
-
function fmt
|
|
286
|
+
function fmt(template: string) {
|
|
275
287
|
let match = /^ +/m.exec(template);
|
|
276
288
|
return template.trim().replace(new RegExp(`^${match[0]}`, 'gm'), '');
|
|
277
289
|
}
|
|
@@ -342,12 +354,12 @@ export class ProxyDeployment {
|
|
|
342
354
|
? [
|
|
343
355
|
// address implementation
|
|
344
356
|
implAddress
|
|
345
|
-
] as [
|
|
357
|
+
] as [TEth.Address]
|
|
346
358
|
: [
|
|
347
359
|
// address implementation_, address initialOwner
|
|
348
360
|
implAddress,
|
|
349
361
|
deployer.address
|
|
350
|
-
] as [
|
|
362
|
+
] as [TEth.Address, TEth.Address]
|
|
351
363
|
};
|
|
352
364
|
let hasBeacon = await deployments.has(Beacon, beaconOpts);
|
|
353
365
|
let {
|
|
@@ -372,14 +384,14 @@ export class ProxyDeployment {
|
|
|
372
384
|
}
|
|
373
385
|
} else {
|
|
374
386
|
if (contractBeaconReceipt?.status) {
|
|
375
|
-
//
|
|
387
|
+
// New beacon deployment: save the storage layout.
|
|
376
388
|
await this.saveStorageLayout(beaconId, ctx);
|
|
377
389
|
}
|
|
378
390
|
}
|
|
379
391
|
|
|
380
392
|
let beaconProxyOpts = {
|
|
381
393
|
id: beaconProxyId,
|
|
382
|
-
// Pass the target implementation address for verification
|
|
394
|
+
// Pass the target implementation address for verification.
|
|
383
395
|
proxyFor: implAddress,
|
|
384
396
|
arguments: [
|
|
385
397
|
// address implementation
|
|
@@ -402,7 +414,7 @@ export class ProxyDeployment {
|
|
|
402
414
|
}
|
|
403
415
|
|
|
404
416
|
private async saveStorageLayout(proxyId: string, ctx: IDeploymentCtx) {
|
|
405
|
-
$require.notNull(ctx.ImplementationContract, `Implementation
|
|
417
|
+
$require.notNull(ctx.ImplementationContract, `Implementation contract class is required to compare the storage layout`);
|
|
406
418
|
let newSlots = new ctx.ImplementationContract().storage?.$storage?.slots ?? [];
|
|
407
419
|
await this.store.saveStorageLayoutInfo({
|
|
408
420
|
id: proxyId,
|
|
@@ -412,10 +424,10 @@ export class ProxyDeployment {
|
|
|
412
424
|
|
|
413
425
|
private async requireCompatibleStorageLayout(proxyId: string, ctx: IDeploymentCtx) {
|
|
414
426
|
if (ctx.options?.skipStorageLayoutCheck !== true) {
|
|
415
|
-
$require.notNull(ctx.ImplementationContract, `Implementation
|
|
427
|
+
$require.notNull(ctx.ImplementationContract, `Implementation contract class is required to compare the storage layout`);
|
|
416
428
|
|
|
417
429
|
let newStorageLayout = new ctx.ImplementationContract().storage?.$storage?.slots;
|
|
418
|
-
$require.notNull(newStorageLayout, `No storage layout was generated for ${ctx.ImplementationContract.name}
|
|
430
|
+
$require.notNull(newStorageLayout, `No storage layout was generated for ${ctx.ImplementationContract.name}.`);
|
|
419
431
|
|
|
420
432
|
let currentStorageLayout = await this.store.getStorageLayoutInfo(proxyId);
|
|
421
433
|
if (currentStorageLayout != null) {
|
|
@@ -428,9 +440,9 @@ export class ProxyDeployment {
|
|
|
428
440
|
}
|
|
429
441
|
}
|
|
430
442
|
|
|
431
|
-
private getOzVersionByBeacon
|
|
443
|
+
private getOzVersionByBeacon(Beacon: Constructor<IBeacon>): 5 | 4 {
|
|
432
444
|
let $constructor = new Beacon().abi?.find(x => x.type === 'constructor');
|
|
433
|
-
$require.notNull($constructor, `Invalid Beacon contract: constructor not found`);
|
|
445
|
+
$require.notNull($constructor, `Invalid Beacon contract: constructor was not found`);
|
|
434
446
|
|
|
435
447
|
if ($constructor.inputs.length === 1) {
|
|
436
448
|
// constructor(address implementation_)
|
|
@@ -465,9 +477,31 @@ namespace Interfaces {
|
|
|
465
477
|
export const V4 = {
|
|
466
478
|
contractProxy: {
|
|
467
479
|
changeAdmin: 'changeAdmin(address newAdmin) external',
|
|
480
|
+
async version(contract: ContractBase) {
|
|
481
|
+
const slots = await SlotsParser.slotsFromAbi(`
|
|
482
|
+
(uint8 _version, bool initializing)
|
|
483
|
+
`);
|
|
484
|
+
const storage = SlotsStorage.createWithClient(
|
|
485
|
+
contract.client,
|
|
486
|
+
contract.address,
|
|
487
|
+
slots
|
|
488
|
+
);
|
|
489
|
+
let v = await storage.get('_version');
|
|
490
|
+
return v;
|
|
491
|
+
},
|
|
468
492
|
},
|
|
469
493
|
contractProxyAdmin: {
|
|
470
494
|
async upgradeAndCall(account, contract, proxyAddress, implementationAddress, data) {
|
|
495
|
+
if (data != null && $hex.isEmpty(data) === false) {
|
|
496
|
+
return call(
|
|
497
|
+
account,
|
|
498
|
+
contract,
|
|
499
|
+
'upgradeAndCall(address proxy, address implementation, bytes data) external',
|
|
500
|
+
proxyAddress,
|
|
501
|
+
implementationAddress,
|
|
502
|
+
data,
|
|
503
|
+
);
|
|
504
|
+
}
|
|
471
505
|
return call(
|
|
472
506
|
account,
|
|
473
507
|
contract,
|
|
@@ -480,7 +514,18 @@ namespace Interfaces {
|
|
|
480
514
|
}
|
|
481
515
|
export const V5 = {
|
|
482
516
|
contractProxy: {
|
|
483
|
-
|
|
517
|
+
async version(contract: ContractBase) {
|
|
518
|
+
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
|
|
519
|
+
const position = '0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00';
|
|
520
|
+
const slots = await SlotsParser.slotsFromAbi(`
|
|
521
|
+
(uint8 initialized, bool initializing)
|
|
522
|
+
`);
|
|
523
|
+
const storage = SlotsStorage.createWithClient(contract.client, contract.address, slots, {
|
|
524
|
+
storageOffset: position
|
|
525
|
+
});
|
|
526
|
+
const v = await storage.get('initialized');
|
|
527
|
+
return v;
|
|
528
|
+
},
|
|
484
529
|
},
|
|
485
530
|
contractProxyAdmin: {
|
|
486
531
|
upgradeAndCall: 'upgradeAndCall(address proxy, address implementation, bytes memory data) external'
|
|
@@ -22,11 +22,12 @@ import { $path } from '@dequanto/utils/$path';
|
|
|
22
22
|
export interface IDeployment {
|
|
23
23
|
id: string
|
|
24
24
|
name: string
|
|
25
|
-
|
|
25
|
+
immutablesKey?: string
|
|
26
|
+
// TS/JS file.
|
|
26
27
|
main: string
|
|
27
28
|
address: TAddress
|
|
28
29
|
|
|
29
|
-
// If the
|
|
30
|
+
// If the contract was deployed with a proxy, the address is the proxy address.
|
|
30
31
|
implementation?: TAddress
|
|
31
32
|
|
|
32
33
|
proxyFor?: TAddress
|
|
@@ -53,9 +54,9 @@ export class DeploymentsStorage {
|
|
|
53
54
|
|
|
54
55
|
constructor (public client: Web3Client, public deployer: IAccount, public opts: {
|
|
55
56
|
directory?: string
|
|
56
|
-
//
|
|
57
|
+
// Part of the deployments filename.
|
|
57
58
|
name?: string
|
|
58
|
-
// TPlatform of a forked network
|
|
59
|
+
// TPlatform of a forked network.
|
|
59
60
|
fork?: string
|
|
60
61
|
}) {
|
|
61
62
|
|
|
@@ -103,7 +104,7 @@ export class DeploymentsStorage {
|
|
|
103
104
|
if (deploymentsByAddress.length > 1) {
|
|
104
105
|
let asProxy = deploymentsByAddress.filter(x => x.proxyFor != null);
|
|
105
106
|
if (asProxy.length > 0) {
|
|
106
|
-
$require.eq(asProxy.length, 1, '
|
|
107
|
+
$require.eq(asProxy.length, 1, 'Expected only one deployment per address.');
|
|
107
108
|
return asProxy[0];
|
|
108
109
|
}
|
|
109
110
|
}
|
|
@@ -111,12 +112,12 @@ export class DeploymentsStorage {
|
|
|
111
112
|
if (deploymentsByAddress.length === 0) {
|
|
112
113
|
let asImplementations = deployments.filter(x => $address.eq(x.implementation, byAddress));
|
|
113
114
|
if (asImplementations.length > 0) {
|
|
114
|
-
$require.eq(asImplementations.length, 1, '
|
|
115
|
+
$require.eq(asImplementations.length, 1, 'Expected only one deployment per address.');
|
|
115
116
|
return asImplementations[0];
|
|
116
117
|
}
|
|
117
118
|
}
|
|
118
119
|
|
|
119
|
-
throw new Error(`Deployment not found for
|
|
120
|
+
throw new Error(`Deployment was not found for address: ${byAddress}`);
|
|
120
121
|
}
|
|
121
122
|
|
|
122
123
|
let id = typeof mix === 'string' ? mix : mix.name;
|
|
@@ -158,6 +159,7 @@ export class DeploymentsStorage {
|
|
|
158
159
|
async saveDeployment (contract: ContractBase, info: {
|
|
159
160
|
id: string
|
|
160
161
|
name: string
|
|
162
|
+
immutablesKey?: string
|
|
161
163
|
bytecodeHash?: TEth.Hex
|
|
162
164
|
}, receipt?: TEth.TxReceipt) {
|
|
163
165
|
$contract.store.register(contract as any);
|
|
@@ -168,6 +170,7 @@ export class DeploymentsStorage {
|
|
|
168
170
|
let deployment = <IDeployment> {
|
|
169
171
|
id: info.id,
|
|
170
172
|
name: info.name,
|
|
173
|
+
immutablesKey: info.immutablesKey,
|
|
171
174
|
main: $path.getRelativePath(contract.$meta?.class ?? contract.$meta?.artifact ?? contract.$meta.source),
|
|
172
175
|
bytecodeHash: info.bytecodeHash,
|
|
173
176
|
address: contract.address,
|
|
@@ -177,7 +180,7 @@ export class DeploymentsStorage {
|
|
|
177
180
|
deployer: this.deployer.address,
|
|
178
181
|
timestamp: $date.toUnixTimestamp(new Date()),
|
|
179
182
|
|
|
180
|
-
// If current deployment is the implementation, set the field to null
|
|
183
|
+
// If the current deployment is the implementation, set the field to null for later reconfiguration. Otherwise, keep the field uninitialized.
|
|
181
184
|
implementation: currentDeployment?.implementation ? null : void 0,
|
|
182
185
|
};
|
|
183
186
|
|
|
@@ -255,11 +258,11 @@ export class DeploymentsStorage {
|
|
|
255
258
|
let upstreamDeployments: IDeployment[];
|
|
256
259
|
let shouldCopy = true;
|
|
257
260
|
if (await File.existsAsync(path)) {
|
|
258
|
-
// forked deployments path already exists
|
|
261
|
+
// The forked deployments path already exists; check whether it is stale.
|
|
259
262
|
let blockNumber = await this.client.getBlockNumber();
|
|
260
263
|
if (upstreamDeploymentExists) {
|
|
261
264
|
upstreamDeployments = await File.readAsync<IDeployment[]>(upstreamDeploymentsPath);
|
|
262
|
-
// 1. Check
|
|
265
|
+
// 1. Check whether the original (upstream) network has more recent deployments.
|
|
263
266
|
let hasNewDeployments = upstreamDeployments.some(x => x.block > blockNumber);
|
|
264
267
|
shouldCopy = hasNewDeployments;
|
|
265
268
|
} else {
|
|
@@ -275,11 +278,11 @@ export class DeploymentsStorage {
|
|
|
275
278
|
shouldCopy = true;
|
|
276
279
|
}
|
|
277
280
|
if (shouldCopy === false) {
|
|
278
|
-
// 3. Just
|
|
281
|
+
// 3. Just in case, check whether any deployments have a higher block number than the current HEAD.
|
|
279
282
|
let hasNewDeployments = deployments.some(x => x.block > blockNumber);
|
|
280
283
|
shouldCopy = hasNewDeployments;
|
|
281
284
|
if (shouldCopy === false) {
|
|
282
|
-
// 4. Check
|
|
285
|
+
// 4. Check whether the latest deployment transaction exists in the current forked network.
|
|
283
286
|
let latestDeployment = alot(deployments).maxItem(x => x.block);
|
|
284
287
|
if (latestDeployment != null) {
|
|
285
288
|
try {
|
|
@@ -292,7 +295,7 @@ export class DeploymentsStorage {
|
|
|
292
295
|
}
|
|
293
296
|
}
|
|
294
297
|
if (shouldCopy === false && upstreamDeployments?.length > 0) {
|
|
295
|
-
// 5. Just
|
|
298
|
+
// 5. Just in case, check for upstream deployments with a lower block number than the current HEAD that are missing from the current forked network.
|
|
296
299
|
let deploymentIds = alot(deployments).toDictionary(x => x.id);
|
|
297
300
|
let hasNewDeployments = upstreamDeployments
|
|
298
301
|
.filter(x => x.block <= blockNumber)
|
|
@@ -303,14 +306,14 @@ export class DeploymentsStorage {
|
|
|
303
306
|
}
|
|
304
307
|
}
|
|
305
308
|
if (shouldCopy) {
|
|
306
|
-
//
|
|
309
|
+
// Current forked deployments are stale; copy the upstream deployments or clear them.
|
|
307
310
|
if (upstreamDeploymentExists) {
|
|
308
311
|
await File.copyToAsync(upstreamDeploymentsPath, path, {
|
|
309
312
|
silent: true
|
|
310
313
|
});
|
|
311
314
|
File.clearCache();
|
|
312
315
|
} else {
|
|
313
|
-
//
|
|
316
|
+
// Clear.
|
|
314
317
|
await File.writeAsync(path, []);
|
|
315
318
|
}
|
|
316
319
|
}
|
|
@@ -340,7 +343,7 @@ export class DeploymentsStorage {
|
|
|
340
343
|
]);
|
|
341
344
|
let deployments = await store.getAll();
|
|
342
345
|
if (deployments.length === 0) {
|
|
343
|
-
// Nothing to remove:
|
|
346
|
+
// Nothing to remove: no deployments.
|
|
344
347
|
return;
|
|
345
348
|
}
|
|
346
349
|
if (block0 == null) {
|
|
@@ -349,9 +352,9 @@ export class DeploymentsStorage {
|
|
|
349
352
|
|
|
350
353
|
let stale = deployments.filter(x => {
|
|
351
354
|
return x.timestamp == null
|
|
352
|
-
//
|
|
355
|
+
// Was deployed earlier than the current genesis block.
|
|
353
356
|
|| x.timestamp < block0.timestamp
|
|
354
|
-
//
|
|
357
|
+
// Was deployed in a later block than the current block.
|
|
355
358
|
|| x.block > blockNumberHead;
|
|
356
359
|
});
|
|
357
360
|
if (stale.length > 0) {
|
|
@@ -10,7 +10,7 @@ export namespace AbiDeserializer {
|
|
|
10
10
|
|
|
11
11
|
export function process(result: any, types: TAbiOutput[]) {
|
|
12
12
|
if (types == null || types.length === 0) {
|
|
13
|
-
//
|
|
13
|
+
// Return as is.
|
|
14
14
|
return result;
|
|
15
15
|
}
|
|
16
16
|
let type: 'array' | 'object' | AbiNativeType = $abiParser.getReturnTypeFromTypes(types);
|
|
@@ -48,7 +48,7 @@ export namespace AbiDeserializer {
|
|
|
48
48
|
}
|
|
49
49
|
if (type.type === 'tuple[]') {
|
|
50
50
|
if (Array.isArray(val) === false) {
|
|
51
|
-
throw new Error(`${type.name} tuple[] expects array to deserialize. Got ${val}`);
|
|
51
|
+
throw new Error(`${type.name} tuple[] expects an array to deserialize. Got ${val}`);
|
|
52
52
|
}
|
|
53
53
|
return val.map(item => {
|
|
54
54
|
return process(item, type.components);
|
|
@@ -61,7 +61,7 @@ export namespace AbiDeserializer {
|
|
|
61
61
|
value = normalizeArray(value);
|
|
62
62
|
|
|
63
63
|
if (Array.isArray(value) === false) {
|
|
64
|
-
throw new Error(`
|
|
64
|
+
throw new Error(`Expected an array of types: ${types.map(x => x.type)}; got ${value}`);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
let out = [];
|
|
@@ -87,7 +87,7 @@ export namespace AbiDeserializer {
|
|
|
87
87
|
return out;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
// { 0: a, 1: b, 2: c } to array
|
|
90
|
+
// Convert { 0: a, 1: b, 2: c } to an array.
|
|
91
91
|
function normalizeArray(val) {
|
|
92
92
|
if (Array.isArray(val)) {
|
|
93
93
|
return val;
|
|
@@ -11,13 +11,13 @@ export namespace ContractBaseUtils {
|
|
|
11
11
|
export function $getAbiItem(abi: TAbiItem[], type: 'event' | 'function' | 'string', name: string, argsCount?: number) {
|
|
12
12
|
let arr = abi.filter(x => x.type === type && x.name === name);
|
|
13
13
|
if (arr.length === 0) {
|
|
14
|
-
throw new Error(`TAbiItem ${name} not found`);
|
|
14
|
+
throw new Error(`TAbiItem ${name} was not found`);
|
|
15
15
|
}
|
|
16
16
|
if (arr.length === 1) {
|
|
17
17
|
return arr[0];
|
|
18
18
|
}
|
|
19
19
|
if (argsCount == null) {
|
|
20
|
-
throw new Error(`Found multiple TAbiItems for ${name}.
|
|
20
|
+
throw new Error(`Found multiple TAbiItems for ${name}. Argument count was not specified to pick one`);
|
|
21
21
|
}
|
|
22
22
|
return arr.find(x => (x.inputs?.length ?? 0) === argsCount);
|
|
23
23
|
}
|
|
@@ -98,7 +98,7 @@ export namespace ContractBaseUtils {
|
|
|
98
98
|
let tx = await writer.writeAsync(account, abi, params);
|
|
99
99
|
let { error, result } = await $promise.caught(tx.onSigned);
|
|
100
100
|
|
|
101
|
-
//
|
|
101
|
+
// Get the transaction hash.
|
|
102
102
|
let hash = result != null ? $contract.keccak256(result) : null;
|
|
103
103
|
return { error, signed: result, hash };
|
|
104
104
|
}
|
|
@@ -9,8 +9,8 @@ export const UserOperationDefaults = <UserOperation> {
|
|
|
9
9
|
initCode: '0x',
|
|
10
10
|
callData: '0x',
|
|
11
11
|
callGasLimit: 0n,
|
|
12
|
-
verificationGasLimit: 150000n, //
|
|
13
|
-
preVerificationGas: 21000n, //
|
|
12
|
+
verificationGasLimit: 150000n, // Default verification gas, will add the create2 cost (3200+200*length) if initCode exists
|
|
13
|
+
preVerificationGas: 21000n, // Should also cover calldata cost
|
|
14
14
|
maxFeePerGas: 0n,
|
|
15
15
|
maxPriorityFeePerGas: 0n,
|
|
16
16
|
paymasterAndData: '0x',
|
package/src/evm/OpcodesWalker.ts
CHANGED
|
@@ -93,7 +93,7 @@ export class OpcodesWalker {
|
|
|
93
93
|
// Is Conditional
|
|
94
94
|
this.evm.stack.pop();
|
|
95
95
|
|
|
96
|
-
// Visit falsy leaf
|
|
96
|
+
// Visit the falsy leaf as if the jump did not occur
|
|
97
97
|
let evm = this.evm.clone();
|
|
98
98
|
let walker = new OpcodesWalker(evm, this.opcodes);
|
|
99
99
|
let { opcodes } = walker.goToExit(this.current);
|
|
@@ -377,7 +377,7 @@ export class BlockchainExplorer implements IBlockchainExplorer {
|
|
|
377
377
|
files
|
|
378
378
|
};
|
|
379
379
|
} catch (error) {
|
|
380
|
-
throw new Error(`Source code (${url})
|
|
380
|
+
throw new Error(`Source code (${url}) cannot be parsed: ${error.message}`);
|
|
381
381
|
}
|
|
382
382
|
}
|
|
383
383
|
function parseJson(str: string) {
|
|
@@ -50,16 +50,16 @@ export class BlockchainExplorerStorage implements IBlockchainExplorer {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
submitContractProxyVerification(contractData: { address: TAddress; expectedImplementation?: TAddress }): Promise<string> {
|
|
53
|
-
throw new Error('Method not implemented
|
|
53
|
+
throw new Error('Method not implemented');
|
|
54
54
|
}
|
|
55
55
|
checkContractProxyVerificationSubmission(submission: { guid: any; }): Promise<string> {
|
|
56
|
-
throw new Error('Method not implemented
|
|
56
|
+
throw new Error('Method not implemented');
|
|
57
57
|
}
|
|
58
58
|
submitContractVerification(contractData: { address: `0x${string}`; sourceCode: any; contractName: any; compilerVersion: any; optimizer?: { enabled?: boolean; runs: number; }; arguments?: `0x${string}`; }): Promise<string> {
|
|
59
|
-
throw new Error('Method not implemented
|
|
59
|
+
throw new Error('Method not implemented');
|
|
60
60
|
}
|
|
61
61
|
checkContractVerificationSubmission(submission: { guid: any; }): Promise<string> {
|
|
62
|
-
throw new Error('Method not implemented
|
|
62
|
+
throw new Error('Method not implemented');
|
|
63
63
|
}
|
|
64
64
|
registerAbi(abis: { name: any; address: any; abi: any; }[]) {
|
|
65
65
|
abis.forEach(x => {
|
|
@@ -73,10 +73,10 @@ export class BlockchainExplorerStorage implements IBlockchainExplorer {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
getContractMeta(q: string): Promise<IContractDetails> {
|
|
76
|
-
throw new Error('Method not implemented
|
|
76
|
+
throw new Error('Method not implemented');
|
|
77
77
|
}
|
|
78
78
|
getContractCreation(address: string): Promise<{ creator: TEth.Address; txHash: TEth.Hex; }> {
|
|
79
|
-
throw new Error('Method not implemented
|
|
79
|
+
throw new Error('Method not implemented');
|
|
80
80
|
}
|
|
81
81
|
async getContractAbi(address: TAddress, opts?: { implementation?: TAddress; }): Promise<{ abi: string; implementation: TAddress; }> {
|
|
82
82
|
let $address = opts?.implementation ?? address;
|
|
@@ -103,22 +103,22 @@ export class BlockchainExplorerStorage implements IBlockchainExplorer {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
getTransactions(address: string, params?: { fromBlockNumber?: number; page?: number; size?: number; }): Promise<TEth.Tx[]> {
|
|
106
|
-
throw new Error('Method not implemented
|
|
106
|
+
throw new Error('Method not implemented');
|
|
107
107
|
}
|
|
108
108
|
getTransactionsAll(address: string): Promise<TEth.Tx[]> {
|
|
109
|
-
throw new Error('Method not implemented
|
|
109
|
+
throw new Error('Method not implemented');
|
|
110
110
|
}
|
|
111
111
|
getInternalTransactions(address: string, params?: { fromBlockNumber?: number; page?: number; size?: number; }): Promise<TEth.Tx[]> {
|
|
112
|
-
throw new Error('Method not implemented
|
|
112
|
+
throw new Error('Method not implemented');
|
|
113
113
|
}
|
|
114
114
|
getInternalTransactionsAll(address: string): Promise<TEth.Tx[]> {
|
|
115
|
-
throw new Error('Method not implemented
|
|
115
|
+
throw new Error('Method not implemented');
|
|
116
116
|
}
|
|
117
117
|
getErc20Transfers(address: string, fromBlockNumber?: number): Promise<IBlockchainTransferEvent[]> {
|
|
118
|
-
throw new Error('Method not implemented
|
|
118
|
+
throw new Error('Method not implemented');
|
|
119
119
|
}
|
|
120
120
|
getErc20TransfersAll(address: string, fromBlockNumber?: number): Promise<IBlockchainTransferEvent[]> {
|
|
121
|
-
throw new Error('Method not implemented
|
|
121
|
+
throw new Error('Method not implemented');
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
}
|