Skip to content

Commit

Permalink
Merge 8f0458d into fd4db09
Browse files Browse the repository at this point in the history
  • Loading branch information
filmakarov authored Nov 21, 2024
2 parents fd4db09 + 8f0458d commit e1b94a1
Show file tree
Hide file tree
Showing 28 changed files with 725 additions and 697 deletions.
16 changes: 1 addition & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ Documentation: (https://github.com/bcnmy/nexus/wiki)

## Getting Started

To kickstart, follow these steps:
To kickstart, follow these steps:

### Prerequisites
Expand Down Expand Up @@ -148,20 +147,7 @@ To generate reports of the storage layout for potential upgrades safety using `h
| Auditor | Date | Final Report Link |
| ---------------- | ---------- | ----------------------- |
| CodeHawks-Cyfrin | 17-09-2024 | [View Report](./audits/CodeHawks-Cyfrin-17-09-2024.pdf) |
| Firm Name | DD-MM-YYYY | [View Report](./audits) |

## 🏆 Biconomy Champions League 🏆

Welcome to the Champions League, a place where your contributions to Biconomy are celebrated and immortalized in our Hall of Fame. This elite group showcases individuals who have significantly advanced our mission, from enhancing code efficiency to strengthening security, and enriching our documentation.

### Champions Roster

| 🍊 Contributor | 🛡️ Domain |
| -------------- | ----------------- |
| @user1 | Code Optimization |
| @user2 | Security |
| @user3 | Documentation |
| ... | ... |
| Spearbit | 10/11-2024 | [View Report](./audits/report-cantinacode-biconomy-0708-final.pdf) / [View Add-on](./audits/report-cantinacode-biconomy-erc7739-addon-final.pdf) |

### Entering the League

Expand Down
Binary file not shown.
Binary file not shown.
48 changes: 34 additions & 14 deletions contracts/Nexus.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ import { ExecLib } from "./lib/ExecLib.sol";
import { INexus } from "./interfaces/INexus.sol";
import { BaseAccount } from "./base/BaseAccount.sol";
import { IERC7484 } from "./interfaces/IERC7484.sol";
import { IERC7739 } from "./interfaces/IERC7739.sol";
import { ModuleManager } from "./base/ModuleManager.sol";
import { ExecutionHelper } from "./base/ExecutionHelper.sol";
import { IValidator } from "./interfaces/modules/IValidator.sol";
import { MODULE_TYPE_VALIDATOR, MODULE_TYPE_EXECUTOR, MODULE_TYPE_FALLBACK, MODULE_TYPE_HOOK, MODULE_TYPE_MULTI, SUPPORTS_NESTED_TYPED_DATA_SIGN } from "./types/Constants.sol";
import { MODULE_TYPE_VALIDATOR, MODULE_TYPE_EXECUTOR, MODULE_TYPE_FALLBACK, MODULE_TYPE_HOOK, MODULE_TYPE_MULTI, SUPPORTS_ERC7739 } from "./types/Constants.sol";
import { ModeLib, ExecutionMode, ExecType, CallType, CALLTYPE_BATCH, CALLTYPE_SINGLE, CALLTYPE_DELEGATECALL, EXECTYPE_DEFAULT, EXECTYPE_TRY } from "./lib/ModeLib.sol";
import { NonceLib } from "./lib/NonceLib.sol";
import { SentinelListLib, SENTINEL, ZERO_ADDRESS } from "sentinellist/SentinelList.sol";
Expand All @@ -39,6 +38,7 @@ contract Nexus is INexus, BaseAccount, ExecutionHelper, ModuleManager, UUPSUpgra
using ModeLib for ExecutionMode;
using ExecLib for bytes;
using NonceLib for uint256;
using SentinelListLib for SentinelListLib.SentinelList;

/// @dev The timelock period for emergency hook uninstallation.
uint256 internal constant _EMERGENCY_TIMELOCK = 1 days;
Expand Down Expand Up @@ -226,6 +226,15 @@ contract Nexus is INexus, BaseAccount, ExecutionHelper, ModuleManager, UUPSUpgra
/// bytes4(keccak256("isValidSignature(bytes32,bytes)") = 0x1626ba7e
/// @dev Delegates the validation to a validator module specified within the signature data.
function isValidSignature(bytes32 hash, bytes calldata signature) external view virtual override returns (bytes4) {
// Handle potential ERC7739 support detection request
if (signature.length == 0) {
// Forces the compiler to optimize for smaller bytecode size.
if (uint256(hash) == (~signature.length / 0xffff) * 0x7739) {
return checkERC7739Support(hash, signature);
}
}
// else proceed with normal signature verification

// First 20 bytes of data will be validator address and rest of the bytes is complete signature.
address validator = address(bytes20(signature[0:20]));
require(_isValidatorInstalled(validator), ValidatorNotInstalled(validator));
Expand Down Expand Up @@ -320,19 +329,30 @@ contract Nexus is INexus, BaseAccount, ExecutionHelper, ModuleManager, UUPSUpgra
UUPSUpgradeable.upgradeToAndCall(newImplementation, data);
}

/// @dev For automatic detection that the smart account supports the nested EIP-712 workflow
/// Offchain usage only
/// Iterates over all the validators
function supportsNestedTypedDataSign() public view virtual returns (bytes32) {
SentinelListLib.SentinelList storage validators = _getAccountStorage().validators;
address next = validators.entries[SENTINEL];
while (next != ZERO_ADDRESS && next != SENTINEL) {
try IERC7739(next).supportsNestedTypedDataSign() returns (bytes32 res) {
if (res == SUPPORTS_NESTED_TYPED_DATA_SIGN) return SUPPORTS_NESTED_TYPED_DATA_SIGN;
} catch {}
next = validators.entries[next];
/// @dev For automatic detection that the smart account supports the ERC7739 workflow
/// Iterates over all the validators but only if this is a detection request
/// ERC-7739 spec assumes that if the account doesn't support ERC-7739
/// it will try to handle the detection request as it was normal sig verification
/// request and will return 0xffffffff since it won't be able to verify the 0x signature
/// against 0x7739...7739 hash.
/// So this approach is consistent with the ERC-7739 spec.
/// If no validator supports ERC-7739, this function returns false
/// thus the account will proceed with normal signature verification
/// and return 0xffffffff as a result.
function checkERC7739Support(bytes32 hash, bytes calldata signature) public view virtual returns (bytes4) {
bytes4 result;
unchecked {
SentinelListLib.SentinelList storage validators = _getAccountStorage().validators;
address next = validators.entries[SENTINEL];
while (next != ZERO_ADDRESS && next != SENTINEL) {
bytes4 support = IValidator(next).isValidSignatureWithSender(msg.sender, hash, signature);
if (bytes2(support) == bytes2(SUPPORTS_ERC7739) && support > result) {
result = support;
}
next = validators.getNext(next);
}
}
return bytes4(0xffffffff);
return result == bytes4(0) ? bytes4(0xffffffff) : result;
}

/// @dev Ensures that only authorized callers can upgrade the smart contract implementation.
Expand Down
Loading

0 comments on commit e1b94a1

Please sign in to comment.