Skip to content

Commit c460de8

Browse files
authored
Format contracts (#289)
1 parent 6a74860 commit c460de8

38 files changed

+488
-566
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,26 @@ jobs:
1313
with:
1414
path: "**/node_modules"
1515
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
16-
- run: yarn
16+
- run: yarn --frozen-lockfile
1717
- run: yarn build
1818
- run: yarn coverage
1919
- name: Coveralls
2020
uses: coverallsapp/github-action@master
2121
with:
2222
github-token: ${{ secrets.GITHUB_TOKEN }}
23+
lint:
24+
runs-on: ubuntu-latest
25+
steps:
26+
- uses: actions/checkout@v2
27+
- uses: actions/setup-node@v2
28+
with:
29+
node-version: 15
30+
- uses: actions/cache@v2
31+
with:
32+
path: "**/node_modules"
33+
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
34+
- run: yarn --frozen-lockfile
35+
- run: yarn lint:sol
2336
tests-other:
2437
runs-on: ubuntu-latest
2538
strategy:
@@ -37,7 +50,7 @@ jobs:
3750
with:
3851
path: "**/node_modules"
3952
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
40-
- run: yarn
53+
- run: yarn --frozen-lockfile
4154
- run: yarn build
4255
- run: yarn coverage
4356
- name: Coveralls
@@ -65,4 +78,4 @@ jobs:
6578
with:
6679
path: "**/node_modules"
6780
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
68-
- run: (yarn && yarn build && yarn hardhat codesize --contractname GnosisSafe && yarn benchmark) || echo "Benchmark failed"
81+
- run: (yarn --frozen-lockfile && yarn build && yarn hardhat codesize --contractname GnosisSafe && yarn benchmark) || echo "Benchmark failed"

.prettierrc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"overrides": [
3+
{
4+
"files": "*.sol",
5+
"options": {
6+
"printWidth": 140,
7+
"tabWidth": 4,
8+
"useTabs": false,
9+
"singleQuote": false,
10+
"bracketSpacing": false,
11+
"explicitTypes": "always"
12+
}
13+
}
14+
]
15+
}

contracts/GnosisSafe.sol

