Repository: skalenetwork/IMA (language: python)

Issue:
Removed security print out for ecdsaSignMessageHash call
Removed security print out for ecdsaSignMessageHash call


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 74fb0a3e9..1347cef38 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -56,7 +56,9 @@ jobs:
         echo "Branch $BRANCH"
         export VERSION=$(bash ./scripts/calculate_version.sh)
         echo "VERSION=$VERSION" >> $GITHUB_ENV
-        echo "Version $VERSION"    
+        echo "Version $VERSION"
+        ( test $BRANCH = "stable" || test $BRANCH = "master" && export PRERELEASE=false ) || export PRERELEASE=true
+        echo "PRERELEASE=$PRERELEASE" >> $GITHUB_ENV
         echo ------------ download binaries
         LIB_BLS_RELEASE_TAG=${{ secrets.LIB_BLS_RELEASE_TAG }} bash ./scripts/download_binaries.sh
         export RELEASE=true
@@ -116,7 +118,7 @@ jobs:
         tag_name: ${{ env.VERSION }}
         release_name: ${{ env.VERSION }}
         draft: false
-        prerelease: true
+        prerelease: ${{ env.PRERELEASE }}
     
     - name: Upload Release Assets
       id: upload-release-assets
diff --git a/VERSION b/VERSION
index 1892b9267..31e5c8434 100644
--- a/VERSION
+++ b/VERSION
@@ -1,1 +1,1 @@
-1.3.2
+1.3.3
diff --git a/agent/bls.js b/agent/bls.js
index 72cb45352..433f4fcc8 100644
--- a/agent/bls.js
+++ b/agent/bls.js
@@ -822,7 +822,7 @@ async function do_sign_messages_impl(
     };
     const arrSignResults = [];
     let cntSuccess = 0;
