In our application, we often order ECR20 token transactions between safe wallets (in this case from one so-called Hot Wallet to another) on the Base network.
There are times when some transactions end with a GS026 error.
First one with success: https://basescan.org/tx/0x34190b0c29a84caeebdf704d0643b2229d287d7146a909db7afa798360d0887f
and immediatelly after https://basescan.org/tx/0xc1b83c9de94b44a1ccf37d3473406a6fd8d0ddfa5d67f3dc6e972afbd8b419e5
I noticed that they have the same block number, and only the first one was successful. However, the error also occurred for a single transaction over the longer term:
https://basescan.org/tx/0xdf10b985a893d80b67820f27d7769f4de66217896f91d5c56832936a7ceb3e2c
All transfers can be viewed here: https://basescan.org/address/0x7adc19694782c61132bcc38accaf1156d13c80d1
When several transfers (from Hot Wallet) are pending we group them and send them via MultiSend (max 10). Below is a small code, that we use to exec transaction (safe-eth-py==5.6.0):
def _create_multi_transfer(
self, from_address: str, transfers: List[Dict[str, Union[str, str, Decimal]]]
) -> Tuple[str, int]:
contract = get_erc20_contract(self.w3, self.CONTRACT_ADDRESS)
transactions = []
for transfer in transfers:
tx_opts = {'from': transfer['from_address']}
amount = self.w3.to_wei(transfer['amount'], 'ether')
tx = contract.functions.transfer(transfer['to_address'], amount).build_transaction(tx_opts)
ms_tx = MultiSendTx(operation=MultiSendOperation.CALL, value=0, to=self.CONTRACT_ADDRESS, data=tx['data'])
transactions.append(ms_tx)
multi_send = MultiSend(self.client)
data = multi_send.build_tx_data(transactions)
safe_tx = SafeTx(
ethereum_client=self.client,
safe_address=from_address,
to=multi_send.get_contract().address,
value=0,
data=data,
operation=SafeOperation.DELEGATE_CALL.value,
safe_tx_gas=1,
base_gas=0,
gas_price=0,
gas_token=NULL_ADDRESS,
)
safe_tx.sign(self.owner_private_key)
safe_tx.call()
hash, result = safe_tx.execute(self.owner_private_key)
return (hash.hex(), result['nonce'])
We tried:
- send by max 5, max 2 transfers,
- send one by one with
safe.build_multisig_tx()
, - increase
safe_tx_gas
, - specify increased
tx_gas_price
inexecute
,
but it didn't change anything. What else can we do on our side to minimize the occurrence of this problem?