Environment
We are trying to execute admin actions on our contracts using a Gnosis Safe created in Defender.
Details
We are using a Gnosis Safe contract created with Defender to administer our contracts. There is one administrative function in particular whose function signature includes a struct with an array member. I have tried to create a proposal to call this function with our admin account, but I cannot specify that argument because it contains a nested array. My next thought was to submit a similar proposal using the Defender Admin API, but from what I can tell, that API also restricts function arguments to non-nested types.
I'm considering a few options at the moment:
- Change the interface to this contract to no longer require nested types as input. This is doable but it would end up increasing the complexity of the contract and/or increasing the gas cost of its more common operations.
- A specific form of #1 above: change the argument to simply be a single
bytes
argument, and have the contract explicitly decode it in Solidity code. This would allow us to keep the remainder of the contact identical, at the expense of making calls to this function more difficult to interpret for humans. - Have these operations be signed outside of defender and submitted directly to the Gnosis Safe contract. We could certainly do this, but we would like to keep all of our operations within Defender as much as possible, and some of the signers will be less technical members of the team, so we'd like to make the process as simple as possible for them.
- It would be nice to be able to propose arbitrary transaction data for the Gnosis Safe to execute (basically, most arguments of the
execTransaction
function aside from the signatures), and have proposals created in Defender for those. However, it appears that this functionality is not included in the Admin API. I can understand why this is, as such transactions would be difficult to display and interpret for auditing purposes, without support for these more complex ABI types.
Of these, options 1/2 seem like the most viable, so that's my current plan of action, but I was curious whether anybody else has encountered similar scenarios in the past, and how you did/would handle them.
Thanks in advance for everyone's help!
Brendon
Code to reproduce
struct Foo {
address x;
bytes y;
}struct Bar {
// this is an array but renders as a checkbox in the forums
Foo foos;
}function useBar(Bar calldata bar) external {
// do some stuff
}
Try to propose a call to the function useBar
in Defender.