-    let details = log.createMemoryStream();
+    let details = log.createMemoryStream( true );
     const strGatheredDetailsName = strDirection + "-" + "do_sign_messages_impl-#" + nTransferLoopCounter +
         "-" + strFromChainName + "-msg#" + nIdxCurrentMsgBlockStart;
     try {
@@ -864,8 +864,15 @@ async function do_sign_messages_impl(
         //     }
         // }
         //
-        details.write( strLogPrefix + cc.debug( "Will sign " ) + cc.info( jarrMessages.length ) + cc.debug( " message(s)..." ) + "\n" );
-        log.write( strLogPrefix + cc.debug( "Will sign " ) + cc.j( jarrMessages ) + cc.debug( " message(s)..." ) + "\n" );
+        const sequence_id = owaspUtils.remove_starting_0x( get_w3().utils.soliditySha3( log.generate_timestamp_string( null, false ) ) );
+        details.write( strLogPrefix +
+            cc.debug( "Will sign " ) + cc.info( jarrMessages.length ) + cc.debug( " message(s)" ) +
+            cc.debug( ", " ) + cc.notice( "sequence ID" ) + cc.debug( " is " ) + cc.attention( sequence_id ) +
+            cc.debug( "..." ) + "\n" );
+        log.write( strLogPrefix +
+            cc.debug( "Will sign " ) + cc.j( jarrMessages ) + cc.debug( " message(s)" ) +
+            cc.debug( ", " ) + cc.notice( "sequence ID" ) + cc.debug( " is " ) + cc.attention( sequence_id ) +
+            cc.debug( "..." ) + "\n" );
         const jarrNodes = imaState.joSChainNetworkInfo.network;
         details.write( strLogPrefix + cc.debug( "Will query to sign " ) + cc.info( jarrNodes.length ) + cc.debug( " skaled node(s)..." ) + "\n" );
         const nThreshold = discover_bls_threshold( imaState.joSChainNetworkInfo );
@@ -884,13 +891,21 @@ async function do_sign_messages_impl(
         //     details.write( strLogPrefix + cc.warning( "Minimal BLS parts number for dicovery was increased." ) + "\n" );
         //     nCountOfBlsPartsToCollect = 2;
         // }
-        log.write( strLogPrefix + cc.debug( "Will collect " ) + cc.info( nCountOfBlsPartsToCollect ) + cc.debug( " signature(s)" ) + "\n" );
-        details.write( strLogPrefix + cc.debug( "Will collect " ) + cc.info( nCountOfBlsPartsToCollect ) + cc.debug( " from " ) + cc.info( jarrNodes.length ) + cc.debug( " nodes" ) + "\n" );
+        log.write( strLogPrefix +
+            cc.debug( "Will collect " ) + cc.info( nCountOfBlsPartsToCollect ) + cc.debug( " signature(s)" ) +
+            cc.debug( ", " ) + cc.notice( "sequence ID" ) + cc.debug( " is " ) + cc.attention( sequence_id ) +
+            "\n" );
+        details.write( strLogPrefix +
+            cc.debug( "Will collect " ) + cc.info( nCountOfBlsPartsToCollect ) + cc.debug( " from " ) +
+            cc.info( jarrNodes.length ) + cc.debug( " nodes" ) +
+            cc.debug( ", " ) + cc.notice( "sequence ID" ) + cc.debug( " is " ) + cc.attention( sequence_id ) +
+            "\n" );
         for( let i = 0; i < jarrNodes.length; ++i ) {
             const joNode = jarrNodes[i];
             const strNodeURL = imaUtils.compose_schain_node_url( joNode );
             const strNodeDescColorized = cc.u( strNodeURL ) + " " +
-                cc.normal( "(" ) + cc.bright( i ) + cc.normal( "/" ) + cc.bright( jarrNodes.length ) + cc.normal( ", ID " ) + cc.info( joNode.nodeID ) + cc.normal( ")" );
+                cc.normal( "(" ) + cc.bright( i ) + cc.normal( "/" ) + cc.bright( jarrNodes.length ) + cc.normal( ", ID " ) + cc.info( joNode.nodeID ) + cc.normal( ")" ) +
+                cc.normal( ", " ) + cc.notice( "sequence ID" ) + cc.normal( " is " ) + cc.attention( sequence_id );
             const rpcCallOpts = null;
             await rpcCall.create( strNodeURL, rpcCallOpts, async function( joCall, err ) {
                 if( err ) {
@@ -899,7 +914,9 @@ async function do_sign_messages_impl(
                     const strErrorMessage =
                         strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) +
                         cc.error( " JSON RPC call to S-Chain node " ) + strNodeDescColorized +
-                        cc.error( " failed, RPC call was not created, error: " ) + cc.warning( err ) + "\n";
+                        cc.error( " failed, RPC call was not created, error: " ) + cc.warning( err ) +
+                        cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) +
+                        "\n";
                     log.write( strErrorMessage );
                     details.write( strErrorMessage );
                     return;
@@ -931,15 +948,22 @@ async function do_sign_messages_impl(
                     startMessageIdx: nIdxCurrentMsgBlockStart,
                     dstChainName: targetChainName,
                     srcChainName: fromChainName,
-                    messages: jarrMessages
+                    messages: jarrMessages,
                     // fromChainURL: fromChainURL,
-                    // targetChainURL: targetChainURL
+                    // targetChainURL: targetChainURL,
+                    qa: {
+                        skaled_no: 0 + i,
+                        sequence_id: "" + sequence_id,
+                        ts: "" + log.generate_timestamp_string( null, false )
+                    }
                 };
                 details.write(
-                    strLogPrefix + cc.debug( "Will invoke " ) + cc.info( "skale_imaVerifyAndSign" ) +
+                    strLogPrefix + log.generate_timestamp_string( null, true ) + " " +
+                    cc.debug( "Will invoke " ) + cc.info( "skale_imaVerifyAndSign" ) +
                     cc.debug( " for transfer from chain " ) + cc.info( fromChainName ) +
                     cc.debug( " to chain " ) + cc.info( targetChainName ) +
                     cc.debug( " with params " ) + cc.j( joParams ) +
+                    cc.debug( ", " ) + cc.notice( "sequence ID" ) + cc.debug( " is " ) + cc.attention( sequence_id ) +
                     "\n" );
                 await joCall.call( {
                     method: "skale_imaVerifyAndSign",
@@ -951,17 +975,21 @@ async function do_sign_messages_impl(
                         const strErrorMessage =
                             strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) +
                             cc.error( " JSON RPC call to S-Chain node " ) + strNodeDescColorized +
-                            cc.error( " failed, RPC call reported error: " ) + cc.warning( err ) + "\n";
+                            cc.error( " failed, RPC call reported error: " ) + cc.warning( err ) +
+                            cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) +
+                            "\n";
                         log.write( strErrorMessage );
                         details.write( strErrorMessage );
                         return;
                     }
                     details.write(
-                        strLogPrefix + cc.debug( "Got answer from " ) + cc.info( "skale_imaVerifyAndSign" ) +
+                        strLogPrefix + log.generate_timestamp_string( null, true ) + " " +
+                        cc.debug( "Got answer from " ) + cc.info( "skale_imaVerifyAndSign" ) +
                         cc.debug( " for transfer from chain " ) + cc.info( fromChainName ) +
                         cc.debug( " to chain " ) + cc.info( targetChainName ) +
                         cc.debug( " with params " ) + cc.j( joParams ) +
                         cc.debug( ", answer is " ) + cc.j( joOut ) +
+                        cc.debug( ", " ) + cc.notice( "sequence ID" ) + cc.debug( " is " ) + cc.attention( sequence_id ) +
                         "\n" );
                     if( joOut.result == null || joOut.result == undefined || ( !typeof joOut.result == "object" ) ) {
                         ++joGatheringTracker.nCountErrors;
@@ -969,14 +997,18 @@ async function do_sign_messages_impl(
                             const strErrorMessage =
                                 strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " +
                                 cc.error( "S-Chain node " ) + strNodeDescColorized +
-                                cc.error( " reported wallet error: " ) + cc.warning( joOut.error.message ) + "\n";
+                                cc.error( " reported wallet error: " ) + cc.warning( joOut.error.message ) +
+                                cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) +
+                                "\n";
                             log.write( strErrorMessage );
                             details.write( strErrorMessage );
                         } else {
                             const strErrorMessage =
                                 strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " +
                                 cc.error( "JSON RPC call to S-Chain node " ) + strNodeDescColorized +
-                                cc.error( " failed with " ) + cc.warning( "unknown wallet error" ) + "\n";
+                                cc.error( " failed with " ) + cc.warning( "unknown wallet error" ) +
+                                cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) +
+                                "\n";
                             log.write( strErrorMessage );
                             details.write( strErrorMessage );
                         }
@@ -1030,7 +1062,9 @@ async function do_sign_messages_impl(
                                 const strErrorMessage =
                                     strLogPrefixA + cc.error( "S-Chain node " ) + strNodeDescColorized + cc.error( " sign " ) +
                                     cc.error( " CRITICAL ERROR:" ) + cc.error( " partial signature fail from with index " ) + cc.info( nZeroBasedNodeIndex ) +
-                                    cc.error( ", error is " ) + cc.warning( err.toString() ) + "\n";
+                                    cc.error( ", error is " ) + cc.warning( err.toString() ) +
+                                    cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) +
+                                    "\n";
                                 log.write( strErrorMessage );
                                 details.write( strErrorMessage );
                             }
@@ -1059,7 +1093,9 @@ async function do_sign_messages_impl(
                         const strErrorMessage =
                             strLogPrefix + cc.error( "S-Chain node " ) + strNodeDescColorized + " " + cc.fatal( "CRITICAL ERROR:" ) +
                             cc.error( " signature fail from node " ) + cc.info( joNode.nodeID ) +
-                            cc.error( ", error is " ) + cc.warning( err.toString() ) + "\n";
+                            cc.error( ", error is " ) + cc.warning( err.toString() ) +
+                            cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) +
+                            "\n";
                         log.write( strErrorMessage );
                         details.write( strErrorMessage );
                     }
diff --git a/agent/cli.js b/agent/cli.js
index c999c74b2..a8fb69514 100644
--- a/agent/cli.js
+++ b/agent/cli.js
@@ -422,8 +422,10 @@ function parse( joExternalHandlers, argv ) {
             console.log( soi + cc.debug( "--" ) + cc.bright( "log" ) + cc.sunny( "=" ) + cc.note( "path" ) + cc.debug( "......................" ) + cc.notice( "Write program output to specified " ) + cc.note( "log file" ) + cc.debug( "(multiple files can be specified)" ) + cc.notice( "." ) );
             console.log( soi + cc.debug( "--" ) + cc.bright( "log-size" ) + cc.sunny( "=" ) + cc.note( "value" ) + cc.debug( "................" ) + cc.notice( "Max size" ) + cc.debug( "(in bytes)" ) + cc.notice( " of one log file" ) + cc.debug( "(affects to log log rotation)" ) + cc.notice( "." ) );
             console.log( soi + cc.debug( "--" ) + cc.bright( "log-files" ) + cc.sunny( "=" ) + cc.note( "value" ) + cc.debug( "..............." ) + cc.notice( "Maximum number of log files for log rotation." ) );
-            console.log( soi + cc.debug( "--" ) + cc.bright( "gathered" ) + cc.debug( "......................" ) + cc.notice( "Print details of gathering data from command line arguments. " ) + cc.debug( "Default mode." ) );
+            console.log( soi + cc.debug( "--" ) + cc.bright( "gathered" ) + cc.debug( "......................" ) + cc.notice( "Print details of gathering data from command line arguments. " ) + cc.debug( "Default mode" ) + cc.notice( "." ) );
             console.log( soi + cc.debug( "--" ) + cc.bright( "no-gathered" ) + cc.debug( "..................." ) + cc.notice( "Do not print details of gathering data from command line arguments." ) );
+            console.log( soi + cc.debug( "--" ) + cc.bright( "expose-security-info" ) + cc.debug( ".........." ) + cc.notice( "Expose security-related values in log output." ) + " " + cc.debug( "This mode is needed for debugging purposes only" ) + cc.notice( "." ) );
+            console.log( soi + cc.debug( "--" ) + cc.bright( "no-expose-security-info" ) + cc.debug( "......." ) + cc.notice( "Do not expose security-related values in log output." ) + " " + cc.debug( "Default mode" ) + cc.notice( "." ) );
             //
             process.exit( 0 );
         }
@@ -1095,6 +1097,14 @@ function parse( joExternalHandlers, argv ) {
             imaState.isPrintGathered = false;
             continue;
         }
+        if( joArg.name == "expose-security-info" ) {
+            imaState.isPrintSecurityValues = true;
+            continue;
+        }
+        if( joArg.name == "no-expose-security-info" ) {
+            imaState.isPrintSecurityValues = false;
+            continue;
+        }
         if( joArg.name == "log" ) {
             owaspUtils.verifyArgumentWithNonEmptyValue( joArg );
             imaState.strLogFilePath = "" + joArg.value;
@@ -1258,7 +1268,7 @@ function getWeb3FromURL( strURL ) {
 }
 
 async function async_check_url_at_startup( u, name ) {
-    const details = log.createMemoryStream();
+    const details = log.createMemoryStream( true );
     const nTimeoutMilliseconds = 10 * 1000;
     try {
         details.write( cc.debug( "Will check URL " ) + cc.u( u ) + cc.debug( " connectivity for " ) + cc.info( name ) + cc.debug( " at start-up..." ) + "\n" );
@@ -1989,6 +1999,7 @@ function ima_common_init() {
 
     if( IMA.verbose_get() > IMA.RV_VERBOSE.information || imaState.bShowConfigMode ) {
         const isPrintGathered = imaState.isPrintGathered ? true : false;
+        const isPrintSecurityValues = imaState.isPrintSecurityValues ? true : false;
         if( isPrintGathered ) {
             print_about( true );
             log.write( cc.attention( "IMA AGENT" ) + cc.normal( " is using " ) + cc.bright( "Web3" ) + cc.normal( " version " ) + cc.sunny( IMA.w3mod.version ) + "\n" );
@@ -1999,31 +2010,31 @@ function ima_common_init() {
         ensure_have_value( "Verbose level", IMA.VERBOSE[IMA.verbose_get()], false, isPrintGathered, null, ( x ) => {
             return cc.sunny( x );
         } );
-        ensure_have_value( "Main-net URL", imaState.strURL_main_net, false, isPrintGathered, null, ( x ) => {
+        ensure_have_value( "Main-net URL", imaState.strURL_main_net, false, isPrintGathered && isPrintSecurityValues, null, ( x ) => {
             return cc.u( x );
         } );
-        ensure_have_value( "S-chain URL", imaState.strURL_s_chain, false, isPrintGathered, null, ( x ) => {
+        ensure_have_value( "S-chain URL", imaState.strURL_s_chain, false, isPrintGathered && isPrintSecurityValues, null, ( x ) => {
             return cc.u( x );
         } );
-        ensure_have_value( "S<->S Target S-chain URL", imaState.strURL_t_chain, false, isPrintGathered, null, ( x ) => {
+        ensure_have_value( "S<->S Target S-chain URL", imaState.strURL_t_chain, false, isPrintGathered && isPrintSecurityValues, null, ( x ) => {
             return cc.u( x );
         } );
-        ensure_have_value( "Main-net Ethereum network name", imaState.strChainName_main_net, false, isPrintGathered, null, ( x ) => {
+        ensure_have_value( "Main-net Ethereum network name", imaState.strChainName_main_net, false, isPrintGathered && isPrintSecurityValues, null, ( x ) => {
             return cc.note( x );
         } );
-        ensure_have_value( "S-Chain Ethereum network name", imaState.strChainName_s_chain, false, isPrintGathered, null, ( x ) => {
+        ensure_have_value( "S-Chain Ethereum network name", imaState.strChainName_s_chain, false, isPrintGathered && isPrintSecurityValues, null, ( x ) => {
             return cc.note( x );
         } );
-        ensure_have_value( "S<->S Target S-Chain Ethereum network name", imaState.strChainName_t_chain, false, isPrintGathered, null, ( x ) => {
+        ensure_have_value( "S<->S Target S-Chain Ethereum network name", imaState.strChainName_t_chain, false, isPrintGathered && isPrintSecurityValues, null, ( x ) => {
             return cc.note( x );
         } );
-        ensure_have_value( "Main-net Ethereum chain ID", imaState.cid_main_net, false, isPrintGathered, null, ( x ) => {
+        ensure_have_value( "Main-net Ethereum chain ID", imaState.cid_main_net, false, isPrintGathered && isPrintSecurityValues, null, ( x ) => {
             return cc.note( x );
         } );
-        ensure_have_value( "S-Chain Ethereum chain ID", imaState.cid_s_chain, false, isPrintGathered, null, ( x ) => {
+        ensure_have_value( "S-Chain Ethereum chain ID", imaState.cid_s_chain, false, isPrintGathered && isPrintSecurityValues, null, ( x ) => {
             return cc.note( x );
         } );
-        ensure_have_value( "S<->S Target S-Chain Ethereum chain ID", imaState.cid_t_chain, false, isPrintGathered, null, ( x ) => {
+        ensure_have_value( "S<->S Target S-Chain Ethereum chain ID", imaState.cid_t_chain, false, isPrintGathered && isPrintSecurityValues, null, ( x ) => {
             return cc.note( x );
         } );
         ensure_have_value( "Skale Manager ABI JSON file path", imaState.strPathAbiJson_skale_manager, false, isPrintGathered, null, ( x ) => {
@@ -2041,33 +2052,33 @@ function ima_common_init() {
         //
         //
         try {
-            ensure_have_value( "Main-net user account address", imaState.joAccount_main_net.address( imaState.w3_main_net ), false, isPrintGathered );
+            ensure_have_value( "Main-net user account address", imaState.joAccount_main_net.address( imaState.w3_main_net ), false, isPrintGathered && isPrintSecurityValues );
         } catch ( err ) {}
         try {
-            ensure_have_value( "S-chain user account address", imaState.joAccount_s_chain.address( imaState.w3_s_chain ), false, isPrintGathered );
+            ensure_have_value( "S-chain user account address", imaState.joAccount_s_chain.address( imaState.w3_s_chain ), false, isPrintGathered && isPrintSecurityValues );
         } catch ( err ) {}
         try {
             ensure_have_value( "S<->S Target S-chain user account address", imaState.joAccount_t_chain.address( imaState.w3_t_chain ), false, isPrintGathered );
         } catch ( err ) {}
         //
-        // ensure_have_value( "Private key for main-net user account address", imaState.joAccount_main_net.privateKey, false, isPrintGathered, null, ( x ) => {
+        // ensure_have_value( "Private key for main-net user account address", imaState.joAccount_main_net.privateKey, false, isPrintGathered && isPrintSecurityValues, null, ( x ) => {
         //     return cc.attention( x );
         // } );
-        // ensure_have_value( "Private key for S-Chain user account address", imaState.joAccount_s_chain.privateKey, false, isPrintGathered, null, ( x ) => {
+        // ensure_have_value( "Private key for S-Chain user account address", imaState.joAccount_s_chain.privateKey, false, isPrintGathered && isPrintSecurityValues, null, ( x ) => {
         //     return cc.attention( x );
         // } );
-        // ensure_have_value( "Private key for S<->S Target S-Chain user account address", imaState.joAccount_t_chain.privateKey, false, isPrintGathered, null, ( x ) => {
+        // ensure_have_value( "Private key for S<->S Target S-Chain user account address", imaState.joAccount_t_chain.privateKey, false, isPrintGathered && isPrintSecurityValues, null, ( x ) => {
         //     return cc.attention( x );
         // } );
         //
         try {
-            ensure_have_chain_credentials( "Main Net", imaState.joAccount_main_net, false, isPrintGathered );
+            ensure_have_chain_credentials( "Main Net", imaState.joAccount_main_net, false, isPrintGathered && isPrintSecurityValues );
         } catch ( err ) {}
         try {
-            ensure_have_chain_credentials( "S-Chain", imaState.joAccount_s_chain, false, isPrintGathered );
+            ensure_have_chain_credentials( "S-Chain", imaState.joAccount_s_chain, false, isPrintGathered && isPrintSecurityValues );
         } catch ( err ) {}
         try {
-            ensure_have_chain_credentials( "S<->S Target S-Chain", imaState.joAccount_t_chain, false, isPrintGathered );
+            ensure_have_chain_credentials( "S<->S Target S-Chain", imaState.joAccount_t_chain, false, isPrintGathered && isPrintSecurityValues );
         } catch ( err ) {}
         //
         //
@@ -2133,7 +2144,7 @@ function ima_common_init() {
             return cc.info( x );
         } );
 
-        ensure_have_value( "Automatic exit(seconds)", imaState.nAutoExitAfterSeconds, false, isPrintGathered );
+        ensure_have_value( "Automatic exit(seconds)", imaState.nAutoExitAfterSeconds, false, isPrintGathered && isPrintSecurityValues );
 
         if( imaState.strLogFilePath.length > 0 ) {
             ensure_have_value( "Log file path", imaState.strLogFilePath, false, isPrintGathered, null, ( x ) => {
diff --git a/agent/main.js b/agent/main.js
index 1f3c13916..d1f9bc425 100644
--- a/agent/main.js
+++ b/agent/main.js
@@ -56,6 +56,7 @@ global.imaState = {
     "nLogMaxSizeBeforeRotation": -1,
     "nLogMaxFilesCount": -1,
     "isPrintGathered": true,
+    "isPrintSecurityValues": false,
 
     "bIsNeededCommonInit": true,
     "bSignMessages": false, // use BLS message signing, turned on with --sign-messages
@@ -311,7 +312,7 @@ const fnInitActionSkaleNetworkScanForS2S = function() {
                 console.log( cc.fatal( "CRITICAL ERROR:" ) + cc.error( " missing Skale Manager ABI, please specify " ) + cc.info( "abi-skale-manager" ) );
                 process.exit( 153 );
             }
-            log.write( strLogPrefix + cc.normal( "Downloading SKALE network information " ) + cc.normal( "..." ) + "\n" ); // just print value
+            log.write( strLogPrefix + cc.debug( "Downloading SKALE network information..." ) + "\n" ); // just print value
             const opts = {
                 imaState: imaState,
                 "details": log,
@@ -337,6 +338,7 @@ const fnInitActionSkaleNetworkScanForS2S = function() {
                 addressFrom,
                 opts
             );
+            log.write( strLogPrefix + cc.success( "Done, did started periodic S-Chains caching." ) + "\n" );
             return true;
         }
     } );
@@ -1452,7 +1454,7 @@ imaCLI.parse( {
                     console.log( cc.fatal( "CRITICAL ERROR:" ) + cc.error( " missing Skale Manager ABI, please specify " ) + cc.info( "abi-skale-manager" ) );
                     process.exit( 160 );
                 }
-                log.write( strLogPrefix + cc.normal( "Downloading SKALE network information " ) + cc.normal( "..." ) + "\n" ); // just print value
+                log.write( strLogPrefix + cc.debug( "Downloading SKALE network information..." ) + "\n" ); // just print value
                 const opts = {
                     imaState: imaState,
                     "details": log,
@@ -1475,7 +1477,7 @@ imaCLI.parse( {
                     console.log( cc.fatal( "CRITICAL ERROR:" ) + cc.error( " missing Skale Manager ABI, please specify " ) + cc.info( "abi-skale-manager" ) );
                     process.exit( 161 );
                 }
-                log.write( strLogPrefix + cc.normal( "Downloading SKALE network information " ) + cc.normal( "..." ) + "\n" ); // just print value
+                log.write( strLogPrefix + cc.debug( "Downloading SKALE network information..." ) + "\n" ); // just print value
 
                 const opts = {
                     imaState: imaState,
diff --git a/agent/run.sh b/agent/run.sh
index 4149381b5..77646efc8 100644
--- a/agent/run.sh
+++ b/agent/run.sh
@@ -111,9 +111,10 @@ BASE_OPTIONS="--gas-price-multiplier=$GAS_PRICE_MULTIPLIER \
 --time-gap=$TIME_GAP \
 --monitoring-port=$MONITORING_PORT"
 
-echo "Base options:"
-echo "$BASE_OPTIONS"
+#echo "Base options:"
+#echo "$BASE_OPTIONS"
 
 echo "Running loop cmd..."
-echo "Going to run: node $DIR/main.js --loop $BASE_OPTIONS"
+#echo "Going to run: node $DIR/main.js --loop $BASE_OPTIONS"
+echo "Going to run: node $DIR/main.js --loop ... ... ..."
 node "$DIR/main.js" --loop $BASE_OPTIONS
diff --git a/npms/skale-ima/index.js b/npms/skale-ima/index.js
index 022988471..6740ce23f 100644
--- a/npms/skale-ima/index.js
+++ b/npms/skale-ima/index.js
@@ -1252,8 +1252,8 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc
         /*
         details.write(
             cc.debug( "Will sign with Transaction Manager wallet, transaction is " ) + cc.j( tx ) +
-            cc.debug( ", raw transaction is " ) + cc.j( rawTx ) + "\n" +
-            cc.debug( " using account " ) + cc.j( joAccount ) + "\n"
+            cc.debug( ", raw transaction is " ) + cc.j( rawTx ) + "\n"
+            // + cc.debug( " using account " ) + cc.j( joAccount ) + "\n"
         );
         let rpcCallOpts = null;
         if( "strPathSslKey" in joAccount && typeof joAccount.strPathSslKey == "string" && joAccount.strPathSslKey.length > 0 &&
@@ -1309,8 +1309,9 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc
         */
         strMsg =
             cc.debug( "Will sign with Transaction Manager wallet, transaction is " ) + cc.j( tx ) +
-            cc.debug( ", raw transaction is " ) + cc.j( rawTx ) + "\n" +
-            cc.debug( " using account " ) + cc.j( joAccount );
+            cc.debug( ", raw transaction is " ) + cc.j( rawTx )
+            // + "\n" + cc.debug( " using account " ) + cc.j( joAccount )
+        ;
         details.write( strPrefixDetails + strMsg + "\n" );
         log.write( strPrefixLog + strMsg + "\n" );
         const txAdjusted = JSON.parse( JSON.stringify( rawTx ) ); // tx // rawTx
@@ -1341,8 +1342,8 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc
     case "sgx": {
         details.write(
             cc.debug( "Will sign with SGX wallet, transaction is " ) + cc.j( tx ) +
-            cc.debug( ", raw transaction is " ) + cc.j( rawTx ) + "\n" +
-            cc.debug( " using account " ) + cc.j( joAccount ) + "\n"
+            cc.debug( ", raw transaction is " ) + cc.j( rawTx ) + "\n"
+            // + cc.debug( " using account " ) + cc.j( joAccount ) + "\n"
         );
         let rpcCallOpts = null;
         if( "strPathSslKey" in joAccount && typeof joAccount.strPathSslKey == "string" && joAccount.strPathSslKey.length > 0 &&
@@ -1373,7 +1374,7 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc
                     "base": 16 // 10
                 }
             };
-            details.write( cc.debug( "Calling SGX to sign using ECDSA key with: " ) + cc.j( joIn ) + "\n" );
+            details.write( cc.debug( "Calling SGX to sign using ECDSA key with " ) + cc.info( joIn.method ) + cc.debug( "..." ) + "\n" );
             await joCall.call( joIn, async function( joIn, joOut, err ) {
                 if( err ) {
                     const s = cc.fatal( "CRITICAL TRANSACTION SIGNING ERROR:" ) + cc.error( " JSON RPC call to SGX wallet failed, error: " ) + cc.warning( err ) + "\n";
@@ -1425,16 +1426,17 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc
     case "direct": {
         details.write(
             cc.debug( "Will sign with private key, transaction is " ) + cc.notice( JSON.stringify( tx ) ) +
-            cc.debug( ", raw transaction is " ) + cc.notice( JSON.stringify( rawTx ) ) + "\n" +
-            cc.debug( " using account " ) + cc.j( joAccount ) + "\n"
+            cc.debug( ", raw transaction is " ) + cc.notice( JSON.stringify( rawTx ) ) + "\n"
+            // + cc.debug( " using account " ) + cc.j( joAccount ) + "\n"
         );
         const key = Buffer.from( joAccount.privateKey, "hex" ); // convert private key to buffer
         tx.sign( key ); // arg is privateKey as buffer
     } break;
     default: {
         const s = cc.fatal( "CRITICAL TRANSACTION SIGNING ERROR:" ) +
-            cc.error( " bad credentials information specified, no explicit SGX and no explicit private key found, account is: " ) +
-            cc.j( joAccount ) + "\n";
+            cc.error( " bad credentials information specified, no explicit SGX and no explicit private key found" ) +
+            // + cc.error( ", account is: " ) + cc.j( joAccount )
+            "\n";
         details.write( s );
         log.write( s );
         if( isExitIfEmpty ) {
@@ -4721,7 +4723,6 @@ async function async_pending_tx_start( details, w3, w3_opposite, chain_id, chain
                     }
                 } );
             } );
-
         }
     } catch ( err ) {
         const s =
@@ -5021,7 +5022,7 @@ async function do_transfer(
     const strGatheredDetailsNameColored = "" + cc.bright( strDirection ) + cc.debug( "-" ) +
         cc.info( "do_transfer-A-" ) + cc.debug( "-" ) + cc.notice( "#" ) + cc.note( nTransferLoopCounter ) +
         cc.debug( "-" ) + cc.notice( chain_id_src ) + cc.debug( "-->" ) + cc.notice( chain_id_dst );
-    const details = log.createMemoryStream();
+    const details = log.createMemoryStream( true );
     const jarrReceipts = [];
     let bErrorInSigningMessages = false;
     await init_ima_state_file( details, w3_src, strDirection, optsStateFile );
@@ -5609,7 +5610,7 @@ async function do_transfer(
                 cc.info( nIdxCurrentMsgBlockStart ) + cc.info( jarrMessages.length ) +
                 cc.debug( " message(s) to process: " ) + cc.j( jarrMessages ) +
                 "\n" );
-            let detailsB = log.createMemoryStream();
+            let detailsB = log.createMemoryStream( true );
             const strGatheredDetailsName = "" + strDirection + "-" +
                 "do_transfer-B-#" + nTransferLoopCounter +
                 "-" + chain_id_src + "-->" + chain_id_dst;
@@ -5745,7 +5746,6 @@ async function do_transfer(
                             joReceipt = await safe_send_signed_transaction( detailsB, w3_dst, serializedTx_postIncomingMessages, strActionName, strLogPrefix );
                         }
                         detailsB.write( strLogPrefix + cc.success( "Result receipt: " ) + cc.j( joReceipt ) + "\n" );
-
                         if( joReceipt && typeof joReceipt == "object" && "gasUsed" in joReceipt ) {
                             jarrReceipts.push( {
                                 "description": "do_transfer/postIncomingMessages()",
diff --git a/npms/skale-log/log.js b/npms/skale-log/log.js
index 0d2a1eb37..115677532 100644
--- a/npms/skale-log/log.js
+++ b/npms/skale-log/log.js
@@ -37,22 +37,27 @@ function n2s( n, sz ) {
     return s;
 }
 
-function generateTimestamp() {
-    const ts = new Date();
+function generate_timestamp_string( ts, isColorized ) {
+    isColorized = ( typeof isColorized == "undefined" ) ? true : ( isColorized ? true : false );
+    ts = ( ts instanceof Date ) ? ts : new Date();
+    const cc_date = function( x ) { return isColorized ? cc.date( x ) : x; };
+    const cc_time = function( x ) { return isColorized ? cc.time( x ) : x; };
+    const cc_frac_time = function( x ) { return isColorized ? cc.frac_time( x ) : x; };
+    const cc_bright = function( x ) { return isColorized ? cc.bright( x ) : x; };
     const s =
-	"" + cc.date( n2s( ts.getUTCFullYear(), 4 ) ) +
-	cc.bright( "-" ) + cc.date( n2s( ts.getUTCMonth() + 1, 2 ) ) +
-	cc.bright( "-" ) + cc.date( n2s( ts.getUTCDate(), 2 ) ) +
-	" " + cc.time( n2s( ts.getUTCHours(), 2 ) ) +
-	cc.bright( ":" ) + cc.time( n2s( ts.getUTCMinutes(), 2 ) ) +
-	cc.bright( ":" ) + cc.time( n2s( ts.getUTCSeconds(), 2 ) ) +
-	cc.bright( "." ) + cc.frac_time( n2s( ts.getUTCMilliseconds(), 3 ) )
-	;
+        "" + cc_date( n2s( ts.getUTCFullYear(), 4 ) ) +
+        cc_bright( "-" ) + cc_date( n2s( ts.getUTCMonth() + 1, 2 ) ) +
+        cc_bright( "-" ) + cc_date( n2s( ts.getUTCDate(), 2 ) ) +
+        " " + cc_time( n2s( ts.getUTCHours(), 2 ) ) +
+        cc_bright( ":" ) + cc_time( n2s( ts.getUTCMinutes(), 2 ) ) +
+        cc_bright( ":" ) + cc_time( n2s( ts.getUTCSeconds(), 2 ) ) +
+        cc_bright( "." ) + cc_frac_time( n2s( ts.getUTCMilliseconds(), 3 ) )
+        ;
     return s;
 }
 
-function generateTimestampPrefix() {
-    return generateTimestamp() + cc.bright( ":" ) + " ";
+function generate_timestamp_prefix( ts, isColorized ) {
+    return generate_timestamp_string( ts, isColorized ) + cc.bright( ":" ) + " ";
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -134,15 +139,19 @@ function insertStandardOutputStream() {
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-function createMemoryOutputStream() {
+function createMemoryOutputStream( isAutoAddTimestamps ) {
     try {
         const objEntry = {
             strPath: "memory",
             nMaxSizeBeforeRotation: -1,
             nMaxFilesCount: -1,
             strAccumulatedLogText: "",
+            isWithTimestamps: ( isAutoAddTimestamps || ( typeof isAutoAddTimestamps == "undefined" ) ) ? true : false,
             write: function( s ) {
-                this.strAccumulatedLogText += s;
+                let strPrefix = "";
+                if( this.isWithTimestamps )
+                    strPrefix = generate_timestamp_prefix( null, true );
+                this.strAccumulatedLogText += strPrefix + s;
             },
             clear: function() { this.strAccumulatedLogText = ""; },
             close: function() { this.clear(); },
@@ -251,12 +260,13 @@ function insertFileOutput( strFilePath, nMaxSizeBeforeRotation, nMaxFilesCount )
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 module.exports = {
+    generate_timestamp_string: generate_timestamp_string,
+    generate_timestamp_prefix: generate_timestamp_prefix,
     cc: cc,
-	  write: function() {
-        let s = generateTimestampPrefix(); let i = 0; let cnt = 0;
+    write: function() {
+        let s = generate_timestamp_prefix( null, true ); let i = 0; let cnt = 0;
         try {
-            cnt = arguments.length;
-            for( i = 0; i < cnt; ++i ) {
+            for( i = 0; i < arguments.length; ++i ) {
                 try {
                     s += arguments[i];
                 } catch ( err ) {
@@ -287,8 +297,8 @@ module.exports = {
     addMemory: function() {
         return insertMemoryOutputStream();
     },
-    createMemoryStream: function() {
-        return createMemoryOutputStream();
+    createMemoryStream: function( isAutoAddTimestamps ) {
+        return createMemoryOutputStream( isAutoAddTimestamps );
     },
     add: function( strFilePath, nMaxSizeBeforeRotation, nMaxFilesCount ) {
         return insertFileOutput(
diff --git a/proxy/DEPLOYED b/proxy/DEPLOYED
index 52f2c31b1..a939f53a1 100644
--- a/proxy/DEPLOYED
+++ b/proxy/DEPLOYED
@@ -1,1 +1,1 @@
-1.3.0-stable.0
\ No newline at end of file
+1.3.2-stable.1
\ No newline at end of file
diff --git a/proxy/migrations/deploySkaleManagerComponents.ts b/proxy/migrations/deploySkaleManagerComponents.ts
index 680e49e2f..943d947da 100644
--- a/proxy/migrations/deploySkaleManagerComponents.ts
+++ b/proxy/migrations/deploySkaleManagerComponents.ts
@@ -29,7 +29,7 @@ import { getAbi } from './tools/abi';
 import { Manifest, hashBytecode } from "@openzeppelin/upgrades-core";
 import { KeyStorageMock } from '../typechain/KeyStorageMock';
 import { Wallet } from 'ethers';
-import { getPublicKey, stringValue } from '../test/utils/helper';
+import { getPublicKey } from '../test/utils/helper';
 
 export function getContractKeyInAbiFile(contract: string) {
     return contract.replace(/([a-z0-9])(?=[A-Z])/g, '$1_').toLowerCase();
@@ -75,6 +75,16 @@ async function main() {
         process.exit( 126 );
     }
 
+    if ( process.env.PRIVATE_KEY_FOR_ETHEREUM === undefined || process.env.PRIVATE_KEY_FOR_ETHEREUM === "" ) {
+        console.log( "Please set PRIVATE_KEY_FOR_ETHEREUM to .env file" );
+        process.exit( 127 );
+    }
+
+    if ( process.env.PRIVATE_KEY_FOR_SCHAIN === undefined || process.env.PRIVATE_KEY_FOR_SCHAIN === "" ) {
+        console.log( "Please set PRIVATE_KEY_FOR_ETHEREUM to .env file" );
+        process.exit( 128 );
+    }
+
     const schainName = process.env.CHAIN_NAME_SCHAIN;
 
     console.log("Deploy ContractManager");
@@ -132,8 +142,8 @@ async function main() {
     console.log("Set KeyStorage", keyStorage.address, "to ContractManager", contractManager.address, "\n");
     await contractManager.setContractsAddress( "Nodes", nodes.address );
     console.log("Set Nodes", nodes.address, "to ContractManager", contractManager.address, "\n");
-    const nodeAddress1 = new Wallet(stringValue(process.env.PRIVATE_KEY_FOR_ETHEREUM)).connect(ethers.provider);
-    const nodeAddress2 = new Wallet(stringValue(process.env.PRIVATE_KEY_FOR_SCHAIN)).connect(ethers.provider);
+    const nodeAddress1 = new Wallet(process.env.PRIVATE_KEY_FOR_ETHEREUM).connect(ethers.provider);
+    const nodeAddress2 = new Wallet(process.env.PRIVATE_KEY_FOR_SCHAIN).connect(ethers.provider);
     await owner.sendTransaction({to: nodeAddress1.address, value: ethers.utils.parseEther("1")});
     await owner.sendTransaction({to: nodeAddress2.address, value: ethers.utils.parseEther("1")});
 
@@ -161,7 +171,7 @@ async function main() {
     console.log("Create Node 1 with address", nodeAddress2.address, "\n");
     await schainsInternal.initializeSchain( schainName, owner.address, 1, 1 );
     console.log("Initialize Schain", schainName, "with address", owner.address, "\n");
-    await schainsInternal.connect(owner).addNodesToSchainsGroups(stringValue(ethers.utils.id(schainName)), [0, 1]);
+    await schainsInternal.connect(owner).addNodesToSchainsGroups(ethers.utils.id(schainName), [0, 1]);
     console.log("Add Nodes 0 and 1 to schain", schainName, "\n");
     const BLSPublicKey = {
         x: {
diff --git a/proxy/migrations/upgradeMainnet.ts b/proxy/migrations/upgradeMainnet.ts
index 3a63275b3..a9951d8c3 100644
--- a/proxy/migrations/upgradeMainnet.ts
+++ b/proxy/migrations/upgradeMainnet.ts
@@ -3,7 +3,7 @@ import { upgrade } from "./upgrade";
 
 async function main() {
     await upgrade(
-        "1.3.0",
+        "1.3.2",
         contracts,
         async (safeTransactions, abi) => undefined,
         async (safeTransactions, abi) => undefined,
diff --git a/proxy/migrations/upgradeSchain.ts b/proxy/migrations/upgradeSchain.ts
index f54d9a7f7..f787263dd 100644
--- a/proxy/migrations/upgradeSchain.ts
+++ b/proxy/migrations/upgradeSchain.ts
@@ -14,7 +14,7 @@ async function main() {
     const pathToManifest: string = stringValue(process.env.MANIFEST);
     await manifestSetup( pathToManifest );
     await upgrade(
-        "1.3.0",
+        "1.3.2",
         contracts,
         async (safeTransactions, abi) => {
             // deploying of new contracts


Test patch:
diff --git a/proxy/scripts/test_upgrade.sh b/proxy/scripts/test_upgrade.sh
index 5778acbd4..3945fbcc7 100644
--- a/proxy/scripts/test_upgrade.sh
+++ b/proxy/scripts/test_upgrade.sh
@@ -10,12 +10,15 @@ DEPLOYED_DIR=$GITHUB_WORKSPACE/deployed-proxy/
 
 git clone --branch "$DEPLOYED_TAG" "https://github.com/$GITHUB_REPOSITORY.git" "$DEPLOYED_DIR"
 
-npx ganache-cli --gasLimit 9000000 --quiet --allowUnlimitedContractSize &
+ACCOUNTS_FILENAME="$DEPLOYED_DIR/proxy/generatedAccounts.json"
+npx ganache-cli --gasLimit 9000000 --quiet --allowUnlimitedContractSize --account_keys_path "$ACCOUNTS_FILENAME" &
 
 cd "$DEPLOYED_DIR"
 yarn install
 cd proxy
-CHAIN_NAME_SCHAIN="Test" VERSION="$DEPLOYED_VERSION" npx hardhat run migrations/deploySkaleManagerComponents.ts --network localhost
+PRIVATE_KEY_FOR_ETHEREUM=$(cat "$ACCOUNTS_FILENAME" | jq -r  '.private_keys | to_entries | .[8].value')
+PRIVATE_KEY_FOR_SCHAIN=$(cat "$ACCOUNTS_FILENAME" | jq -r '.private_keys | to_entries | .[9].value')
+CHAIN_NAME_SCHAIN="Test" VERSION="$DEPLOYED_VERSION" PRIVATE_KEY_FOR_ETHEREUM="$PRIVATE_KEY_FOR_ETHEREUM" PRIVATE_KEY_FOR_SCHAIN="$PRIVATE_KEY_FOR_SCHAIN" npx hardhat run migrations/deploySkaleManagerComponents.ts --network localhost
 VERSION="$DEPLOYED_VERSION" npx hardhat run migrations/deployMainnet.ts --network localhost
 CHAIN_NAME_SCHAIN="Test" VERSION="$DEPLOYED_VERSION" npx hardhat run migrations/deploySchain.ts --network localhost
 cp "$GITHUB_WORKSPACE/proxy/migrations/generateManifest.ts" ./migrations/generateManifest.ts
diff --git a/test-tokens/yarn.lock b/test-tokens/yarn.lock
index c1d6ac2dd..00881be31 100644
--- a/test-tokens/yarn.lock
+++ b/test-tokens/yarn.lock
@@ -912,13 +912,6 @@ block-stream@*:
   dependencies:
     inherits "~2.0.0"
 
-block-stream@*:
-  version "0.0.9"
-  resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
-  integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=
-  dependencies:
-    inherits "~2.0.0"
-
 bluebird@^3.5.0:
   version "3.7.2"
   resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
@@ -3337,40 +3330,6 @@ node-pre-gyp@^0.11.0:
     semver "^5.3.0"
     tar "^4"
 
-node-gyp@3.x:
-  version "3.8.0"
-  resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c"
-  integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==
-  dependencies:
-    fstream "^1.0.0"
-    glob "^7.0.3"
-    graceful-fs "^4.1.2"
-    mkdirp "^0.5.0"
-    nopt "2 || 3"
-    npmlog "0 || 1 || 2 || 3 || 4"
-    osenv "0"
-    request "^2.87.0"
-    rimraf "2"
-    semver "~5.3.0"
-    tar "^2.0.0"
-    which "1"
-
-node-pre-gyp@^0.11.0:
-  version "0.11.0"
-  resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz#db1f33215272f692cd38f03238e3e9b47c5dd054"
-  integrity sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==
-  dependencies:
-    detect-libc "^1.0.2"
-    mkdirp "^0.5.1"
-    needle "^2.2.1"
-    nopt "^4.0.1"
-    npm-packlist "^1.1.6"
-    npmlog "^4.0.2"
-    rc "^1.2.7"
-    rimraf "^2.6.1"
-    semver "^5.3.0"
-    tar "^4"
-
 nofilter@^1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-1.0.4.tgz#78d6f4b6a613e7ced8b015cec534625f7667006e"
@@ -3680,11 +3639,6 @@ printj@~1.1.0:
   resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"
   integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==
 
-printj@~1.3.1:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/printj/-/printj-1.3.1.tgz#9af6b1d55647a1587ac44f4c1654a4b95b8e12cb"
-  integrity sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==
-
 process-nextick-args@~2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -4861,8 +4815,8 @@ web3-utils@1.5.3:
   integrity sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==
   dependencies:
     bn.js "^4.11.9"
+    eth-lib "0.2.8"
     ethereum-bloom-filters "^1.0.6"
-    ethereumjs-util "^7.1.0"
     ethjs-unit "0.1.6"
     number-to-bn "1.7.0"
     randombytes "^2.1.0"
@@ -4941,7 +4895,7 @@ which@1, which@1.3.1:
   dependencies:
     isexe "^2.0.0"
 
-wide-align@1.1.3, wide-align@^1.1.0:
+wide-align@1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
   integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==