1use alloy::sol;
4
5sol! {
6 #[sol(rpc)]
8 interface ISafe {
9 function execTransaction(
11 address to,
12 uint256 value,
13 bytes calldata data,
14 uint8 operation,
15 uint256 safeTxGas,
16 uint256 baseGas,
17 uint256 gasPrice,
18 address gasToken,
19 address payable refundReceiver,
20 bytes memory signatures
21 ) external payable returns (bool success);
22
23 function nonce() external view returns (uint256 nonce);
25
26 function getThreshold() external view returns (uint256 threshold);
28
29 function getOwners() external view returns (address[] memory owners);
31
32 function isOwner(address owner) external view returns (bool isOwner);
34
35 function domainSeparator() external view returns (bytes32);
37
38 function getTransactionHash(
40 address to,
41 uint256 value,
42 bytes calldata data,
43 uint8 operation,
44 uint256 safeTxGas,
45 uint256 baseGas,
46 uint256 gasPrice,
47 address gasToken,
48 address refundReceiver,
49 uint256 _nonce
50 ) external view returns (bytes32);
51
52 function encodeTransactionData(
54 address to,
55 uint256 value,
56 bytes calldata data,
57 uint8 operation,
58 uint256 safeTxGas,
59 uint256 baseGas,
60 uint256 gasPrice,
61 address gasToken,
62 address refundReceiver,
63 uint256 _nonce
64 ) external view returns (bytes memory);
65
66 function checkSignatures(
68 bytes32 dataHash,
69 bytes memory data,
70 bytes memory signatures
71 ) external view;
72
73 function getChainId() external view returns (uint256);
75
76 event ExecutionSuccess(bytes32 indexed txHash, uint256 payment);
78 event ExecutionFailure(bytes32 indexed txHash, uint256 payment);
79 event SafeReceived(address indexed sender, uint256 value);
80 }
81
82 #[sol(rpc)]
84 interface IMultiSend {
85 function multiSend(bytes memory transactions) external payable;
89 }
90
91 #[sol(rpc)]
93 interface IMultiSendCallOnly {
94 function multiSend(bytes memory transactions) external payable;
96 }
97
98 #[sol(rpc)]
100 interface IERC20 {
101 function transfer(address to, uint256 amount) external returns (bool);
102 function approve(address spender, uint256 amount) external returns (bool);
103 function transferFrom(address from, address to, uint256 amount) external returns (bool);
104 function balanceOf(address account) external view returns (uint256);
105 function allowance(address owner, address spender) external view returns (uint256);
106
107 event Transfer(address indexed from, address indexed to, uint256 value);
108 event Approval(address indexed owner, address indexed spender, uint256 value);
109 }
110
111 #[sol(rpc)]
113 interface ISafeProxyFactory {
114 function createProxyWithNonce(
116 address _singleton,
117 bytes memory initializer,
118 uint256 saltNonce
119 ) external returns (address proxy);
120
121 function proxyCreationCode() external pure returns (bytes memory);
123
124 event ProxyCreation(address indexed proxy, address singleton);
125 }
126
127 #[sol(rpc)]
129 interface ISafeSetup {
130 function setup(
132 address[] calldata _owners,
133 uint256 _threshold,
134 address to,
135 bytes calldata data,
136 address fallbackHandler,
137 address paymentToken,
138 uint256 payment,
139 address payable paymentReceiver
140 ) external;
141 }
142}
143
144pub const SAFE_TX_TYPEHASH: [u8; 32] = [
147 0xbb, 0x83, 0x10, 0xd4, 0x86, 0x36, 0x8d, 0xb6, 0xbd, 0x6f, 0x84, 0x94, 0x02, 0xfd, 0xd7, 0x3a,
148 0xd5, 0x3d, 0x31, 0x6b, 0x5a, 0x4b, 0x26, 0x44, 0xad, 0x6e, 0xfe, 0x0f, 0x94, 0x12, 0x86, 0xd8,
149];
150
151pub const DOMAIN_SEPARATOR_TYPEHASH: [u8; 32] = [
154 0x47, 0xe7, 0x95, 0x34, 0xa2, 0x45, 0x95, 0x2e, 0x8b, 0x16, 0x89, 0x3a, 0x33, 0x6b, 0x85, 0xa3,
155 0xd9, 0xea, 0x9f, 0xa8, 0xc5, 0x73, 0xf3, 0xd8, 0x03, 0xaf, 0xb9, 0x2a, 0x79, 0x46, 0x92, 0x18,
156];
157
158#[cfg(test)]
159mod tests {
160 use super::*;
161 use alloy::primitives::keccak256;
162
163 #[test]
164 fn test_safe_tx_typehash() {
165 let computed = keccak256(
166 "SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)"
167 );
168 assert_eq!(computed.as_slice(), &SAFE_TX_TYPEHASH);
169 }
170
171 #[test]
172 fn test_domain_separator_typehash() {
173 let computed = keccak256("EIP712Domain(uint256 chainId,address verifyingContract)");
174 assert_eq!(computed.as_slice(), &DOMAIN_SEPARATOR_TYPEHASH);
175 }
176}