-
Notifications
You must be signed in to change notification settings - Fork 903
-
Notifications
You must be signed in to change notification settings - Fork 903
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add simulateTransaction Function for Static Safe Transaction Simulation #788
Comments
We use state overrides on Tenderly, it should be also available in many ethereum nodes by default. Check out the stateDiff parameter here: https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-eth#eth-call. We use it to override the threshold to 1 + use a pre-approved signature for simulation |
I also think that there is a I think this already can be used with const safe = new ethers.Contract(
SAFE_ADDRESS,
["function simulate(address, bytes) view returns (bytes)"],
provider,
);
const accessor = new ethers.Contract(
// NOTE: address may vary per network, use `safe-deployments` package to get
// correct address.
"0x59AD6735bCd8152B84860Cb256dD9e96b85F69Da",
["function simulate(address, uint256, bytes, uint8) returns (uint256, bool, bytes)"],
provider,
);
const data = await safe.simulate(
accessor.target,
accessor.interface.encodeFunctionData("simulate", [tx.to, tx.value, tx.bytes, tx.operation]),
);
const [gasEstimate, success, returnData] = accessor.interface.decodeFunctionResult("simulate", data);
console.log({
gasEstimate,
success,
returnData,
}); Is there some additional feature that is missing here? |
I think the largest thing missing is that this simulation doesn't take into account the guard. EDIT: Well, I think it's possible to orchestrate multiple calls to different contracts to get a proper simulation, but yeah, I think the initial contract makes sense for more efficiency |
@nlordell I've actually already made a change to my PoC to simulate safe transactions using the method you described yesterday(see the @mmv08 the guard would be a pretty major part of getting a more accurate simulation, but I think it's worth adding a standard periphery contract that returns a gas estimate for the safeTx if y'all don't want to make any changes to core. If there isn't a periphery repo should I added the periphery contract here, say under |
What gas are you referring to? Safe transaction has two gas parameters: dataGas (everything outside of the internal call: signature verification, calldata gas costs, etc) and safeTxGas (internal call gas). Both can be estimated without any additional contracts. For the safeTxGas you can use the |
Safe team ran a relayer service before, you can check its code to see how it was done: https://github.com/5afe/safe-relay-service |
Weird, I just ran my snippet with the following modification and it worked: const data = await safe.simulate(
accessor.target,
accessor.interface.encodeFunctionData("simulate", [
tx.to,
ethers.parseEther("0.001"), // native transfer amount
tx.bytes,
tx.operation,
]),
); Does your Safe have enough funds for the native transfer? If not, I would expect it to revert. |
@nlordell I mean the slightly modified test cases that do |
@mmv08 ah yes, I didn't notice that |
@nlordell so took another look and the issue with the simulation success mismatch is not actually on safeTxs that transfer native, rather there's a mismatch with the simulation returning |
Ah OK - so you want the |
@nlordell more or less, |
Ok, I see. Yes this isn't directly supported at the moment, but can be "hacked" together with the current contracts (depending on the urgency for getting this to work). You could simulate a multisend which internally sets approved hashes for each owner, then call In general, not against adding an additional accessor to simulate this kind of thing (but it shouldn't change the original contracts IMO). |
Context / issue
IMU
Safe
contract does not currently have the functionality to simulate a safe transaction without requiring the threshold of owner signatures. This limitation makes it difficult to estimate gas usage or verify if a transaction would succeed without actually executing it. As a result, users and developers face challenges in performing pre-execution checks especially on chains not supported by Tenderly(not too sure how tenderly gets around this issue).Proposed solution
To address this issue, I propose adding a new function,
simulateTransaction
, to theSafe
contract. This function will allow for the simulation of transactions in a secure manner without requiring the threshold of owner signatures. To enable this the Safe will have todelegatecall
to a new contract that doesExecutor.execute
but immediately afterwards reverts to undo any state changes. This feature will enable users toeth_call
thesimulateTransaction
function to obtain transaction success status, gas used, and the transaction hash, enhancing the ability to perform pre-execution checks. This external contract should be immutably configured somewhere, perhaps singularly in theSafe
implementation contract.Alternatives
Do what Tenderly does, though not sure what they do and if it's generally achievable across EVM chains, if so, then ideally this simulation should be exposed via a function in the ts sdk.
The text was updated successfully, but these errors were encountered: