Skip to content

Commit

Permalink
Merge pull request #87 from keyper-labs/feature/reduce-bytesize-code
Browse files Browse the repository at this point in the history
Reduce byteSize Code and Fix override of deepTreeLimit when Create a New rootSafe (issue 49)
  • Loading branch information
alfredolopez80 authored Jun 28, 2024
2 parents dfd821e + cd08376 commit f3004bc
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 118 deletions.
40 changes: 0 additions & 40 deletions docs/SigningUtils.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,44 +24,4 @@ struct Transaction {
bytes signatures;
}
```
### _hashTypedDataV4

```solidity
function _hashTypedDataV4(bytes32 domainSeparator, bytes32 structHash) internal view virtual returns (bytes32)
```

_Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
function returns the hash of the fully encoded EIP712 message for this domain.

This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:

```solidity
bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
keccak256("Mail(address to,string contents)"),
mailTo,
keccak256(bytes(mailContents))
)));
address signer = ECDSA.recover(digest, signature);
```_
### createDigestExecTx
```solidity
function createDigestExecTx(bytes32 domainSeparatorSafe, struct SigningUtils.Transaction safeTx) public view returns (bytes32)
```

_Given a transaction, it creates a hash of the transaction that can be signed_

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| domainSeparatorSafe | bytes32 | Hash of the Safe domain separator |
| safeTx | struct SigningUtils.Transaction | Safe transaction |

#### Return Values

| Name | Type | Description |
| ---- | ---- | ----------- |
| [0] | bytes32 | Hash of the transaction |

2 changes: 0 additions & 2 deletions src/DenyHelper.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.23;

import {GnosisSafeMath} from "@safe-contracts/external/GnosisSafeMath.sol";
import {Address} from "@openzeppelin/utils/Address.sol";
import {Context} from "@openzeppelin/utils/Context.sol";
import {Constants} from "./libraries/Constants.sol";
Expand All @@ -27,7 +26,6 @@ abstract contract ValidAddress is Context {
/// @notice Deny Helpers Methods for the Palmera module
/// @dev RDeny Helper Palmera Modules
abstract contract DenyHelper is ValidAddress {
using GnosisSafeMath for uint256;
using Address for address;

/// @dev Deny/Allowlist Flags by Org
Expand Down
6 changes: 3 additions & 3 deletions src/Helpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
DenyHelper,
Address,
Context,
GnosisSafeMath,
Constants,
DataTypes,
Errors,
Expand All @@ -24,7 +23,6 @@ import {ReentrancyGuard} from "@openzeppelin/security/ReentrancyGuard.sol";
/// @notice This contract is a helper contract for the Palmera Module
/// @dev Helper Methods for the Palmera module
abstract contract Helpers is DenyHelper, SignatureDecoder, ReentrancyGuard {
using GnosisSafeMath for uint256;
using Address for address;

/// @dev Modifier for Validate if the address is a Safe Smart Account Wallet
Expand All @@ -43,7 +41,9 @@ abstract contract Helpers is DenyHelper, SignatureDecoder, ReentrancyGuard {
/// @return Hash of the domain separator
function domainSeparator() public view returns (bytes32) {
return keccak256(
abi.encode(Constants.DOMAIN_SEPARATOR_TYPEHASH, getChainId(), this)
abi.encode(
Constants.DOMAIN_SEPARATOR_TYPEHASH, getChainId(), address(this)
)
);
}

Expand Down
26 changes: 12 additions & 14 deletions src/PalmeraModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@ import {
DataTypes,
Events,
Address,
GnosisSafeMath,
Enum,
ISafe
} from "./Helpers.sol";

/// @title Palmera Module
/// @custom:security-contact [email protected]
contract PalmeraModule is Auth, Helpers {
using GnosisSafeMath for uint256;
using Address for address;

/// @dev Definition of Safe Palmera Module
Expand Down Expand Up @@ -334,8 +332,6 @@ contract PalmeraModule is Auth, Helpers {
bytes32 org = getOrgHashBySafe(caller);
uint256 newIndex = indexId;
safeId = _createOrgOrRoot(name, caller, newRootSafe);
// Setting level by default
depthTreeLimit[org] = 8;

emit Events.RootSafeCreated(org, newIndex, caller, newRootSafe, name);
}
Expand Down Expand Up @@ -384,7 +380,7 @@ contract PalmeraModule is Auth, Helpers {
!_authority.doesUserHaveRole(
superSafeOrgSafe.safe, uint8(DataTypes.Role.SUPER_SAFE)
)
) && (superSafeOrgSafe.child.length > 0)
) && (superSafeOrgSafe.child.length != 0)
) {
_authority.setUserRole(
superSafeOrgSafe.safe, uint8(DataTypes.Role.SUPER_SAFE), true
Expand Down Expand Up @@ -423,7 +419,7 @@ contract PalmeraModule is Auth, Helpers {
// Check if the safe is Root Safe and has child
if (
((_safe.tier == DataTypes.Tier.ROOT) || (_safe.superSafe == 0))
&& (_safe.child.length > 0)
&& (_safe.child.length != 0)
) {
revert Errors.CannotRemoveSafeBeforeRemoveChild(_safe.child.length);
}
Expand Down Expand Up @@ -727,7 +723,7 @@ contract PalmeraModule is Auth, Helpers {
address prevUser = getPrevUser(org, user);
listed[org][prevUser] = listed[org][user];
listed[org][user] = address(0);
listCount[org] = listCount[org] > 1 ? listCount[org].sub(1) : 0;
listCount[org] = listCount[org] > 1 ? (listCount[org] - 1) : 0;
emit Events.DroppedFromList(user);
}

Expand Down Expand Up @@ -967,9 +963,10 @@ contract PalmeraModule is Auth, Helpers {
revert Errors.OrgNotRegistered(org);
}
/// Check if the Safe address is into an Safe mapping
for (uint256 i; i < indexSafe[org].length;) {
if (safes[org][indexSafe[org][i]].safe == safe) {
return indexSafe[org][i];
uint256[] memory indexSafeOrg = indexSafe[org];
for (uint256 i; i < indexSafeOrg.length;) {
if (safes[org][indexSafeOrg[i]].safe == safe) {
return indexSafeOrg[i];
}
unchecked {
++i;
Expand Down Expand Up @@ -1118,10 +1115,11 @@ contract PalmeraModule is Auth, Helpers {
/// @param org ID's of the organisation
/// @param safeId uint256 of the safe
function removeIndexSafe(bytes32 org, uint256 safeId) private {
for (uint256 i; i < indexSafe[org].length;) {
if (indexSafe[org][i] == safeId) {
indexSafe[org][i] = indexSafe[org][indexSafe[org].length - 1];
indexSafe[org].pop();
uint256[] storage indexSafeOrg = indexSafe[org];
for (uint256 i; i < indexSafeOrg.length;) {
if (indexSafeOrg[i] == safeId) {
indexSafeOrg[i] = indexSafeOrg[indexSafeOrg.length - 1];
indexSafeOrg.pop();
break;
}
unchecked {
Expand Down
59 changes: 0 additions & 59 deletions src/SigningUtils.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.23;

import {ECDSA} from "@openzeppelin/utils/cryptography/ECDSA.sol";
import {Enum} from "@safe-contracts/base/Executor.sol";

/// @title SigningUtils
Expand All @@ -20,62 +19,4 @@ abstract contract SigningUtils {
address refundReceiver;
bytes signatures;
}

/**
* @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
* function returns the hash of the fully encoded EIP712 message for this domain.
*
* This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
*
* ```solidity
* bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
* keccak256("Mail(address to,string contents)"),
* mailTo,
* keccak256(bytes(mailContents))
* )));
* address signer = ECDSA.recover(digest, signature);
* ```
*/
function _hashTypedDataV4(bytes32 domainSeparator, bytes32 structHash)
internal
view
virtual
returns (bytes32)
{
return ECDSA.toTypedDataHash(domainSeparator, structHash);
}

/**
* @dev Given a transaction, it creates a hash of the transaction that can be signed
* @param domainSeparatorSafe Hash of the Safe domain separator
* @param safeTx Safe transaction
* @return Hash of the transaction
*/
function createDigestExecTx(
bytes32 domainSeparatorSafe,
Transaction memory safeTx
) public view returns (bytes32) {
bytes32 digest = _hashTypedDataV4(
domainSeparatorSafe,
keccak256(
abi.encode(
keccak256(
"execTransaction(address to,uint256 value,bytes data,Enum.Operation operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,bytes signatures)"
),
safeTx.to,
safeTx.value,
safeTx.data,
safeTx.operation,
safeTx.safeTxGas,
safeTx.baseGas,
safeTx.gasPrice,
safeTx.gasToken,
safeTx.refundReceiver,
safeTx.signatures
)
)
);

return digest;
}
}

0 comments on commit f3004bc

Please sign in to comment.