This changelog only contains changes starting from version 1.3.0
Solidity compiler: 0.7.6 (for more info see issue #251)
Solidity optimizer: disabled
Expected addresses with Safe Singleton Factory
Safe
at0x41675C099F32341bf84BFc5382aF534df5C7461a
SafeL2
at0x29fcB43b46531BcA003ddC8FCB67FFE91900C762
SafeProxyFactory
at0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67
TokenCallbackHandler
at0xeDCF620325E82e3B9836eaaeFdc4283E99Dd7562
CompatibilityFallbackHandler
at0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99
MultiSend
at0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526
MultiSendCallOnly
at0x9641d764fc13c8B624c04430C7356C1C7C8102e2
CreateCall
at0x9b35Af71d77eaf8d7e40252370304687390A1A52
SignMessageLib
at0xd53cd0aB83D845Ac265BE939c57F53AD838012c9
SimulateTxAccessor
at0x3d4BA2E0884aa488718476ca2FB8Efc291A46199
Issue: #391
New function signature implemented and legacy function removed from compatibility fallback handler contract.
Issue: #601
Calls to transfer
and send
were removed to make the contract not depend on any potential gas cost changes. The calls were replaced with call
, and that should be kept in mind when using the contract and designing extensions due to potential reentrancy vectors.
Issue: #544
The contracts couldn't be compiled with the solidity compiler versions 0.8.19+ because of the compiler optimizations that copy stack variables to memory to prevent stack-too-deep errors. In some assembly blocks, the scratch space was used, and that's not considered safe, so all the assembly blocks were adjusted to use safe memory allocation.
Issue: #335
The checkModuleTransaction
method was added to the guard to allow checking the module transactions before execution. The method is called before the checkAfterExecution
method. While migrating, it should be checked if a Safe has an existing guard and if it implements the checkModuleTransaction
method. If it doesn't, module transactions will be blocked.
Issues:
Previously pre-approved signatures relying on the msg.sender
variable couldn't be used in guards or modules without duplicating the logic within the module itself. This is now improved by adding an overloaded checkNSignatures
method that accepts a msg.sender
parameter. This allows the module to pass the msg.sender
variable to the checkNSignatures
method and use the pre-approved signatures. The old method was moved from the core contract to the CompatibilityFallbackHandler
.
To fit all of the above changes into the bytecode size limit, the encodeTransactionData
method was made private.
Solidity compiler: 0.7.6 (for more info see issue #251)
Solidity optimizer: disabled
Expected addresses with Safe Singleton Factory
Safe
at0x41675C099F32341bf84BFc5382aF534df5C7461a
SafeL2
at0x29fcB43b46531BcA003ddC8FCB67FFE91900C762
SafeProxyFactory
at0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67
TokenCallbackHandler
at0xeDCF620325E82e3B9836eaaeFdc4283E99Dd7562
CompatibilityFallbackHandler
at0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99
MultiSend
at0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526
MultiSendCallOnly
at0x9641d764fc13c8B624c04430C7356C1C7C8102e2
CreateCall
at0x9b35Af71d77eaf8d7e40252370304687390A1A52
SignMessageLib
at0xd53cd0aB83D845Ac265BE939c57F53AD838012c9
SimulateTxAccessor
at0x3d4BA2E0884aa488718476ca2FB8Efc291A46199
Issue: #568
setupModules
made a call to gasleft()
that is invalid in the ERC-4337 standard. The call was replaced with type(uint256).max
to forward all the available gas instead.
Solidity compiler: 0.7.6 (for more info see issue #251)
Solidity optimizer: disabled
Expected addresses with Safe Singleton Factory
Safe
at0xc962E67D9490E154D81181879ddf4CD3b65D2132
SafeL2
at0x1eb4681c549d995AbdC4aB189cAbb9f00B508cAb
SafeProxyFactory
at0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67
TokenCallbackHandler
at0xeDCF620325E82e3B9836eaaeFdc4283E99Dd7562
CompatibilityFallbackHandler
at0x2a15DE4410d4c8af0A7b6c12803120f43C42B820
MultiSend
at0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526
MultiSendCallOnly
at0x9641d764fc13c8B624c04430C7356C1C7C8102e2
CreateCall
at0x9b35Af71d77eaf8d7e40252370304687390A1A52
SignMessageLib
at0x58FCe385Ed16beB4BCE49c8DF34c7d6975807520
SimulateTxAccessor
at0x3d4BA2E0884aa488718476ca2FB8Efc291A46199
Removed the "Gnosis" prefix from all contract names.
File: contracts/SafeL2.sol
Issue: #459
The following rule of usage of the GAS
opcode in the ERC-4337 standard made it impossible to build a module to support ERC4337:
- Must not use GAS opcode (unless followed immediately by one of { CALL, DELEGATECALL, CALLCODE, STATICCALL }.)
We removed the GAS
opcode usage in module transactions to forward all the available gas instead.
Issue: #483
The setupModules
method was changed to require the to
address to be a contract. If the to
address is not a contract, the transaction will revert with a GS002
error code.
Issue: #497
To prevent unexpected behaviour, the dataHash
must now equal a hash of the data
in the signature verification process for contract signatures. Otherwise, the transaction will revert with a GS027
error code.
Issue: #461
The getModulesPaginated
method was fixed to return a correct next
pointer. The next
pointer now equals the last module in the returned array.
Issue: #309
When setting a guard, the core contract will check that the target address supports the Guard interface with an EIP-165 check. If it doesn't, the transaction will revert with the GS300
error code.
Issue: #541
Index essential parameters in the essential events, such as:
- Owner additions and removals (Indexed parameter - owner address)
- Fallback manager changes (Indexed parameter - fallback manager address)
- Module additions and removals (Indexed parameter - module address)
- Transaction guard changes (Indexed parameter - guard address)
- Transaction execution/failure (Indexed parameter - transaction hash)
Umbrella issue: #462
This method uses the CREATE
opcode, which is not counterfactual for a specific deployment. This caused user errors and lost/stuck funds and is now removed.
If the initializer data is provided, the Factory now checks that the Singleton contract exists and the success of the call to avoid a proxy being deployed uninitialized
This method will use the chain id in the CREATE2
salt; therefore, deploying a proxy to the same address on other networks is impossible.
This method should enable the creation of proxies that should exist only on one network (e.g. specific governance or admin accounts)
Method uses the revert approach to return data that only works well with some nodes, as they all return messages differently. Hence, we removed it, and the off-chain CREATE2 calculation is still possible.
The .runtimeCode
method is not supported by the ZkSync compiler, so we removed it.
Files:
Since the DefaultCallbackHandler
only handled token callbacks, it was renamed to TokenCallbackHandler
.
The NAME
and VERSION
constants were removed from the CompatibilityFallbackHandler
contract.
Issue: #440
Fixed mismatch between the function signature in the isValidSignature
method and the ISignatureValidator
interface.
File: contracts/libraries/CreateCall.sol
Issue: #541
The deployed contract address in the ContractCreation
event is now indexed.
Issue: #460
Deployments with the Safe Singleton Factory are now the default deployment process to ensure the same addresses on all chains.
Solidity compiler: 0.7.6 (more info see issue #251)
Solidity optimizer: disabled
Expected addresses with Deterministic Deployment Proxy (default)
GnosisSafe
at0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552
GnosisSafeL2
at0x3E5c63644E683549055b9Be8653de26E0B4CD36E
GnosisSafeProxyFactory
at0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2
DefaultCallbackHandler
at0x1AC114C2099aFAf5261731655Dc6c306bFcd4Dbd
CompatibilityFallbackHandler
at0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4
MultiSend
at0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761
MultiSendCallOnly
at0x40A2aCCbd92BCA938b02010E17A5b8929b49130D
CreateCall
at0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4
SignMessageLib
at0xA65387F16B013cf2Af4605Ad8aA5ec25a2cbA3a2
SimulateTxAccessor
at0x59AD6735bCd8152B84860Cb256dD9e96b85F69Da
Expected addresses with Safe Singleton Factory
GnosisSafe
at0x69f4D1788e39c87893C980c06EdF4b7f686e2938
GnosisSafeL2
at0xfb1bffC9d739B8D520DaF37dF666da4C687191EA
GnosisSafeProxyFactory
at0xC22834581EbC8527d974F8a1c97E1bEA4EF910BC
DefaultCallbackHandler
at0x3d8E605B02032A941Cfe26897Ca94d77a5BC24b3
CompatibilityFallbackHandler
at0x017062a1dE2FE6b99BE3d9d37841FeD19F573804
MultiSend
at0x998739BFdAAdde7C933B942a68053933098f9EDa
MultiSendCallOnly
at0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B
CreateCall
at0xB19D6FFc2182150F8Eb585b79D4ABcd7C5640A9d
SignMessageLib
at0x98FFBBF51bb33A056B08ddf711f289936AafF717
SimulateTxAccessor
at0x727a77a074D1E6c4530e814F89E618a3298FC044
To support deployment to networks that require replay protection support for the Safe Singleton Factory has been added. This will result in an additional set of deterministic addresses which are listed above.
The following libraries have been marked as production ready.
File: contracts/libraries/SignMessage.sol
Expected behaviour:
The library is meant as a compatibility tool for the removed signMessage
function from the pre-1.3.0 Safe contracts. It has the same signature and assumes the same storage layout as the previous Safe contract versions. After calling this function with a massage, the hash of that message should be marked as executed in the signedMessages
mapping.
File: contracts/libraries/GnosisSafeStorage.sol
Expected behaviour:
The contract contains the basic storage layout of the GnosisSafe.sol
contract and can be used by library contracts to access the storage variables.
Solidity compiler: 0.7.6 (more info see issue #251)
Solidity optimizer: disabled
GnosisSafe
at0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552
GnosisSafeL2
at0x3E5c63644E683549055b9Be8653de26E0B4CD36E
GnosisSafeProxyFactory
at0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2
DefaultCallbackHandler
at0x1AC114C2099aFAf5261731655Dc6c306bFcd4Dbd
CompatibilityFallbackHandler
at0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4
MultiSend
at0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761
MultiSendCallOnly
at0x40A2aCCbd92BCA938b02010E17A5b8929b49130D
CreateCall
at0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4
SimulateTxAccessor
at0x59AD6735bCd8152B84860Cb256dD9e96b85F69Da
File: contracts/GnosisSafe.sol
Issue: #170
Expected behaviour:
The chainId
has been added to the EIP-712 domain. In case of a change of the chainId
(e.g. hardfork related) the new chainId
will automatically be used for future signature checks.
Issue: #224
Expected behaviour:
It is possible to add a transaction guard, which can check all of the parameters that have been sent to execTransaction
prior to execution. For this check the checkTransaction
needs to be implemented by the guard. In case that checkTransaction
reverts, execTransaction
will also revert. Another check that can be implemented by the guard is checkAfterExecution
. This check is called at the very end of the execution and allows to perform checks on the final state of the Safe. The parameters passed to that check are the safeTxHash
and a success
boolean.
Issue: #201
Expected behaviour:
It is possible to use simulateDelegatecallInternal
to simulate logic on the Safe by providing a contract and calldata. This contract will then be called via a delegatecall and the result will be returned via a revert.The revert data will have the following format:
success:bool || response.length:uint256 || response:bytes
.
Important: This method will always revert.
Expected behaviour:
It is not possible anymore to change the singleton address (formerly known as master copy) via a method call. To make the implications of a singleton address change more visible it is required to use a delegatecall with a migration contract. (See example migration in libraries)
Issue: #248
Expected behaviour:
The checkSignature
method is now a view method that is public. This makes it possible that it can be used in other contracts (e.g. modules) to make it easier to reuse existing signature check logic. The function expects that there are at least enough valid signatures to hit the threshold.
Another method that has been added to make the usage from external contracts easier is checkNSignatures
which allows to set how many valid signatures are expected.
Note: The storage allocated by approveHash
will no longer be zeroed when being used in checkSignature
. If this is required a delegatecall with a contract that zeroes past approved hashes should be used.
Issue: #247
Expected behaviour:
To make it easier to interact with this method (e.g. by providing a wrapper). The requirement that the method can only be called by the Safe itself has been removed. The method will still always revert.
Note: This method is superseded by the StorageAccessible
logic and will be removed in the next major version.
Issue: #223
Expected behaviour:
As EIP-1271 is still changing the logic for it has been moved to a fallback handler. The fallback handler uses the checkSignatures
method to validate the signatures. Also this fallback handler supports the latest version of EIP-1271. The logic to mark a message hash as signed in the contract also has been moved to other contracts. getMessageHash
has been moved to a fallback handler and signMessage
into a library that can be used via delegatecall.
Note: The checkSignature
method still uses the previous version of EIP-1271 that uses the data to be signed instead of the hash of the data.
Issue: #246
Expected behaviour:
When the Safe forwards a call to the fallback handler it will append the msg.sender
to the calldata. This will allow the fallback handler to use this information.
Note: Fallback handlers should make sure that the connected Safe supports this, else this can be used by the caller to influence the fallback handler (by specifying an arbitrary msg.sender
)
Issue: #274
Expected behaviour:
If safeTxGas
is 0 (therefore all available gas has been used for the internal tx) and gasPrice
is also 0 (therefore no refund is involved) the transaction will revert when the internal tx fails. This makes it easier to interact with the Safe without having to estimate the internal transaction ahead of time.
Issue: #233
Expected behaviour:
The Safe now emits an event that contains all setup information that influences the State of the nearly setup Safe. The initializer calldata is omitted to prevent excessive gas costs. And the refund information is omitted as they don’t have an influence on the internal contract state.
Issue: #209
Expected behaviour:
When the Safe is receiving ETH it will now trigger an event (with exception of ETH received via a call to execTransaction
or as a result of a selfdestruct of another contract).
Note: It will not be possible anymore to send ETH via the solidity calls transfer or send to a Safe. This is expected to break because of the gas costs changes with the Berlin hard fork (EIP-2929) in any case (even without the event) when using the legacy transaction format. As there is also a new transaction format (EIP-2930) it is possible to use that together with the correct access list to still execute transfer/ send calls and emit the event.
File: contracts/GnosisSafeL2.sol
Expected behaviour:
The extended version will emit an event with all the information related to the Safe transaction that will be executed. As this is quite gas expensive, it is only expected that this version will be used on Layer 2 networks with low gas prices. It is expected that the events are emitted on entry to the method. As the normal Safe methods emit already some events after the execution of the Safe transaction. This will make it possible to connect other events to that call as they are "boxed" by the GnosisSafeL2 events and the GnosisSafe events.
Example:
On entry into execTransaction
of the GnosisSafeL2
contract a SafeMultiSigTransaction
event will be emitted that contains all the parameters of the function and the nonce
, msg.sender
and threshold
. Once the internal execution has finished the execTransaction
of the GnosisSafe
contract will emit a ExecutionSuccess
or ExecutionFailure
event. When processing the events of that transaction it is now possible to connect all events that were emitted between these two events to this specific Safe transaction.
Same can be done with the SafeModuleTransaction
and ExecutionFromModuleSuccess
(or ExecutionFromModuleFailure
) events when executing a transaction via a module.
Issue: #161
File: contracts/handler/DefaultCallbackHandler.sol
Expected behaviour:
Indicate via the supportsInterface
method of EIP-165 that the EIP-721 and EIP-1155 receiver interfaces are supported.
Issue: #223
File: contracts/handler/CompatibilityFallbackHandler.sol
Expected behaviour:
The CompatibilityFallbackHandler
extends the DefaultCallbackHandler
and implements support for some logic that has been removed from the core contracts. Namely EIP-1271 support and the non reverting method of the StorageAccessible
contract. Also the fallback manager contains the logic to verify Safe messages.
File: contracts/handler/HandlerContext.sol
Expected behaviour:
The HandlerContext
can be used to retrieve the msg.sender
and the Safe (aka manager) that have been forwarding the call to the fallback handler. The msg.sender
is expected to be appended to the calldata (e.g. last 20 bytes). This will only work if used with a Safe contract that supports this (e.g. 1.3.0 or newer).
File: contracts/examples/guards/DelegateCallTransactionGuard.sol
Note: This contract is meant as an example to demonstrate how to facilitate a guard. This should not be used in production without further checks.
Expected behaviour:
This transaction guard can be used to prevent that Safe transactions that use a delegatecall operation are being executed. It is also possible to specify an exception when deploying the contract (e.g. a MultiSendCallOnly
instance).
File: contracts/examples/guards/DebugTransactionGuard.sol
Note: This contract is meant as an example to demonstrate how to facilitate a guard. This should not be used in production without further checks.
Expected behaviour:
This transaction guard can be used to log more details about a transaction. This is similar to what the L2 version of the Safe does, but implemented as a transaction guard. One event will be emitted containing the transaction details and another to track the status of a specific nonce.
File: contracts/examples/guards/ReentrancyTransactionGuard.sol
Note: This contract is meant as an example to demonstrate how to facilitate a guard. This should not be used in production without further checks.
Expected behaviour:
This transaction guard can be used to prevent that Safe transactions can re-enter the execTransaction
method. The transaction guard does not differentiate between different Safes, so if multiple Safes use the same guard instance it prevents entrancy in all of the connected Safes.
Issue: #227
File: contracts/libraries/MultiSend.sol
Expected behaviour:
The multiSend
is now payable therefore will enforce anymore that msg.value
is 0. ETH that is not transferred out again will remain in this
(the calling contract when used via a delegatecall or the contract when used via call, only possible with MultiSendCallOnly
)
File: contracts/libraries/MultiSendCallOnly.sol
Expected behaviour:
The logic is the same as for the normal MultiSend
, but when an attempt is made to execute a transaction via a delegatecall the contract will revert.
Note: The encoding of the data send to the multiSend
method is exactly the same as for the normal MultiSend
, this makes it easy to exchange the contracts depending on the use case.
File: contracts/examples/libraries/GnosisSafeStorage.sol
Note: This contract is meant as an example to demonstrate how to access the Safe state within a library contract. This should not be used in production without further checks.
Expected behaviour:
The contract contains the basic storage layout of the GnosisSafe.sol
contract.
File: contracts/examples/libraries/SignMessage.sol
Note: This contract is meant as an example to demonstrate how to mark Safe message as signed in the signedMessages mapping. This should not be used in production without further checks.
Expected behaviour:
The library is meant as a compatibility tool for the removed signMessage
function from the pre-1.3.0 Safe contracts. It has the same signature and assumes the same storage layout as the previous Safe contract versions. After calling this function with a massage, the hash of that message should be marked as executed in the signedMessages
mapping.
File: contracts/examples/libraries/Migrate_1_3_0_to_1_2_0.sol
Note: This contract is meant as an example to demonstrate how to facilitate migration in the future. This should not be used in production without further checks.
Expected behaviour:
This migration can be used to migrate a Safe to another singleton address. Once the migration has been executed the singleton address will point to the address specified in the constructor of the migration and the domain separator will be properly set in storage (as this is required by the 1.2.0 version of the Safe contracts). Note: This is meant as an example contract, only to be used in production if you know what you do.