Source Code
Overview
XDAI Balance
XDAI Value
$0.00Latest 25 from a total of 72,040 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Register Safe By... | 44309765 | 26 hrs ago | IN | 0 XDAI | 0.00000004 | ||||
| Register Safe By... | 44309764 | 26 hrs ago | IN | 0 XDAI | 0.00000004 | ||||
| Register Safe By... | 44309760 | 26 hrs ago | IN | 0 XDAI | 0.00000004 | ||||
| Register Safe By... | 44309757 | 26 hrs ago | IN | 0 XDAI | 0.00000009 | ||||
| Register Safe By... | 44309757 | 26 hrs ago | IN | 0 XDAI | 0.00000009 | ||||
| Register Safe By... | 44292406 | 2 days ago | IN | 0 XDAI | 0.00000009 | ||||
| Register Safe By... | 44289910 | 2 days ago | IN | 0 XDAI | 0.00000009 | ||||
| Register Safe By... | 44276050 | 3 days ago | IN | 0 XDAI | 0.00000004 | ||||
| Register Safe By... | 44276040 | 3 days ago | IN | 0 XDAI | 0.00000009 | ||||
| Register Safe By... | 44263198 | 3 days ago | IN | 0 XDAI | 0.00000004 | ||||
| Register Safe By... | 44263189 | 3 days ago | IN | 0 XDAI | 0.00000009 | ||||
| Register Safe By... | 44261545 | 4 days ago | IN | 0 XDAI | 0.00000009 | ||||
| Register Safe By... | 44260616 | 4 days ago | IN | 0 XDAI | 0.00000009 | ||||
| Register Safe By... | 44255894 | 4 days ago | IN | 0 XDAI | 0.00000009 | ||||
| Register Safe By... | 44255061 | 4 days ago | IN | 0 XDAI | 0.00000004 | ||||
| Register Safe By... | 44255059 | 4 days ago | IN | 0 XDAI | 0.00000004 | ||||
| Register Safe By... | 44255052 | 4 days ago | IN | 0 XDAI | 0.00000009 | ||||
| Register Safe By... | 44244476 | 5 days ago | IN | 0 XDAI | 0.00000004 | ||||
| Register Safe By... | 44244468 | 5 days ago | IN | 0 XDAI | 0.00000009 | ||||
| Register Safe By... | 44242535 | 5 days ago | IN | 0 XDAI | 0.00000004 | ||||
| Register Safe By... | 44242532 | 5 days ago | IN | 0 XDAI | 0.00000004 | ||||
| Register Safe By... | 44242525 | 5 days ago | IN | 0 XDAI | 0.00000009 | ||||
| Register Safe By... | 44242477 | 5 days ago | IN | 0 XDAI | 0.00000004 | ||||
| Register Safe By... | 44242467 | 5 days ago | IN | 0 XDAI | 0.00000009 | ||||
| Register Safe By... | 44213162 | 7 days ago | IN | 0 XDAI | 0.00000004 |
View more zero value Internal Transactions in Advanced View mode
Cross-Chain Transactions
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x7b8E16AD...bbB6b1b5C The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
HoprNodeSafeRegistry
Compiler Version
v0.8.30+commit.73712a01
Optimization Enabled:
Yes with 200 runs
Other Settings:
prague EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8;
import { ECDSA } from "openzeppelin-contracts-5.4.0/utils/cryptography/ECDSA.sol";
import { EfficientHashLib } from "solady-0.1.24/utils/EfficientHashLib.sol";
abstract contract HoprNodeSafeRegistryEvents {
/**
* Emitted once a safe and node pair gets registered
*/
event RegisteredNodeSafe(address indexed safeAddress, address indexed nodeAddress);
/**
* Emitted once a safe and node pair gets deregistered
*/
event DeregisteredNodeSafe(address indexed safeAddress, address indexed nodeAddress);
/**
* Emitted once the domain separator is updated.
*/
event DomainSeparatorUpdated(bytes32 indexed domainSeparator);
}
/**
* &&&&
* &&&&
* &&&&
* &&&& &&&&&&&&& &&&&&&&&&&&& &&&&&&&&&&/ &&&&.&&&&&&&&&
* &&&&&&&&& &&&&& &&&&&& &&&&&, &&&&& &&&&& &&&&&&&& &&&&
* &&&&&& &&&& &&&&# &&&& &&&&& &&&&& &&&&&& &&&&&
* &&&&& &&&&/ &&&& &&&& #&&&& &&&& &&&&&
* &&&& &&&& &&&&& &&&& &&&& &&&&& &&&&&
* %%%% /%%%% %%%%%% %%%%%% %%%% %%%%%%%%% %%%%%
* %%%%% %%%% %%%%%%%%%%% %%%% %%%%%% %%%%
* %%%%
* %%%%
* %%%%
*
* @title HoprNodeSafeRegistry
* @dev Node safe must prove that the Safe is the only authorized controller of
* the CHAIN_KEY address. This link between the Safe and node's chain-key address
* should be registered upon successful verification
*
* The CHAIN_KEY address should not be a contract
* The Safe addres should be a contract
* This implies that Safe and CHAIN_KEY address cannot be the same.
*
* This contract is meant to be deployed as a standalone contract
*/
contract HoprNodeSafeRegistry is HoprNodeSafeRegistryEvents {
// Node already has mapped to Safe
error NodeHasSafe();
// Not a valid Safe address;
error NotValidSafe();
// Not a valid signature from node;
error NotValidSignatureFromNode();
// Safe address is zero
error SafeAddressZero();
// Node address is zero
error NodeAddressZero();
// Node address is a contract
error NodeIsContract();
// Provided address is not a member of an enabled NodeManagementModule
error NodeNotModuleMember();
// Structure to store the mapping between nodes and their associated Safe contracts
struct NodeSafeRecord {
address safeAddress;
uint96 nodeSigNonce;
}
// Structure to represent a node-safe pair with a nonce
struct NodeSafeNonce {
address safeAddress;
address nodeChainKeyAddress;
uint256 nodeSigNonce;
}
// Currently deployed version, starting with 1.0.0
string public constant VERSION = "1.0.0";
bytes32 public domainSeparator;
mapping(address => NodeSafeRecord) _nodeToSafe;
// NodeSafeNonce struct type hash.
// keccak256("NodeSafeNonce(address safeAddress,address nodeChainKeyAddress,uint256 nodeSigNonce)");
bytes32 public constant NODE_SAFE_TYPEHASH = hex"a8ac7aed128d1a2da0773fecc80b6265d15f7e62bf4401eb23bd46c3fcf5d2f8";
// start and end point for linked list of modules
address private constant SENTINEL_MODULES = address(0x1);
// page size of querying modules
uint256 private constant PAGE_SIZE = 100;
/**
* @dev Constructor function to initialize the contract state.
* Computes the domain separator for EIP-712 verification.
*/
constructor() {
// compute the domain separator on deployment
updateDomainSeparator();
}
/**
* @dev Returns the Safe address associated with a specific node address.
* @param nodeAddress The address of the Hopr node.
* @return safeAddress The associated Safe address.
*/
function nodeToSafe(address nodeAddress) external view returns (address) {
return _nodeToSafe[nodeAddress].safeAddress;
}
/**
* @dev Returns the nonce of the signature for a specific node address.
* @param nodeAddress The address of the Hopr node.
* @return nodeSigNonce The nonce of the node's signature.
*/
function nodeSigNonce(address nodeAddress) external view returns (uint256) {
return _nodeToSafe[nodeAddress].nodeSigNonce;
}
/**
* @dev Checks whether a specific node-safe combination is registered.
* @param safeAddress Address of safe
* @param nodeChainKeyAddress Address of node
* @return registered Whether the node-safe combination is registered.
*/
function isNodeSafeRegistered(address safeAddress, address nodeChainKeyAddress) external view returns (bool) {
// If node is not registered to any safe, return false
if (_nodeToSafe[nodeChainKeyAddress].safeAddress == address(0)) {
return false;
}
return _nodeToSafe[nodeChainKeyAddress].safeAddress == safeAddress;
}
/**
* @dev Register the Safe with a signature from the node.
* This function can be called by any party.
* @param safeAddress Address of safe
* @param nodeChainKeyAddress Address of node
* @param sig The signature provided by the node.
*/
function registerSafeWithNodeSig(address safeAddress, address nodeChainKeyAddress, bytes calldata sig) external {
// check adminKeyAddress has added HOPR tokens to the staking contract.
// Compute the hash of the struct according to EIP712 guidelines
// using assembly for gas optimization (-95 gas)
bytes32 hashStruct = EfficientHashLib.hash(
uint256(NODE_SAFE_TYPEHASH),
uint256(uint160(safeAddress)),
uint256(uint160(nodeChainKeyAddress)),
uint256(_nodeToSafe[nodeChainKeyAddress].nodeSigNonce)
);
// Build the typed digest for signature verification
/// forge-lint: disable-next-line(asm-keccak256)
bytes32 registerHash = keccak256(abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator, hashStruct));
// Verify that the signature is from nodeChainKeyAddress
(address recovered, ECDSA.RecoverError error,) = ECDSA.tryRecover(registerHash, sig);
if (error != ECDSA.RecoverError.NoError || recovered != nodeChainKeyAddress) {
revert NotValidSignatureFromNode();
}
// store those state, emit events etc.
addNodeSafe(safeAddress, nodeChainKeyAddress);
}
/**
* @dev Deregisters a Hopr node from its associated Safe and emits relevant events.
* This function can only be called by the associated Safe.
* @notice This function does not perform additional checks on whether the node is
* registered in the active node management module.
* @param nodeAddr The address of the Hopr node to be deregistered.
*/
function deregisterNodeBySafe(address nodeAddr) external {
// check this node was registered to the caller
if (_nodeToSafe[nodeAddr].safeAddress != msg.sender) {
revert NotValidSafe();
}
// Update the state and emit the event
_nodeToSafe[nodeAddr].safeAddress = address(0);
emit DeregisteredNodeSafe(msg.sender, nodeAddr);
}
/**
* @dev Registers a Safe by the node through a direct function call.
* This function is meant to be called by the Hopr node itself.
* @param safeAddr The address of the Safe to be registered.
*/
function registerSafeByNode(address safeAddr) external {
addNodeSafe(safeAddr, msg.sender);
}
/**
* @dev Recomputes the domain separator in case of a network fork or update.
* This function should be called by anyone when required.
* An event is emitted when the domain separator is updated
*/
function updateDomainSeparator() public {
// following encoding guidelines of EIP712, using assembly for gas optimization (-60 gas)
bytes32 newDomainSeparator = EfficientHashLib.hash(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes("NodeSafeRegistry")),
keccak256(bytes(VERSION)),
bytes32(block.chainid),
bytes32(uint256(uint160(address(this))))
);
if (newDomainSeparator != domainSeparator) {
domainSeparator = newDomainSeparator;
emit DomainSeparatorUpdated(domainSeparator);
}
}
/**
* @dev Internal function to store a node-safe pair and emit relevant events.
* @notice This function does not perform additional checks on whether the node is
* registered in the active node management module.
* @param safeAddress Address of safe
* @param nodeChainKeyAddress Address of node
*/
function addNodeSafe(address safeAddress, address nodeChainKeyAddress) internal {
// Safe address cannot be zero
if (safeAddress == address(0)) {
revert SafeAddressZero();
}
// Safe address cannot be zero
if (nodeChainKeyAddress == address(0)) {
revert NodeAddressZero();
}
// Ensure that the node address is not a contract address
if (nodeChainKeyAddress.code.length > 0) {
revert NodeIsContract();
}
// check this node hasn't been registered ower
if (_nodeToSafe[nodeChainKeyAddress].safeAddress != address(0)) {
revert NodeHasSafe();
}
NodeSafeRecord storage record = _nodeToSafe[nodeChainKeyAddress];
// update record
record.safeAddress = safeAddress;
record.nodeSigNonce++; // as of Solidity 0.8, this reverts on overflows
// update and emit event
emit RegisteredNodeSafe(safeAddress, nodeChainKeyAddress);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.20;
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS
}
/**
* @dev The signature derives the `address(0)`.
*/
error ECDSAInvalidSignature();
/**
* @dev The signature has an invalid length.
*/
error ECDSAInvalidSignatureLength(uint256 length);
/**
* @dev The signature has an S value that is in the upper half order.
*/
error ECDSAInvalidSignatureS(bytes32 s);
/**
* @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not
* return address(0) without also returning an error description. Errors are documented using an enum (error type)
* and a bytes32 providing additional information about the error.
*
* If no error is returned, then the address can be used for verification purposes.
*
* The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*/
function tryRecover(
bytes32 hash,
bytes memory signature
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
assembly ("memory-safe") {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[ERC-2098 short signatures]
*/
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
unchecked {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
// We do not check for an overflow here since the shift operation results in 0 or 1.
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*/
function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS, s);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature, bytes32(0));
}
return (signer, RecoverError.NoError, bytes32(0));
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.
*/
function _throwError(RecoverError error, bytes32 errorArg) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert ECDSAInvalidSignature();
} else if (error == RecoverError.InvalidSignatureLength) {
revert ECDSAInvalidSignatureLength(uint256(errorArg));
} else if (error == RecoverError.InvalidSignatureS) {
revert ECDSAInvalidSignatureS(errorArg);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice Library for efficiently performing keccak256 hashes.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/EfficientHashLib.sol)
/// @dev To avoid stack-too-deep, you can use:
/// ```
/// bytes32[] memory buffer = EfficientHashLib.malloc(10);
/// EfficientHashLib.set(buffer, 0, value0);
/// ..
/// EfficientHashLib.set(buffer, 9, value9);
/// bytes32 finalHash = EfficientHashLib.hash(buffer);
/// ```
library EfficientHashLib {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* MALLOC-LESS HASHING OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns `keccak256(abi.encode(v0))`.
function hash(bytes32 v0) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, v0)
result := keccak256(0x00, 0x20)
}
}
/// @dev Returns `keccak256(abi.encode(v0))`.
function hash(uint256 v0) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, v0)
result := keccak256(0x00, 0x20)
}
}
/// @dev Returns `keccak256(abi.encode(v0, v1))`.
function hash(bytes32 v0, bytes32 v1) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, v0)
mstore(0x20, v1)
result := keccak256(0x00, 0x40)
}
}
/// @dev Returns `keccak256(abi.encode(v0, v1))`.
function hash(uint256 v0, uint256 v1) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, v0)
mstore(0x20, v1)
result := keccak256(0x00, 0x40)
}
}
/// @dev Returns `keccak256(abi.encode(v0, v1, v2))`.
function hash(bytes32 v0, bytes32 v1, bytes32 v2) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
result := keccak256(m, 0x60)
}
}
/// @dev Returns `keccak256(abi.encode(v0, v1, v2))`.
function hash(uint256 v0, uint256 v1, uint256 v2) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
result := keccak256(m, 0x60)
}
}
/// @dev Returns `keccak256(abi.encode(v0, v1, v2, v3))`.
function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
result := keccak256(m, 0x80)
}
}
/// @dev Returns `keccak256(abi.encode(v0, v1, v2, v3))`.
function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
result := keccak256(m, 0x80)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v4))`.
function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3, bytes32 v4)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
result := keccak256(m, 0xa0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v4))`.
function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3, uint256 v4)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
result := keccak256(m, 0xa0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v5))`.
function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3, bytes32 v4, bytes32 v5)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
result := keccak256(m, 0xc0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v5))`.
function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3, uint256 v4, uint256 v5)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
result := keccak256(m, 0xc0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v6))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
result := keccak256(m, 0xe0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v6))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
result := keccak256(m, 0xe0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v7))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6,
bytes32 v7
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
result := keccak256(m, 0x100)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v7))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6,
uint256 v7
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
result := keccak256(m, 0x100)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v8))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6,
bytes32 v7,
bytes32 v8
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
result := keccak256(m, 0x120)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v8))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6,
uint256 v7,
uint256 v8
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
result := keccak256(m, 0x120)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v9))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6,
bytes32 v7,
bytes32 v8,
bytes32 v9
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
result := keccak256(m, 0x140)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v9))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6,
uint256 v7,
uint256 v8,
uint256 v9
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
result := keccak256(m, 0x140)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v10))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6,
bytes32 v7,
bytes32 v8,
bytes32 v9,
bytes32 v10
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
result := keccak256(m, 0x160)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v10))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6,
uint256 v7,
uint256 v8,
uint256 v9,
uint256 v10
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
result := keccak256(m, 0x160)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v11))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6,
bytes32 v7,
bytes32 v8,
bytes32 v9,
bytes32 v10,
bytes32 v11
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
mstore(add(m, 0x160), v11)
result := keccak256(m, 0x180)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v11))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6,
uint256 v7,
uint256 v8,
uint256 v9,
uint256 v10,
uint256 v11
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
mstore(add(m, 0x160), v11)
result := keccak256(m, 0x180)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v12))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6,
bytes32 v7,
bytes32 v8,
bytes32 v9,
bytes32 v10,
bytes32 v11,
bytes32 v12
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
mstore(add(m, 0x160), v11)
mstore(add(m, 0x180), v12)
result := keccak256(m, 0x1a0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v12))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6,
uint256 v7,
uint256 v8,
uint256 v9,
uint256 v10,
uint256 v11,
uint256 v12
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
mstore(add(m, 0x160), v11)
mstore(add(m, 0x180), v12)
result := keccak256(m, 0x1a0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v13))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6,
bytes32 v7,
bytes32 v8,
bytes32 v9,
bytes32 v10,
bytes32 v11,
bytes32 v12,
bytes32 v13
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
mstore(add(m, 0x160), v11)
mstore(add(m, 0x180), v12)
mstore(add(m, 0x1a0), v13)
result := keccak256(m, 0x1c0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v13))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6,
uint256 v7,
uint256 v8,
uint256 v9,
uint256 v10,
uint256 v11,
uint256 v12,
uint256 v13
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
mstore(add(m, 0x160), v11)
mstore(add(m, 0x180), v12)
mstore(add(m, 0x1a0), v13)
result := keccak256(m, 0x1c0)
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* BYTES32 BUFFER HASHING OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns `keccak256(abi.encode(buffer[0], .., buffer[buffer.length - 1]))`.
function hash(bytes32[] memory buffer) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
result := keccak256(add(buffer, 0x20), shl(5, mload(buffer)))
}
}
/// @dev Sets `buffer[i]` to `value`, without a bounds check.
/// Returns the `buffer` for function chaining.
function set(bytes32[] memory buffer, uint256 i, bytes32 value)
internal
pure
returns (bytes32[] memory)
{
/// @solidity memory-safe-assembly
assembly {
mstore(add(buffer, shl(5, add(1, i))), value)
}
return buffer;
}
/// @dev Sets `buffer[i]` to `value`, without a bounds check.
/// Returns the `buffer` for function chaining.
function set(bytes32[] memory buffer, uint256 i, uint256 value)
internal
pure
returns (bytes32[] memory)
{
/// @solidity memory-safe-assembly
assembly {
mstore(add(buffer, shl(5, add(1, i))), value)
}
return buffer;
}
/// @dev Returns `new bytes32[](n)`, without zeroing out the memory.
function malloc(uint256 n) internal pure returns (bytes32[] memory buffer) {
/// @solidity memory-safe-assembly
assembly {
buffer := mload(0x40)
mstore(buffer, n)
mstore(0x40, add(shl(5, add(1, n)), buffer))
}
}
/// @dev Frees memory that has been allocated for `buffer`.
/// No-op if `buffer.length` is zero, or if new memory has been allocated after `buffer`.
function free(bytes32[] memory buffer) internal pure {
/// @solidity memory-safe-assembly
assembly {
let n := mload(buffer)
mstore(shl(6, lt(iszero(n), eq(add(shl(5, add(1, n)), buffer), mload(0x40)))), buffer)
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* EQUALITY CHECKS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns `a == abi.decode(b, (bytes32))`.
function eq(bytes32 a, bytes memory b) internal pure returns (bool result) {
/// @solidity memory-safe-assembly
assembly {
result := and(eq(0x20, mload(b)), eq(a, mload(add(b, 0x20))))
}
}
/// @dev Returns `abi.decode(a, (bytes32)) == a`.
function eq(bytes memory a, bytes32 b) internal pure returns (bool result) {
/// @solidity memory-safe-assembly
assembly {
result := and(eq(0x20, mload(a)), eq(b, mload(add(a, 0x20))))
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* BYTE SLICE HASHING OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the keccak256 of the slice from `start` to `end` (exclusive).
/// `start` and `end` are byte offsets.
function hash(bytes memory b, uint256 start, uint256 end)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let n := mload(b)
end := xor(end, mul(xor(end, n), lt(n, end)))
start := xor(start, mul(xor(start, n), lt(n, start)))
result := keccak256(add(add(b, 0x20), start), mul(gt(end, start), sub(end, start)))
}
}
/// @dev Returns the keccak256 of the slice from `start` to the end of the bytes.
function hash(bytes memory b, uint256 start) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let n := mload(b)
start := xor(start, mul(xor(start, n), lt(n, start)))
result := keccak256(add(add(b, 0x20), start), mul(gt(n, start), sub(n, start)))
}
}
/// @dev Returns the keccak256 of the bytes.
function hash(bytes memory b) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
result := keccak256(add(b, 0x20), mload(b))
}
}
/// @dev Returns the keccak256 of the slice from `start` to `end` (exclusive).
/// `start` and `end` are byte offsets.
function hashCalldata(bytes calldata b, uint256 start, uint256 end)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
end := xor(end, mul(xor(end, b.length), lt(b.length, end)))
start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
let n := mul(gt(end, start), sub(end, start))
calldatacopy(mload(0x40), add(b.offset, start), n)
result := keccak256(mload(0x40), n)
}
}
/// @dev Returns the keccak256 of the slice from `start` to the end of the bytes.
function hashCalldata(bytes calldata b, uint256 start) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
let n := mul(gt(b.length, start), sub(b.length, start))
calldatacopy(mload(0x40), add(b.offset, start), n)
result := keccak256(mload(0x40), n)
}
}
/// @dev Returns the keccak256 of the bytes.
function hashCalldata(bytes calldata b) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
calldatacopy(mload(0x40), b.offset, b.length)
result := keccak256(mload(0x40), b.length)
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* SHA2-256 HELPERS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns `sha256(abi.encode(b))`. Yes, it's more efficient.
function sha2(bytes32 b) internal view returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, b)
result := mload(staticcall(gas(), 2, 0x00, 0x20, 0x01, 0x20))
if iszero(returndatasize()) { invalid() }
}
}
/// @dev Returns the sha256 of the slice from `start` to `end` (exclusive).
/// `start` and `end` are byte offsets.
function sha2(bytes memory b, uint256 start, uint256 end)
internal
view
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let n := mload(b)
end := xor(end, mul(xor(end, n), lt(n, end)))
start := xor(start, mul(xor(start, n), lt(n, start)))
// forgefmt: disable-next-item
result := mload(staticcall(gas(), 2, add(add(b, 0x20), start),
mul(gt(end, start), sub(end, start)), 0x01, 0x20))
if iszero(returndatasize()) { invalid() }
}
}
/// @dev Returns the sha256 of the slice from `start` to the end of the bytes.
function sha2(bytes memory b, uint256 start) internal view returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let n := mload(b)
start := xor(start, mul(xor(start, n), lt(n, start)))
// forgefmt: disable-next-item
result := mload(staticcall(gas(), 2, add(add(b, 0x20), start),
mul(gt(n, start), sub(n, start)), 0x01, 0x20))
if iszero(returndatasize()) { invalid() }
}
}
/// @dev Returns the sha256 of the bytes.
function sha2(bytes memory b) internal view returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
result := mload(staticcall(gas(), 2, add(b, 0x20), mload(b), 0x01, 0x20))
if iszero(returndatasize()) { invalid() }
}
}
/// @dev Returns the sha256 of the slice from `start` to `end` (exclusive).
/// `start` and `end` are byte offsets.
function sha2Calldata(bytes calldata b, uint256 start, uint256 end)
internal
view
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
end := xor(end, mul(xor(end, b.length), lt(b.length, end)))
start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
let n := mul(gt(end, start), sub(end, start))
calldatacopy(mload(0x40), add(b.offset, start), n)
result := mload(staticcall(gas(), 2, mload(0x40), n, 0x01, 0x20))
if iszero(returndatasize()) { invalid() }
}
}
/// @dev Returns the sha256 of the slice from `start` to the end of the bytes.
function sha2Calldata(bytes calldata b, uint256 start) internal view returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
let n := mul(gt(b.length, start), sub(b.length, start))
calldatacopy(mload(0x40), add(b.offset, start), n)
result := mload(staticcall(gas(), 2, mload(0x40), n, 0x01, 0x20))
if iszero(returndatasize()) { invalid() }
}
}
/// @dev Returns the sha256 of the bytes.
function sha2Calldata(bytes calldata b) internal view returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
calldatacopy(mload(0x40), b.offset, b.length)
result := mload(staticcall(gas(), 2, mload(0x40), b.length, 0x01, 0x20))
if iszero(returndatasize()) { invalid() }
}
}
}{
"remappings": [
"forge-std/=../../vendor/solidity/forge-std-1.10.0/src/",
"openzeppelin-contracts-4.4.2/=../../vendor/solidity/openzeppelin-contracts-4.4.2/contracts/",
"openzeppelin-contracts-5.4.0/=../../vendor/solidity/openzeppelin-contracts-upgradeable-5.4.0/lib/openzeppelin-contracts/contracts/",
"safe-contracts-1.4.1/=../../vendor/solidity/safe-contracts-1.4.1/contracts/",
"safe-contracts-1.5.0/=../../vendor/solidity/safe-contracts-1.5.0/contracts/",
"openzeppelin-contracts-upgradeable-5.4.0/=../../vendor/solidity/openzeppelin-contracts-upgradeable-5.4.0/contracts/",
"solcrypto/=../../vendor/solidity/solcrypto/contracts/",
"solady-0.1.24/=../../vendor/solidity/solady-v0.1.24/src/",
"@openzeppelin/=../../vendor/solidity/openzeppelin-contracts-upgradeable-5.4.0/lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "prague",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NodeAddressZero","type":"error"},{"inputs":[],"name":"NodeHasSafe","type":"error"},{"inputs":[],"name":"NodeIsContract","type":"error"},{"inputs":[],"name":"NodeNotModuleMember","type":"error"},{"inputs":[],"name":"NotValidSafe","type":"error"},{"inputs":[],"name":"NotValidSignatureFromNode","type":"error"},{"inputs":[],"name":"SafeAddressZero","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"safeAddress","type":"address"},{"indexed":true,"internalType":"address","name":"nodeAddress","type":"address"}],"name":"DeregisteredNodeSafe","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"domainSeparator","type":"bytes32"}],"name":"DomainSeparatorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"safeAddress","type":"address"},{"indexed":true,"internalType":"address","name":"nodeAddress","type":"address"}],"name":"RegisteredNodeSafe","type":"event"},{"inputs":[],"name":"NODE_SAFE_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nodeAddr","type":"address"}],"name":"deregisterNodeBySafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"domainSeparator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"safeAddress","type":"address"},{"internalType":"address","name":"nodeChainKeyAddress","type":"address"}],"name":"isNodeSafeRegistered","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nodeAddress","type":"address"}],"name":"nodeSigNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nodeAddress","type":"address"}],"name":"nodeToSafe","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"safeAddr","type":"address"}],"name":"registerSafeByNode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"safeAddress","type":"address"},{"internalType":"address","name":"nodeChainKeyAddress","type":"address"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"registerSafeWithNodeSig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateDomainSeparator","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
0x608060405234801561000f575f5ffd5b5061001861001d565b610119565b604080518082018252601081526f4e6f646553616665526567697374727960801b6020918201528151808301835260058152640312e302e360dc1b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81527f447fbad4d46bbc04590cba6c2c058e72910ea40398cd34085373b98ea4daa0e8918101919091527f06c015bd22b4c69690933c1058878ebdfef31f9aaae40bbe86d8a09fe1b2972c9181019190915246606082015230608082015260a090205f548114610116575f81815560405182917f771f5240ae5fd8a7640d3fb82fa70aab2fb1dbf35f2ef464f8509946717664c591a25b50565b61094f806101265f395ff3fe608060405234801561000f575f5ffd5b506004361061009b575f3560e01c806389ccfe891161006357806389ccfe891461016757806391607c4c1461016f578063aa90f2a514610182578063f698da25146101ba578063ffa1ad74146101c2575f5ffd5b806337480abd1461009f57806349d215e1146100c75780637f935931146100dc57806384b0dec2146100ef57806389978c4014610124575b5f5ffd5b6100b26100ad3660046107bf565b6101f3565b60405190151581526020015b60405180910390f35b6100da6100d53660046107f0565b610241565b005b6100da6100ea36600461087a565b6103a0565b6101167fa8ac7aed128d1a2da0773fecc80b6265d15f7e62bf4401eb23bd46c3fcf5d2f881565b6040519081526020016100be565b61014f61013236600461087a565b6001600160a01b039081165f908152600160205260409020541690565b6040516001600160a01b0390911681526020016100be565b6100da6103ad565b6100da61017d36600461087a565b6104a8565b61011661019036600461087a565b6001600160a01b03165f90815260016020526040902054600160a01b90046001600160601b031690565b6101165f5481565b6101e6604051806040016040528060058152602001640312e302e360dc1b81525081565b6040516100be919061089a565b6001600160a01b038181165f9081526001602052604081205490911661021a57505f61023b565b506001600160a01b038181165f908152600160205260409020548116908316145b92915050565b6001600160a01b038381165f8181526001602090815260408083205481517fa8ac7aed128d1a2da0773fecc80b6265d15f7e62bf4401eb23bd46c3fcf5d2f88152958a1692860192909252840192909252600160a01b9091046001600160601b0316606083015260809091205f8054604051601960f81b6020820152600160f81b6021820152602281019190915260428101839052919250906062016040516020818303038152906040528051906020012090505f5f6103368387878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061053092505050565b5090925090505f81600381111561034f5761034f6108cf565b14158061036e5750866001600160a01b0316826001600160a01b031614155b1561038c5760405163b4c91ffb60e01b815260040160405180910390fd5b6103968888610579565b5050505050505050565b6103aa8133610579565b50565b604080518082018252601081526f4e6f646553616665526567697374727960801b6020918201528151808301835260058152640312e302e360dc1b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81527f447fbad4d46bbc04590cba6c2c058e72910ea40398cd34085373b98ea4daa0e8918101919091527f06c015bd22b4c69690933c1058878ebdfef31f9aaae40bbe86d8a09fe1b2972c9181019190915246606082015230608082015260a090205f5481146103aa575f81815560405182917f771f5240ae5fd8a7640d3fb82fa70aab2fb1dbf35f2ef464f8509946717664c591a250565b6001600160a01b038181165f908152600160205260409020541633146104e1576040516315bfa15560e21b815260040160405180910390fd5b6001600160a01b0381165f8181526001602052604080822080546001600160a01b03191690555133917f1eb3e9b31552ebe06015df6569e31abbec0e73a88c3ccdd9fead65c4378b4e5091a350565b5f5f5f8351604103610567576020840151604085015160608601515f1a610559888285856106dc565b955095509550505050610572565b505081515f91506002905b9250925092565b6001600160a01b0382166105a0576040516314e7922160e01b815260040160405180910390fd5b6001600160a01b0381166105c757604051633e876a9360e11b815260040160405180910390fd5b6001600160a01b0381163b156105f057604051631f829f0360e21b815260040160405180910390fd5b6001600160a01b038181165f908152600160205260409020541615610628576040516367dc300160e01b815260040160405180910390fd5b6001600160a01b038181165f90815260016020526040902080546001600160a01b03191691841691909117808255600160a01b90046001600160601b0316816014610672836108e3565b91906101000a8154816001600160601b0302191690836001600160601b0316021790555050816001600160a01b0316836001600160a01b03167f776da40cbf2c223552661bd48502ceb72409b3362bb0c66d8989bd7e20e4497d60405160405180910390a3505050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084111561071557505f9150600390508261079a565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610766573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b03811661079157505f92506001915082905061079a565b92505f91508190505b9450945094915050565b80356001600160a01b03811681146107ba575f5ffd5b919050565b5f5f604083850312156107d0575f5ffd5b6107d9836107a4565b91506107e7602084016107a4565b90509250929050565b5f5f5f5f60608587031215610803575f5ffd5b61080c856107a4565b935061081a602086016107a4565b9250604085013567ffffffffffffffff811115610835575f5ffd5b8501601f81018713610845575f5ffd5b803567ffffffffffffffff81111561085b575f5ffd5b87602082840101111561086c575f5ffd5b949793965060200194505050565b5f6020828403121561088a575f5ffd5b610893826107a4565b9392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b634e487b7160e01b5f52602160045260245ffd5b5f6001600160601b0382166001600160601b03810361091057634e487b7160e01b5f52601160045260245ffd5b6001019291505056fea26469706673582212204696231eca19ccb446bc664ab9e925c9ca98961ba31abff9cbdba0b301bb69ea64736f6c634300081e0033
Deployed Bytecode
0x608060405234801561000f575f5ffd5b506004361061009b575f3560e01c806389ccfe891161006357806389ccfe891461016757806391607c4c1461016f578063aa90f2a514610182578063f698da25146101ba578063ffa1ad74146101c2575f5ffd5b806337480abd1461009f57806349d215e1146100c75780637f935931146100dc57806384b0dec2146100ef57806389978c4014610124575b5f5ffd5b6100b26100ad3660046107bf565b6101f3565b60405190151581526020015b60405180910390f35b6100da6100d53660046107f0565b610241565b005b6100da6100ea36600461087a565b6103a0565b6101167fa8ac7aed128d1a2da0773fecc80b6265d15f7e62bf4401eb23bd46c3fcf5d2f881565b6040519081526020016100be565b61014f61013236600461087a565b6001600160a01b039081165f908152600160205260409020541690565b6040516001600160a01b0390911681526020016100be565b6100da6103ad565b6100da61017d36600461087a565b6104a8565b61011661019036600461087a565b6001600160a01b03165f90815260016020526040902054600160a01b90046001600160601b031690565b6101165f5481565b6101e6604051806040016040528060058152602001640312e302e360dc1b81525081565b6040516100be919061089a565b6001600160a01b038181165f9081526001602052604081205490911661021a57505f61023b565b506001600160a01b038181165f908152600160205260409020548116908316145b92915050565b6001600160a01b038381165f8181526001602090815260408083205481517fa8ac7aed128d1a2da0773fecc80b6265d15f7e62bf4401eb23bd46c3fcf5d2f88152958a1692860192909252840192909252600160a01b9091046001600160601b0316606083015260809091205f8054604051601960f81b6020820152600160f81b6021820152602281019190915260428101839052919250906062016040516020818303038152906040528051906020012090505f5f6103368387878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061053092505050565b5090925090505f81600381111561034f5761034f6108cf565b14158061036e5750866001600160a01b0316826001600160a01b031614155b1561038c5760405163b4c91ffb60e01b815260040160405180910390fd5b6103968888610579565b5050505050505050565b6103aa8133610579565b50565b604080518082018252601081526f4e6f646553616665526567697374727960801b6020918201528151808301835260058152640312e302e360dc1b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81527f447fbad4d46bbc04590cba6c2c058e72910ea40398cd34085373b98ea4daa0e8918101919091527f06c015bd22b4c69690933c1058878ebdfef31f9aaae40bbe86d8a09fe1b2972c9181019190915246606082015230608082015260a090205f5481146103aa575f81815560405182917f771f5240ae5fd8a7640d3fb82fa70aab2fb1dbf35f2ef464f8509946717664c591a250565b6001600160a01b038181165f908152600160205260409020541633146104e1576040516315bfa15560e21b815260040160405180910390fd5b6001600160a01b0381165f8181526001602052604080822080546001600160a01b03191690555133917f1eb3e9b31552ebe06015df6569e31abbec0e73a88c3ccdd9fead65c4378b4e5091a350565b5f5f5f8351604103610567576020840151604085015160608601515f1a610559888285856106dc565b955095509550505050610572565b505081515f91506002905b9250925092565b6001600160a01b0382166105a0576040516314e7922160e01b815260040160405180910390fd5b6001600160a01b0381166105c757604051633e876a9360e11b815260040160405180910390fd5b6001600160a01b0381163b156105f057604051631f829f0360e21b815260040160405180910390fd5b6001600160a01b038181165f908152600160205260409020541615610628576040516367dc300160e01b815260040160405180910390fd5b6001600160a01b038181165f90815260016020526040902080546001600160a01b03191691841691909117808255600160a01b90046001600160601b0316816014610672836108e3565b91906101000a8154816001600160601b0302191690836001600160601b0316021790555050816001600160a01b0316836001600160a01b03167f776da40cbf2c223552661bd48502ceb72409b3362bb0c66d8989bd7e20e4497d60405160405180910390a3505050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084111561071557505f9150600390508261079a565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610766573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b03811661079157505f92506001915082905061079a565b92505f91508190505b9450945094915050565b80356001600160a01b03811681146107ba575f5ffd5b919050565b5f5f604083850312156107d0575f5ffd5b6107d9836107a4565b91506107e7602084016107a4565b90509250929050565b5f5f5f5f60608587031215610803575f5ffd5b61080c856107a4565b935061081a602086016107a4565b9250604085013567ffffffffffffffff811115610835575f5ffd5b8501601f81018713610845575f5ffd5b803567ffffffffffffffff81111561085b575f5ffd5b87602082840101111561086c575f5ffd5b949793965060200194505050565b5f6020828403121561088a575f5ffd5b610893826107a4565b9392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b634e487b7160e01b5f52602160045260245ffd5b5f6001600160601b0382166001600160601b03810361091057634e487b7160e01b5f52601160045260245ffd5b6001019291505056fea26469706673582212204696231eca19ccb446bc664ab9e925c9ca98961ba31abff9cbdba0b301bb69ea64736f6c634300081e0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in XDAI
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.