Source Code
Latest 25 from a total of 8,851 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer To Hot ... | 42016133 | 39 mins ago | IN | 0 ETH | 0.00000167 | ||||
| Transfer To Hot ... | 42016058 | 42 mins ago | IN | 0 ETH | 0.00000172 | ||||
| Transfer To Hot ... | 42015263 | 1 hr ago | IN | 0 ETH | 0.00000198 | ||||
| Transfer To Hot ... | 42014290 | 1 hr ago | IN | 0 ETH | 0.00000071 | ||||
| Transfer To Hot ... | 42014168 | 1 hr ago | IN | 0 ETH | 0.00000079 | ||||
| Transfer To Hot ... | 42013644 | 2 hrs ago | IN | 0 ETH | 0.00000034 | ||||
| Transfer To Hot ... | 42013268 | 2 hrs ago | IN | 0 ETH | 0.00000027 | ||||
| Transfer To Hot ... | 42012908 | 2 hrs ago | IN | 0 ETH | 0.00000023 | ||||
| Transfer To Hot ... | 42012384 | 2 hrs ago | IN | 0 ETH | 0.00000021 | ||||
| Transfer To Hot ... | 42010778 | 3 hrs ago | IN | 0 ETH | 0.00000022 | ||||
| Transfer To Hot ... | 42010148 | 3 hrs ago | IN | 0 ETH | 0.0000002 | ||||
| Transfer To Hot ... | 42010104 | 4 hrs ago | IN | 0 ETH | 0.00000019 | ||||
| Transfer To Hot ... | 42009593 | 4 hrs ago | IN | 0 ETH | 0.00000021 | ||||
| Transfer To Hot ... | 42007583 | 5 hrs ago | IN | 0 ETH | 0.0000002 | ||||
| Transfer To Hot ... | 42007267 | 5 hrs ago | IN | 0 ETH | 0.00000017 | ||||
| Transfer To Hot ... | 42006458 | 6 hrs ago | IN | 0 ETH | 0.0000002 | ||||
| Transfer To Hot ... | 42005738 | 6 hrs ago | IN | 0 ETH | 0.00000027 | ||||
| Transfer To Hot ... | 42005483 | 6 hrs ago | IN | 0 ETH | 0.00000029 | ||||
| Transfer To Hot ... | 42004763 | 6 hrs ago | IN | 0 ETH | 0.00000043 | ||||
| Transfer To Hot ... | 42004148 | 7 hrs ago | IN | 0 ETH | 0.00000043 | ||||
| Transfer To Hot ... | 42003713 | 7 hrs ago | IN | 0 ETH | 0.00000037 | ||||
| Transfer To Hot ... | 42000278 | 9 hrs ago | IN | 0 ETH | 0.00000021 | ||||
| Transfer To Hot ... | 41999662 | 9 hrs ago | IN | 0 ETH | 0.00000023 | ||||
| Transfer To Hot ... | 41999438 | 9 hrs ago | IN | 0 ETH | 0.0000002 | ||||
| Transfer To Hot ... | 41999362 | 9 hrs ago | IN | 0 ETH | 0.00000022 |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ConditionalWithdrawal
Compiler Version
v0.8.30+commit.73712a01
Optimization Enabled:
Yes with 1 runs
Other Settings:
prague EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.30;
import "./IBank.sol";
import "./IFactRegistry.sol";
import "../deploymentEthereum/ICrossDomainMessenger.sol";
import "openzeppelin-contracts-v5.3.0/contracts/access/AccessControl.sol";
import "openzeppelin-contracts-v5.3.0/contracts/utils/ReentrancyGuardTransient.sol";
contract ConditionalWithdrawal is
AccessControl,
ReentrancyGuardTransient,
IFactRegistry
{
error InvalidTransferRegistry();
error FactNotRegistered();
error FactAlreadyRegistered();
error ZeroAddress();
event FactRegistered(bytes32 fact);
IBank public immutable bank;
address public immutable transferRegistry;
mapping(bytes32 fact => bool registered) public registeredFacts;
// Constant messenger address on every OP-Stack L2 (Base, OP, etc.)
address public constant MESSENGER =
0x4200000000000000000000000000000000000007;
bytes32 public constant SIGNER_ROLE = keccak256("SIGNER_ROLE");
constructor(address _bank, address _transferRegistry) {
if (_bank == address(0)) revert ZeroAddress();
bank = IBank(_bank);
if (_transferRegistry == address(0)) revert ZeroAddress();
transferRegistry = _transferRegistry;
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(SIGNER_ROLE, msg.sender);
}
/// @dev Transfer ETH from one account to the hot wallet account
/// if the inverse transfer was processed on L1.
/// We don't need to verify that the fact was not already processed
/// because we have replay protection on the signature.
/// @param _from The address of the sender.
/// @param _withdrawalDestination The address of the recipient on L1.
/// @param _amount The amount of ETH to transfer.
/// @param _feesAmount The amount of fees to transfer.
/// @param _salt The salt of the fact.
/// @param _signature The signature of the transfer.
/// @param _liquidityProvider LP that sent the funds on L1.
function transferToHotWalletWithFact(
address _from,
address _withdrawalDestination,
uint256 _amount,
uint256 _feesAmount,
uint64 _deadline,
bytes32 _salt,
bytes calldata _signature,
address _liquidityProvider
) external onlyRole(SIGNER_ROLE) nonReentrant {
bytes32 _fact = keccak256(
abi.encode(_withdrawalDestination, _amount, _salt)
);
if (!registeredFacts[_fact]) revert FactNotRegistered();
IBank.EthTransfer memory transfer = IBank.EthTransfer({
from: _from,
to: _liquidityProvider,
amount: _amount,
signedAmount: _amount,
feeRecipient: _liquidityProvider,
feeAmount: _feesAmount,
signedFeeAmount: _feesAmount,
deadline: _deadline,
salt: _salt,
proxy: address(this),
data: abi.encode(_fact),
signature: _signature
});
delete registeredFacts[_fact];
bank.transferEth(transfer);
}
function registerFact(bytes32 _fact) external {
require(msg.sender == MESSENGER, "Not CrossDomainMessenger");
address _from = ICrossDomainMessenger(MESSENGER).xDomainMessageSender();
if (_from != transferRegistry) revert InvalidTransferRegistry();
if (registeredFacts[_fact]) revert FactAlreadyRegistered();
registeredFacts[_fact] = true;
emit FactRegistered(_fact);
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.30;
interface IBank {
/// @dev internal structure that helps with ETH settlement
struct EthTransfer {
address from;
address to;
uint256 amount;
uint256 feeAmount;
address feeRecipient;
uint256 signedAmount;
uint256 signedFeeAmount;
uint64 deadline;
bytes32 salt;
address proxy;
bytes data;
bytes signature;
}
/// @dev Transfer ETH from one account to another.
/// @param _transfer the transfer to perform.
function transferEth(EthTransfer calldata _transfer) external;
function transferAll(EthTransfer[] calldata _transfers) external;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.30;
interface IFactRegistry {
function registerFact(bytes32 _fact) external;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.30;
interface ICrossDomainMessenger {
function sendMessage(
address _receiver,
bytes memory _message,
uint32 _gas
) external;
function xDomainMessageSender() external view returns (address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {ERC165} from "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
mapping(bytes32 role => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
return _roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
if (!hasRole(role, account)) {
_roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
if (hasRole(role, account)) {
_roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (utils/ReentrancyGuardTransient.sol)
pragma solidity ^0.8.24;
import {TransientSlot} from "./TransientSlot.sol";
/**
* @dev Variant of {ReentrancyGuard} that uses transient storage.
*
* NOTE: This variant only works on networks where EIP-1153 is available.
*
* _Available since v5.1._
*/
abstract contract ReentrancyGuardTransient {
using TransientSlot for *;
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant REENTRANCY_GUARD_STORAGE =
0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, REENTRANCY_GUARD_STORAGE.asBoolean().tload() will be false
if (_reentrancyGuardEntered()) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
REENTRANCY_GUARD_STORAGE.asBoolean().tstore(true);
}
function _nonReentrantAfter() private {
REENTRANCY_GUARD_STORAGE.asBoolean().tstore(false);
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return REENTRANCY_GUARD_STORAGE.asBoolean().tload();
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (access/IAccessControl.sol)
pragma solidity ^0.8.20;
/**
* @dev External interface of AccessControl declared to support ERC-165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted to signal this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).
* Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (utils/TransientSlot.sol)
// This file was procedurally generated from scripts/generate/templates/TransientSlot.js.
pragma solidity ^0.8.24;
/**
* @dev Library for reading and writing value-types to specific transient storage slots.
*
* Transient slots are often used to store temporary values that are removed after the current transaction.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* * Example reading and writing values using transient storage:
* ```solidity
* contract Lock {
* using TransientSlot for *;
*
* // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.
* bytes32 internal constant _LOCK_SLOT = 0xf4678858b2b588224636b8522b729e7722d32fc491da849ed75b3fdf3c84f542;
*
* modifier locked() {
* require(!_LOCK_SLOT.asBoolean().tload());
*
* _LOCK_SLOT.asBoolean().tstore(true);
* _;
* _LOCK_SLOT.asBoolean().tstore(false);
* }
* }
* ```
*
* TIP: Consider using this library along with {SlotDerivation}.
*/
library TransientSlot {
/**
* @dev UDVT that represents a slot holding an address.
*/
type AddressSlot is bytes32;
/**
* @dev Cast an arbitrary slot to a AddressSlot.
*/
function asAddress(bytes32 slot) internal pure returns (AddressSlot) {
return AddressSlot.wrap(slot);
}
/**
* @dev UDVT that represents a slot holding a bool.
*/
type BooleanSlot is bytes32;
/**
* @dev Cast an arbitrary slot to a BooleanSlot.
*/
function asBoolean(bytes32 slot) internal pure returns (BooleanSlot) {
return BooleanSlot.wrap(slot);
}
/**
* @dev UDVT that represents a slot holding a bytes32.
*/
type Bytes32Slot is bytes32;
/**
* @dev Cast an arbitrary slot to a Bytes32Slot.
*/
function asBytes32(bytes32 slot) internal pure returns (Bytes32Slot) {
return Bytes32Slot.wrap(slot);
}
/**
* @dev UDVT that represents a slot holding a uint256.
*/
type Uint256Slot is bytes32;
/**
* @dev Cast an arbitrary slot to a Uint256Slot.
*/
function asUint256(bytes32 slot) internal pure returns (Uint256Slot) {
return Uint256Slot.wrap(slot);
}
/**
* @dev UDVT that represents a slot holding a int256.
*/
type Int256Slot is bytes32;
/**
* @dev Cast an arbitrary slot to a Int256Slot.
*/
function asInt256(bytes32 slot) internal pure returns (Int256Slot) {
return Int256Slot.wrap(slot);
}
/**
* @dev Load the value held at location `slot` in transient storage.
*/
function tload(AddressSlot slot) internal view returns (address value) {
assembly ("memory-safe") {
value := tload(slot)
}
}
/**
* @dev Store `value` at location `slot` in transient storage.
*/
function tstore(AddressSlot slot, address value) internal {
assembly ("memory-safe") {
tstore(slot, value)
}
}
/**
* @dev Load the value held at location `slot` in transient storage.
*/
function tload(BooleanSlot slot) internal view returns (bool value) {
assembly ("memory-safe") {
value := tload(slot)
}
}
/**
* @dev Store `value` at location `slot` in transient storage.
*/
function tstore(BooleanSlot slot, bool value) internal {
assembly ("memory-safe") {
tstore(slot, value)
}
}
/**
* @dev Load the value held at location `slot` in transient storage.
*/
function tload(Bytes32Slot slot) internal view returns (bytes32 value) {
assembly ("memory-safe") {
value := tload(slot)
}
}
/**
* @dev Store `value` at location `slot` in transient storage.
*/
function tstore(Bytes32Slot slot, bytes32 value) internal {
assembly ("memory-safe") {
tstore(slot, value)
}
}
/**
* @dev Load the value held at location `slot` in transient storage.
*/
function tload(Uint256Slot slot) internal view returns (uint256 value) {
assembly ("memory-safe") {
value := tload(slot)
}
}
/**
* @dev Store `value` at location `slot` in transient storage.
*/
function tstore(Uint256Slot slot, uint256 value) internal {
assembly ("memory-safe") {
tstore(slot, value)
}
}
/**
* @dev Load the value held at location `slot` in transient storage.
*/
function tload(Int256Slot slot) internal view returns (int256 value) {
assembly ("memory-safe") {
value := tload(slot)
}
}
/**
* @dev Store `value` at location `slot` in transient storage.
*/
function tstore(Int256Slot slot, int256 value) internal {
assembly ("memory-safe") {
tstore(slot, value)
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"ds-test/=lib/forge-std/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"openzeppelin-contracts-v3.0.0/=lib/openzeppelin-contracts-v3.0.0/",
"openzeppelin-contracts-v4.6.0/=lib/openzeppelin-contracts-v4.6.0/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts-v5.3.0/contracts/",
"openzeppelin-contracts-v5.3.0/=lib/openzeppelin-contracts-v5.3.0/"
],
"optimizer": {
"enabled": true,
"runs": 1
},
"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":[{"internalType":"address","name":"_bank","type":"address"},{"internalType":"address","name":"_transferRegistry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"FactAlreadyRegistered","type":"error"},{"inputs":[],"name":"FactNotRegistered","type":"error"},{"inputs":[],"name":"InvalidTransferRegistry","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"fact","type":"bytes32"}],"name":"FactRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MESSENGER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SIGNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bank","outputs":[{"internalType":"contract IBank","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_fact","type":"bytes32"}],"name":"registerFact","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"fact","type":"bytes32"}],"name":"registeredFacts","outputs":[{"internalType":"bool","name":"registered","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"transferRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_withdrawalDestination","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_feesAmount","type":"uint256"},{"internalType":"uint64","name":"_deadline","type":"uint64"},{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"address","name":"_liquidityProvider","type":"address"}],"name":"transferToHotWalletWithFact","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60c060405234801561000f575f5ffd5b50604051610d68380380610d6883398101604081905261002e91610190565b6001600160a01b0382166100555760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0380831660805281166100825760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660a0526100995f336100cc565b506100c47fe2f4eaae4a9751e85a3e4a7b9587827a877f29914755229b07a7b2da98285f70336100cc565b5050506101c1565b5f828152602081815260408083206001600160a01b038516845290915281205460ff1661016c575f838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556101243390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161016f565b505f5b92915050565b80516001600160a01b038116811461018b575f5ffd5b919050565b5f5f604083850312156101a1575f5ffd5b6101aa83610175565b91506101b860208401610175565b90509250929050565b60805160a051610b786101f05f395f818161010a015261039001525f818161018401526106160152610b785ff3fe608060405234801561000f575f5ffd5b50600436106100b8575f3560e01c806301ffc9a7146100bc578063248a9ca3146100e457806329ab4dcb146101055780632f2ff15d1461014457806336568abe146101595780636d5d6eb71461016c57806376cdb03b1461017f57806391d14854146101a6578063927ede2d146101b95780639ed606d7146101c7578063a1ebf35d146101da578063a217fddf146101ee578063c383748f146101f5578063d547741f14610217575b5f5ffd5b6100cf6100ca366004610853565b61022a565b60405190151581526020015b60405180910390f35b6100f76100f2366004610881565b610260565b6040519081526020016100db565b61012c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100db565b6101576101523660046108c9565b610274565b005b6101576101673660046108c9565b610296565b61015761017a366004610881565b6102ce565b61012c7f000000000000000000000000000000000000000000000000000000000000000081565b6100cf6101b43660046108c9565b610460565b61012c6007602160991b0181565b6101576101d53660046108f7565b610488565b6100f75f516020610b035f395f51905f5281565b6100f75f81565b6100cf610203366004610881565b60016020525f908152604090205460ff1681565b6101576102253660046108c9565b61068e565b5f6001600160e01b03198216637965db0b60e01b148061025a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f9081526020819052604090206001015490565b61027d82610260565b610286816106aa565b61029083836106b7565b50505050565b6001600160a01b03811633146102bf5760405163334bd91960e11b815260040160405180910390fd5b6102c98282610746565b505050565b336007602160991b01146103245760405162461bcd60e51b81526020600482015260186024820152772737ba1021b937b9b9a237b6b0b4b726b2b9b9b2b733b2b960411b60448201526064015b60405180910390fd5b5f6007602160991b016001600160a01b0316636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610368573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061038c91906109d6565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b0316146103e0576040516342633ed160e01b815260040160405180910390fd5b5f8281526001602052604090205460ff161561040f57604051630fcb171360e21b815260040160405180910390fd5b5f82815260016020818152604092839020805460ff191690921790915590518381527f9b55a62205cf41784a81d1eb40ac16f5c1347d324e28065a742c53564b9c6a32910160405180910390a15050565b5f918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b5f516020610b035f395f51905f5261049f816106aa565b6104a76107af565b604080516001600160a01b038b166020820152908101899052606081018690525f9060800160408051601f1981840301815291815281516020928301205f818152600190935291205490915060ff1661051357604051634d6b988560e01b815260040160405180910390fd5b5f6040518061018001604052808d6001600160a01b03168152602001856001600160a01b031681526020018b81526020018a8152602001856001600160a01b031681526020018b81526020018a8152602001896001600160401b03168152602001888152602001306001600160a01b031681526020018360405160200161059c91815260200190565b604051602081830303815290604052815260200187878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201829052509390945250508481526001602052604090819020805460ff1916905551632f8bc8f360e11b8152919250506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690635f1791e69061064b908490600401610a1f565b5f604051808303815f87803b158015610662575f5ffd5b505af1158015610674573d5f5f3e3d5ffd5b5050505050506106826107f8565b50505050505050505050565b61069782610260565b6106a0816106aa565b6102908383610746565b6106b4813361080f565b50565b5f6106c28383610460565b61073f575f838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556106f73390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161025a565b505f61025a565b5f6107518383610460565b1561073f575f838152602081815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161025a565b5f516020610b235f395f51905f525c156107dc57604051633ee5aeb560e01b815260040160405180910390fd5b6107f660015f516020610b235f395f51905f525b9061084c565b565b6107f65f5f516020610b235f395f51905f526107f0565b6108198282610460565b6108485760405163e2517d3f60e01b81526001600160a01b03821660048201526024810183905260440161031b565b5050565b80825d5050565b5f60208284031215610863575f5ffd5b81356001600160e01b03198116811461087a575f5ffd5b9392505050565b5f60208284031215610891575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b03811681146106b4575f5ffd5b80356108c4816108a5565b919050565b5f5f604083850312156108da575f5ffd5b8235915060208301356108ec816108a5565b809150509250929050565b5f5f5f5f5f5f5f5f5f6101008a8c031215610910575f5ffd5b893561091b816108a5565b985060208a013561092b816108a5565b975060408a0135965060608a0135955060808a01356001600160401b0381168114610954575f5ffd5b945060a08a0135935060c08a01356001600160401b03811115610975575f5ffd5b8a015f80601f83018e13610987575f5ffd5b5081356001600160401b0381111561099d575f5ffd5b6020830191508d60208285010111156109b4575f5ffd5b90945092506109c7905060e08b016108b9565b90509295985092959850929598565b5f602082840312156109e6575f5ffd5b815161087a816108a5565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b60208152610a31602082018351610898565b5f6020830151610a446040840182610898565b5060408301516060830152606083015160808301526080830151610a6b60a0840182610898565b5060a083015160c083015260c083015160e083015260e0830151610a9b6101008401826001600160401b03169052565b50610100830151610120830152610120830151610abc610140840182610898565b50610140830151610180610160840152610ada6101a08401826109f1565b9050610160840151601f1984830301610180850152610af982826109f1565b9594505050505056fee2f4eaae4a9751e85a3e4a7b9587827a877f29914755229b07a7b2da98285f709b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220b58ca09d8cf14e8ac2ac3741701d0a6fac758193c9d8a7e2bb72c985ead319fc64736f6c634300081e00330000000000000000000000007473899213aa6a3d321ecc2259f567ef1af2acb8000000000000000000000000dab785f7719108390a26ff8d167e40ae4789f8d7
Deployed Bytecode
0x608060405234801561000f575f5ffd5b50600436106100b8575f3560e01c806301ffc9a7146100bc578063248a9ca3146100e457806329ab4dcb146101055780632f2ff15d1461014457806336568abe146101595780636d5d6eb71461016c57806376cdb03b1461017f57806391d14854146101a6578063927ede2d146101b95780639ed606d7146101c7578063a1ebf35d146101da578063a217fddf146101ee578063c383748f146101f5578063d547741f14610217575b5f5ffd5b6100cf6100ca366004610853565b61022a565b60405190151581526020015b60405180910390f35b6100f76100f2366004610881565b610260565b6040519081526020016100db565b61012c7f000000000000000000000000dab785f7719108390a26ff8d167e40ae4789f8d781565b6040516001600160a01b0390911681526020016100db565b6101576101523660046108c9565b610274565b005b6101576101673660046108c9565b610296565b61015761017a366004610881565b6102ce565b61012c7f0000000000000000000000007473899213aa6a3d321ecc2259f567ef1af2acb881565b6100cf6101b43660046108c9565b610460565b61012c6007602160991b0181565b6101576101d53660046108f7565b610488565b6100f75f516020610b035f395f51905f5281565b6100f75f81565b6100cf610203366004610881565b60016020525f908152604090205460ff1681565b6101576102253660046108c9565b61068e565b5f6001600160e01b03198216637965db0b60e01b148061025a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f9081526020819052604090206001015490565b61027d82610260565b610286816106aa565b61029083836106b7565b50505050565b6001600160a01b03811633146102bf5760405163334bd91960e11b815260040160405180910390fd5b6102c98282610746565b505050565b336007602160991b01146103245760405162461bcd60e51b81526020600482015260186024820152772737ba1021b937b9b9a237b6b0b4b726b2b9b9b2b733b2b960411b60448201526064015b60405180910390fd5b5f6007602160991b016001600160a01b0316636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610368573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061038c91906109d6565b90507f000000000000000000000000dab785f7719108390a26ff8d167e40ae4789f8d76001600160a01b0316816001600160a01b0316146103e0576040516342633ed160e01b815260040160405180910390fd5b5f8281526001602052604090205460ff161561040f57604051630fcb171360e21b815260040160405180910390fd5b5f82815260016020818152604092839020805460ff191690921790915590518381527f9b55a62205cf41784a81d1eb40ac16f5c1347d324e28065a742c53564b9c6a32910160405180910390a15050565b5f918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b5f516020610b035f395f51905f5261049f816106aa565b6104a76107af565b604080516001600160a01b038b166020820152908101899052606081018690525f9060800160408051601f1981840301815291815281516020928301205f818152600190935291205490915060ff1661051357604051634d6b988560e01b815260040160405180910390fd5b5f6040518061018001604052808d6001600160a01b03168152602001856001600160a01b031681526020018b81526020018a8152602001856001600160a01b031681526020018b81526020018a8152602001896001600160401b03168152602001888152602001306001600160a01b031681526020018360405160200161059c91815260200190565b604051602081830303815290604052815260200187878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201829052509390945250508481526001602052604090819020805460ff1916905551632f8bc8f360e11b8152919250506001600160a01b037f0000000000000000000000007473899213aa6a3d321ecc2259f567ef1af2acb81690635f1791e69061064b908490600401610a1f565b5f604051808303815f87803b158015610662575f5ffd5b505af1158015610674573d5f5f3e3d5ffd5b5050505050506106826107f8565b50505050505050505050565b61069782610260565b6106a0816106aa565b6102908383610746565b6106b4813361080f565b50565b5f6106c28383610460565b61073f575f838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556106f73390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161025a565b505f61025a565b5f6107518383610460565b1561073f575f838152602081815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161025a565b5f516020610b235f395f51905f525c156107dc57604051633ee5aeb560e01b815260040160405180910390fd5b6107f660015f516020610b235f395f51905f525b9061084c565b565b6107f65f5f516020610b235f395f51905f526107f0565b6108198282610460565b6108485760405163e2517d3f60e01b81526001600160a01b03821660048201526024810183905260440161031b565b5050565b80825d5050565b5f60208284031215610863575f5ffd5b81356001600160e01b03198116811461087a575f5ffd5b9392505050565b5f60208284031215610891575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b03811681146106b4575f5ffd5b80356108c4816108a5565b919050565b5f5f604083850312156108da575f5ffd5b8235915060208301356108ec816108a5565b809150509250929050565b5f5f5f5f5f5f5f5f5f6101008a8c031215610910575f5ffd5b893561091b816108a5565b985060208a013561092b816108a5565b975060408a0135965060608a0135955060808a01356001600160401b0381168114610954575f5ffd5b945060a08a0135935060c08a01356001600160401b03811115610975575f5ffd5b8a015f80601f83018e13610987575f5ffd5b5081356001600160401b0381111561099d575f5ffd5b6020830191508d60208285010111156109b4575f5ffd5b90945092506109c7905060e08b016108b9565b90509295985092959850929598565b5f602082840312156109e6575f5ffd5b815161087a816108a5565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b60208152610a31602082018351610898565b5f6020830151610a446040840182610898565b5060408301516060830152606083015160808301526080830151610a6b60a0840182610898565b5060a083015160c083015260c083015160e083015260e0830151610a9b6101008401826001600160401b03169052565b50610100830151610120830152610120830151610abc610140840182610898565b50610140830151610180610160840152610ada6101a08401826109f1565b9050610160840151601f1984830301610180850152610af982826109f1565b9594505050505056fee2f4eaae4a9751e85a3e4a7b9587827a877f29914755229b07a7b2da98285f709b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220b58ca09d8cf14e8ac2ac3741701d0a6fac758193c9d8a7e2bb72c985ead319fc64736f6c634300081e0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007473899213aa6a3d321ecc2259f567ef1af2acb8000000000000000000000000dab785f7719108390a26ff8d167e40ae4789f8d7
-----Decoded View---------------
Arg [0] : _bank (address): 0x7473899213aa6A3d321eCC2259F567EF1Af2acb8
Arg [1] : _transferRegistry (address): 0xDAB785F7719108390A26ff8d167e40aE4789F8D7
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000007473899213aa6a3d321ecc2259f567ef1af2acb8
Arg [1] : 000000000000000000000000dab785f7719108390a26ff8d167e40ae4789f8d7
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 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.