Skip to content

Commit

Permalink
Merge pull request #1224 from DarkFlorist/gnosis-safe-simulate-with-g…
Browse files Browse the repository at this point in the history
…as-left-in-block

estimate gnosis safe message with all gas left in the block
  • Loading branch information
KillariDev authored Dec 12, 2024
2 parents 59fb4ee + 749d700 commit 513f462
Show file tree
Hide file tree
Showing 6 changed files with 285 additions and 71 deletions.
7 changes: 3 additions & 4 deletions app/ts/background/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { getActiveAddressEntry, getAddressBookEntriesForVisualiser, identifyAddr
import { getActiveAddress, sendPopupMessageToOpenWindows } from './backgroundUtils.js'
import { DistributiveOmit, assertNever, assertUnreachable, modifyObject } from '../utils/typescript.js'
import { EthereumClientService } from '../simulation/services/EthereumClientService.js'
import { appendTransaction, calculateRealizedEffectiveGasPrice, copySimulationState, fixNonceErrorsIfNeeded, getAddressToMakeRich, getBaseFeeAdjustedTransactions, getNonceFixedSimulatedTransactions, getTokenBalancesAfter, getWebsiteCreatedEthereumUnsignedTransactions, mockSignTransaction, setSimulationTransactionsAndSignedMessages, simulateEstimateGas } from '../simulation/services/SimulationModeEthereumClientService.js'
import { appendTransaction, calculateRealizedEffectiveGasPrice, copySimulationState, fixNonceErrorsIfNeeded, getAddressToMakeRich, getBaseFeeAdjustedTransactions, getNonceFixedSimulatedTransactions, getTokenBalancesAfter, getWebsiteCreatedEthereumUnsignedTransactions, mockSignTransaction, setSimulationTransactionsAndSignedMessages, simulationGasLeft } from '../simulation/services/SimulationModeEthereumClientService.js'
import { Semaphore } from '../utils/semaphore.js'
import { JsonRpcResponseError, handleUnexpectedError, isFailedToFetchError, isNewBlockAbort, printError } from '../utils/errors.js'
import { formSimulatedAndVisualizedTransaction } from '../components/formVisualizerResults.js'
Expand Down Expand Up @@ -102,7 +102,7 @@ export const simulateGovernanceContractExecution = async (pendingTransaction: Pe

if (tokenBalancesAfter[0] === undefined) return returnError('Could not compute token balances')

const governanceContractSimulationState: SimulationState = {
const governanceContractSimulationState: SimulationState = {
addressToMakeRich: undefined,
simulatedTransactions: [{
preSimulationTransaction: {
Expand Down Expand Up @@ -145,8 +145,7 @@ export const simulateGnosisSafeMetaTransaction = async (gnosisSafeMessage: Visua
nonce: 0n,
chainId: ethereumClientService.getChainId(),
}
const gasLimit = gnosisSafeMessage.message.message.baseGas !== 0n ? { gas: gnosisSafeMessage.message.message.baseGas } : await simulateEstimateGas(ethereumClientService, undefined, simulationState, transactionWithoutGas)
if ('error' in gasLimit) return returnError(gasLimit.error.message)
const gasLimit = gnosisSafeMessage.message.message.baseGas !== 0n ? { gas: gnosisSafeMessage.message.message.baseGas } : { gas: simulationGasLeft(simulationState, await ethereumClientService.getBlock(undefined)) }
const transaction = { ...transactionWithoutGas, gas: gasLimit.gas }
const metaTransaction: WebsiteCreatedEthereumUnsignedTransaction = {
website: gnosisSafeMessage.website,
Expand Down
3 changes: 2 additions & 1 deletion app/ts/simulation/compoundGovernanceFaking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ export const simulateCompoundGovernanceExecution = async (ethereumClientService:
]
const parentBlock = await ethereumClientService.getBlock(undefined)
if (parentBlock === null) throw new Error('The latest block is null')
const governanceContractCalls = (await ethereumClientService.simulateTransactionsAndSignatures(calls, [], parentBlock.number, undefined)).calls
const governanceContractCalls = (await ethereumClientService.simulateTransactionsAndSignatures([calls], [], parentBlock.number, undefined))[0]?.calls
if (governanceContractCalls === undefined) throw new Error('simulateTransactionsAndSignatures returned zero length aray')
for (const call of governanceContractCalls) {
if (call.status !== 'success') throw new Error('Failed to retrieve governance contracts information')
}
Expand Down
43 changes: 24 additions & 19 deletions app/ts/simulation/services/EthereumClientService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,12 @@ export class EthereumClientService {
return EthSimulateV1Result.parse(unvalidatedResult)
}

public readonly simulateTransactionsAndSignatures = async (transactions: readonly OptionalEthereumUnsignedTransaction[], signatures: readonly SignatureWithFakeSignerAddress[], blockNumber: bigint, requestAbortController: AbortController | undefined, extraAccountOverrides: StateOverrides = {}) => {
const transactionsWithRemoveZeroPricedOnes = transactions.map((transaction) => {
public readonly simulateTransactionsAndSignatures = async (transactionsInBlocks: readonly OptionalEthereumUnsignedTransaction[][], signatures: readonly SignatureWithFakeSignerAddress[], blockNumber: bigint, requestAbortController: AbortController | undefined, extraAccountOverrides: StateOverrides = {}) => {
const transactionsWithRemoveZeroPricedOnes = transactionsInBlocks.map((block) => block.map((transaction) => {
if (transaction.type !== '1559') return transaction
const { maxFeePerGas, ...transactionWithoutMaxFee } = transaction
return { ...transactionWithoutMaxFee, ...maxFeePerGas === 0n ? {} : { maxFeePerGas } }
})
}))
const ecRecoverMovedToAddress = 0x123456n
const ecRecoverAddress = 1n
const parentBlock = await this.getBlock(requestAbortController, blockNumber)
Expand All @@ -233,16 +233,22 @@ export class EthereumClientService {
return acc
}, {} as { [key: string]: bigint } )

const query = [{
calls: transactionsWithRemoveZeroPricedOnes,
blockOverride: {
number: parentBlock.number + 1n,
prevRandao: 0x1n,
time: new Date(parentBlock.timestamp.getTime() + 12 * 1000),
gasLimit: parentBlock.gasLimit,
feeRecipient: parentBlock.miner,
baseFeePerGas: parentBlock.baseFeePerGas === undefined ? 15000000n : parentBlock.baseFeePerGas
},
const getBlockOverrides = (index: number) => ({
number: parentBlock.number + 1n + BigInt(index),
prevRandao: 0x1n,
time: new Date(parentBlock.timestamp.getTime() + (index + 1) * 12 * 1000),
gasLimit: parentBlock.gasLimit,
feeRecipient: parentBlock.miner,
baseFeePerGas: parentBlock.baseFeePerGas === undefined ? 15000000n : parentBlock.baseFeePerGas
})

const [firstBlocksTransactions, ...restofTheBlocks] = transactionsWithRemoveZeroPricedOnes
if (firstBlocksTransactions === undefined) throw new Error('No blocks specified for simulateTransactionsAndSignatures')

// add stateOverrides only to the first block (ecrecover overrides, make me rich and such)
const firstBlocksCalls = {
calls: firstBlocksTransactions,
blockOverride: getBlockOverrides(0),
stateOverrides: {
...signatures.length > 0 ? {
[addressString(ecRecoverAddress)]: {
Expand All @@ -253,12 +259,11 @@ export class EthereumClientService {
} : {},
...extraAccountOverrides,
}
}]
const ethSimulateResults = await this.ethSimulateV1(query, parentBlock.number, requestAbortController)
if (ethSimulateResults.length !== 1) throw new Error('Ran Eth Simulate for one block but did not get one block')
const singleMulticalResult = ethSimulateResults[0]
if (singleMulticalResult === undefined) throw new Error('Eth Simualte result was undefined')
return singleMulticalResult
}
const blockStateCalls = [firstBlocksCalls, ...restofTheBlocks.map((calls, index) => ({ calls, blockOverride: getBlockOverrides(index + 1) }))]
const ethSimulateResults = await this.ethSimulateV1(blockStateCalls, parentBlock.number, requestAbortController)
if (ethSimulateResults.length !== transactionsWithRemoveZeroPricedOnes.length) throw new Error(`Ran Eth Simulate for ${ transactionsWithRemoveZeroPricedOnes.length } blocks but got ${ ethSimulateResults.length } blocks`)
return ethSimulateResults
}

public readonly web3ClientVersion = async (requestAbortController: AbortController | undefined) => {
Expand Down
Loading

0 comments on commit 513f462

Please sign in to comment.