Lines changed: 103 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,18 @@ import "./external/GnosisSafeMath.sol";
1616
/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.
1717
/// @author Stefan George - <stefan@gnosis.io>
1818
/// @author Richard Meissner - <richard@gnosis.io>
19-
contract GnosisSafe
20-
is EtherPaymentFallback, Singleton, ModuleManager, OwnerManager, SignatureDecoder, SecuredTokenTransfer, ISignatureValidatorConstants, FallbackManager, StorageAccessible, GuardManager {
21-
19+
contract GnosisSafe is
20+
EtherPaymentFallback,
21+
Singleton,
22+
ModuleManager,
23+
OwnerManager,
24+
SignatureDecoder,
25+
SecuredTokenTransfer,
26+
ISignatureValidatorConstants,
27+
FallbackManager,
28+
StorageAccessible,
29+
GuardManager
30+
{
2231
using GnosisSafeMath for uint256;
2332

2433
string public constant VERSION = "1.3.0";
@@ -38,26 +47,11 @@ contract GnosisSafe
3847
//);
3948
bytes32 private constant SAFE_MSG_TYPEHASH = 0x60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca;
4049

41-
event SafeSetup(
42-
address indexed initiator,
43-
address[] owners,
44-
uint256 threshold,
45-
address initializer,
46-
address fallbackHandler
47-
);
48-
event ApproveHash(
49-
bytes32 indexed approvedHash,
50-
address indexed owner
51-
);
52-
event SignMsg(
53-
bytes32 indexed msgHash
54-
);
55-
event ExecutionFailure(
56-
bytes32 txHash, uint256 payment
57-
);
58-
event ExecutionSuccess(
59-
bytes32 txHash, uint256 payment
60-
);
50+
event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler);
51+
event ApproveHash(bytes32 indexed approvedHash, address indexed owner);
52+
event SignMsg(bytes32 indexed msgHash);
53+
event ExecutionFailure(bytes32 txHash, uint256 payment);
54+
event ExecutionSuccess(bytes32 txHash, uint256 payment);
6155

6256
uint256 public nonce;
6357
bytes32 private _deprecatedDomainSeparator;
@@ -92,9 +86,7 @@ contract GnosisSafe
9286
address paymentToken,
9387
uint256 payment,
9488
address payable paymentReceiver
95-
)
96-
external
97-
{
89+
) external {
9890
// setupOwners checks if the Threshold is already set, therefore preventing that this method is called twice
9991
setupOwners(_owners, _threshold);
10092
if (fallbackHandler != address(0)) internalSetFallbackHandler(fallbackHandler);
@@ -132,20 +124,26 @@ contract GnosisSafe
132124
address gasToken,
133125
address payable refundReceiver,
134126
bytes memory signatures
135-
)
136-
public
137-
virtual
138-
payable
139-
returns (bool success)
140-
{
127+
) public payable virtual returns (bool success) {
141128
bytes32 txHash;
142129
// Use scope here to limit variable lifetime and prevent `stack too deep` errors
143130
{
144-
bytes memory txHashData = encodeTransactionData(
145-
to, value, data, operation, // Transaction info
146-
safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, // Payment info
147-
nonce
148-
);
131+
bytes memory txHashData =
132+
encodeTransactionData(
133+
// Transaction info
134+
to,
135+
value,
136+
data,
137+
operation,
138+
safeTxGas,
139+
// Payment info
140+
baseGas,
141+
gasPrice,
142+
gasToken,
143+
refundReceiver,
144+
// Signature info
145+
nonce
146+
);
149147
// Increase nonce and execute transaction.
150148
nonce++;
151149
txHash = keccak256(txHashData);
@@ -155,15 +153,26 @@ contract GnosisSafe
155153
address guard = getGuard();
156154
if (guard != address(0)) {
157155
Guard(guard).checkTransaction(
158-
to, value, data, operation, // Transaction info
159-
safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, // Payment info
160-
signatures, msg.sender
156+
// Transaction info
157+
to,
158+
value,
159+
data,
160+
operation,
161+
safeTxGas,
162+
// Payment info
163+
baseGas,
164+
gasPrice,
165+
gasToken,
166+
refundReceiver,
167+
// Signature info
168+
signatures,
169+
msg.sender
161170
);
162171
}
163172
}
164173
// We require some gas to emit the events (at least 2500) after the execution and some to perform code until the execution (500)
165174
// We also include the 1/64 in the check that is not send along with a call to counteract potential shortings because of EIP-150
166-
require(gasleft() >= (safeTxGas * 64 / 63).max(safeTxGas + 2500) + 500, "GS010");
175+
require(gasleft() >= ((safeTxGas * 64) / 63).max(safeTxGas + 2500) + 500, "GS010");
167176
// Use scope here to limit variable lifetime and prevent `stack too deep` errors
168177
{
169178
uint256 gasUsed = gasleft();
@@ -190,10 +199,7 @@ contract GnosisSafe
190199
uint256 gasPrice,
191200
address gasToken,
192201
address payable refundReceiver
193-
)
194-
private
195-
returns (uint256 payment)
196-
{
202+
) private returns (uint256 payment) {
197203
// solhint-disable-next-line avoid-tx-origin
198204
address payable receiver = refundReceiver == address(0) ? payable(tx.origin) : refundReceiver;
199205
if (gasToken == address(0)) {
@@ -207,15 +213,16 @@ contract GnosisSafe
207213
}
208214

209215
/**
210-
* @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.
211-
* @param dataHash Hash of the data (could be either a message hash or transaction hash)
212-
* @param data That should be signed (this is passed to an external validator contract)
213-
* @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.
214-
*/
215-
function checkSignatures(bytes32 dataHash, bytes memory data, bytes memory signatures)
216-
public
217-
view
218-
{
216+
* @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.
217+
* @param dataHash Hash of the data (could be either a message hash or transaction hash)
218+
* @param data That should be signed (this is passed to an external validator contract)
219+
* @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.
220+
*/
221+
function checkSignatures(
222+
bytes32 dataHash,
223+
bytes memory data,
224+
bytes memory signatures
225+
) public view {
219226
// Load threshold to avoid multiple storage loads
220227
uint256 _threshold = threshold;
221228
// Check that a threshold is set
@@ -231,8 +238,8 @@ contract GnosisSafe
231238
uint256 i;
232239
for (i = 0; i < _threshold; i++) {
233240
(v, r, s) = signatureSplit(signatures, i);
234-
// If v is 0 then it is a contract signature
235241
if (v == 0) {
242+
// If v is 0 then it is a contract signature
236243
// When handling contract signatures the address of the contract is encoded into r
237244
currentOwner = address(uint160(uint256(r)));
238245

@@ -260,23 +267,22 @@ contract GnosisSafe
260267
contractSignature := add(add(signatures, s), 0x20)
261268
}
262269
require(ISignatureValidator(currentOwner).isValidSignature(data, contractSignature) == EIP1271_MAGIC_VALUE, "GS024");
263-
// If v is 1 then it is an approved hash
264270
} else if (v == 1) {
271+
// If v is 1 then it is an approved hash
265272
// When handling approved hashes the address of the approver is encoded into r
266273
currentOwner = address(uint160(uint256(r)));
267274
// Hashes are automatically approved by the sender of the message or when they have been pre-approved via a separate transaction
268275
require(msg.sender == currentOwner || approvedHashes[currentOwner][dataHash] != 0, "GS025");
269276
} else if (v > 30) {
277+
// If v > 30 then default va (27,28) has been adjusted for eth_sign flow
270278
// To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix before applying ecrecover
271279
currentOwner = ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", dataHash)), v - 4, r, s);
272280
} else {
281+
// Default is the ecrecover flow with the provided data hash
273282
// Use ecrecover with the messageHash for EOA signatures
274283
currentOwner = ecrecover(dataHash, v, r, s);
275284
}
276-
require (
277-
currentOwner > lastOwner && owners[currentOwner] != address(0) && currentOwner != SENTINEL_OWNERS,
278-
"GS026"
279-
);
285+
require(currentOwner > lastOwner && owners[currentOwner] != address(0) && currentOwner != SENTINEL_OWNERS, "GS026");
280286
lastOwner = currentOwner;
281287
}
282288
}
@@ -290,10 +296,12 @@ contract GnosisSafe
290296
/// @param operation Operation type of Safe transaction.
291297
/// @return Estimate without refunds and overhead fees (base transaction and payload data gas costs).
292298
/// @notice Deprecated in favor of common/StorageAccessible.sol and will be removed in next version.
293-
function requiredTxGas(address to, uint256 value, bytes calldata data, Enum.Operation operation)
294-
external
295-
returns (uint256)
296-
{
299+
function requiredTxGas(
300+
address to,
301+
uint256 value,
302+
bytes calldata data,
303+
Enum.Operation operation
304+
) external returns (uint256) {
297305
uint256 startGas = gasleft();
298306
// We don't provide an error message here, as we use it to return the estimate
299307
require(execute(to, value, data, operation, gasleft()));
@@ -303,31 +311,26 @@ contract GnosisSafe
303311
}
304312

305313
/**
306-
* @dev Marks a hash as approved. This can be used to validate a hash that is used by a signature.
307-
* @param hashToApprove The hash that should be marked as approved for signatures that are verified by this contract.
308-
*/
309-
function approveHash(bytes32 hashToApprove)
310-
external
311-
{
314+
* @dev Marks a hash as approved. This can be used to validate a hash that is used by a signature.
315+
* @param hashToApprove The hash that should be marked as approved for signatures that are verified by this contract.
316+
*/
317+
function approveHash(bytes32 hashToApprove) external {
312318
require(owners[msg.sender] != address(0), "GS030");
313319
approvedHashes[msg.sender][hashToApprove] = 1;
314320
emit ApproveHash(hashToApprove, msg.sender);
315321
}
316322

317323
/**
318-
* @dev Marks a message as signed, so that it can be used with EIP-1271
319-
* @notice Marks a message (`_data`) as signed.
320-
* @param _data Arbitrary length data that should be marked as signed on the behalf of address(this)
321-
*/
322-
function signMessage(bytes calldata _data)
323-
external
324-
authorized
325-
{
324+
* @dev Marks a message as signed, so that it can be used with EIP-1271
325+
* @notice Marks a message (`_data`) as signed.
326+
* @param _data Arbitrary length data that should be marked as signed on the behalf of address(this)
327+
*/
328+
function signMessage(bytes calldata _data) external authorized {
326329
bytes32 msgHash = getMessageHash(_data);
327330
signedMessages[msgHash] = 1;
328331
emit SignMsg(msgHash);
329332
}
330-
333+
331334
/// @dev Returns the chain id used by this contract.
332335
function getChainId() public view returns (uint256) {
333336
uint256 id;
@@ -345,19 +348,9 @@ contract GnosisSafe
345348
/// @dev Returns hash of a message that can be signed by owners.
346349
/// @param message Message that should be hashed
347350
/// @return Message hash.
348-
function getMessageHash(
349-
bytes memory message
350-
)
351-
public
352-
view
353-
returns (bytes32)
354-
{
355-
bytes32 safeMessageHash = keccak256(
356-
abi.encode(SAFE_MSG_TYPEHASH, keccak256(message))
357-
);
358-
return keccak256(
359-
abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator(), safeMessageHash)
360-
);
351+
function getMessageHash(bytes memory message) public view returns (bytes32) {
352+
bytes32 safeMessageHash = keccak256(abi.encode(SAFE_MSG_TYPEHASH, keccak256(message)));
353+
return keccak256(abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator(), safeMessageHash));
361354
}
362355

363356
/// @dev Returns the bytes that are hashed to be signed by owners.
@@ -383,14 +376,23 @@ contract GnosisSafe
383376
address gasToken,
384377
address refundReceiver,
385378
uint256 _nonce
386-
)
387-
public
388-
view
389-
returns (bytes memory)
390-
{
391-
bytes32 safeTxHash = keccak256(
392-
abi.encode(SAFE_TX_TYPEHASH, to, value, keccak256(data), operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce)
393-
);
379+
) public view returns (bytes memory) {
380+
bytes32 safeTxHash =
381+
keccak256(
382+
abi.encode(
383+
SAFE_TX_TYPEHASH,
384+
to,
385+
value,
386+
keccak256(data),
387+
operation,
388+
safeTxGas,
389+
baseGas,
390+
gasPrice,
391+
gasToken,
392+
refundReceiver,
393+
_nonce
394+
)
395+
);
394396
return abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator(), safeTxHash);
395397
}
396398

@@ -417,11 +419,7 @@ contract GnosisSafe
417419
address gasToken,
418420
address refundReceiver,
419421
uint256 _nonce
420-
)
421-
public
422-
view
423-
returns (bytes32)
424-
{
422+
) public view returns (bytes32) {
425423
return keccak256(encodeTransactionData(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce));
426424
}
427425
}

0 commit comments

Comments
 (0)