Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x099f52b74DFe2435a93b74872DD695EAE80E57E2
Balance 0.000300000 ETH
Nonce 1
Code Size 547 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

547 bytes
0x60806040526004361015610015575b3661014557005b5f3560e01c80638da5cb5b146101005763907be21a0361000e57346100fc5760203660031901126100fc576004356001600160a01b038116908190036100fc57335f9081527f246d4897788137da0dfee54983711d7cec9a265cfb0821648ff88be774e373ce602052604090205460ff16156100e5576bffffffffffffffffffffffff60a01b7f5de96d96f7bd5b0df20e0957dfe48c1f2abf0fa75147ae539b8d798edd281caf5416177f5de96d96f7bd5b0df20e0957dfe48c1f2abf0fa75147ae539b8d798edd281caf555f80f35b63e2517d3f60e01b5f52336004525f60245260445ffd5b5f80fd5b346100fc575f3660031901126100fc577f5de96d96f7bd5b0df20e0957dfe48c1f2abf0fa75147ae539b8d798edd281caf546001600160a01b03166080908152602090f35b5f80356001600160e01b03191681527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c60205260409020546001600160a01b031680156101a9575f8091368280378136915af43d5f803e156101a5573d5ff35b3d5ffd5b606460405162461bcd60e51b815260206004820152602060248201527f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f742065786973746044820152fdfea2646970667358221220de83cdd4c5779591495e69db1ffb3d009d06834d030d5bba56293c14a54672ab64736f6c634300081c0033

Verified Source Code Full Match

Compiler: v0.8.28+commit.7893614a EVM: prague Optimization: Yes (200 runs)
AccessControlInternal.sol 104 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)

pragma solidity ^0.8.20;

import {IAccessControl} from "./IAccessControl.sol";
import {AccessControlStorage} from "./AccessControlStorage.sol";

contract AccessControlInternal is IAccessControl {
    bytes32 constant DEFAULT_ADMIN_ROLE = 0x00; //  Default admin role
    bytes32 constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); //  Pauser role
    bytes32 constant CCIP_OPERATOR_ROLE = keccak256("CCIP_OPERATOR_ROLE"); //  CCIP operator role
    bytes32 constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE"); //  Proposer role
    bytes32 constant MULTISIG_ROLE = keccak256("MULTISIG_ROLE"); //  Multisig role

    /**
     * @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 Reverts with an {AccessControlUnauthorizedAccount} error if `msg.sender`
     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
     */
    function _checkRole(bytes32 role) internal view {
        _checkRole(role, msg.sender);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function _hasRole(bytes32 role, address account) internal view returns (bool) {
        return AccessControlStorage._getAccessControlStorage()._roles[role].hasRole[account];
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function _getRoleAdmin(bytes32 role) internal view returns (bytes32) {
        return AccessControlStorage._getAccessControlStorage()._roles[role].adminRole;
    }

    /**
     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
     * is missing `role`.
     */
    function _checkRole(bytes32 role, address account) internal view {
        if (!_hasRole(role, account)) {
            revert AccessControlUnauthorizedAccount(account, role);
        }
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal {
        bytes32 previousAdminRole = _getRoleAdmin(role);
        AccessControlStorage._getAccessControlStorage()._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 returns (bool) {
        if (!_hasRole(role, account)) {
            AccessControlStorage._getAccessControlStorage()._roles[role].hasRole[account] = true;
            emit RoleGranted(role, account, msg.sender);
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Attempts to revoke `role` to `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 returns (bool) {
        if (_hasRole(role, account)) {
            AccessControlStorage._getAccessControlStorage()._roles[role].hasRole[account] = false;
            emit RoleRevoked(role, account, msg.sender);
            return true;
        } else {
            return false;
        }
    }
}
AccessControlStorage.sol 30 lines
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

library AccessControlStorage {
    bytes32 constant ACL_STORAGE_POSITION = keccak256("openzeppelin.accesscontrol.storage");

    /// @title RoleData
    /// @notice Data structure for role management
    struct RoleData {
        mapping(address account => bool) hasRole; //  Mapping of accounts to roles
        bytes32 adminRole; //  Admin role for this role
    }

    /// @title AccessControlStorageStruct
    /// @notice Storage structure for access control
    struct AccessControlStorageStruct {
        address deployerAdmin;
        mapping(bytes32 role => RoleData) _roles; //  Mapping of roles to role data
    }

    /// @notice Retrieves the AccessControl storage instance
    /// @return $ The AccessControl storage instance
    function _getAccessControlStorage() internal pure returns (AccessControlStorageStruct storage $) {
        bytes32 position = ACL_STORAGE_POSITION;
        assembly {
            $.slot := position
        }
    }
}
IAccessControl.sol 44 lines
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

/// @title IAccessControl
/// @notice Interface defining role-based access control methods
/// @dev Specifies core methods for managing roles and access permissions
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();

    /**
     * @notice Event emitted when a role is granted to an account
     * @param role Bytes32 identifier of the role
     * @param account Address receiving the role
     * @param sender Address that granted the role
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @notice Event emitted when a role is revoked from an account
     * @param role Bytes32 identifier of the role
     * @param account Address losing the role
     * @param sender Address that revoked the role
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @notice Event emitted when a role's admin is changed
     * @param role Bytes32 identifier of the role
     * @param previousAdminRole Previous admin role
     * @param newAdminRole New admin role
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
}
BridgeStorage.sol 35 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {BridgeLibrary} from "../../../Libraries/BridgeLibrary.sol";

/// @title BridgeStorage
/// @notice Storage structure for bridge operations
library BridgeStorage {
    bytes32 constant BRIDGE_STORAGE_POSITION = keccak256("diamond.bridge.storage");

    struct BridgeStorageStruct {
        address bridgeFlatFeeReceiver; //  Address to receive protocol fees
        address bridgePercentageFeeReceiver;
        bool erc20Paused; //  Indicates if ERC20 bridging is paused
        uint256 bridgeFlatFee; //  Flat Fee for bridging operations
        uint256 bridgeTotalFlatFeeCollected;
        uint256 bridgeFlatFeeThreshold;
        uint256 bridgePercentageFee; //  Percentage Fee for bridging operations (basis points)
        mapping(address => uint256) bridgeTotalPercentageFeeCollected;
        mapping(address => uint256) deployerNonce; //  Nonce for deployers
        mapping(address => mapping(uint64 => bool)) isDeployedOnDestinationChain; //  Mapping of deployed tokens on destination chains
        mapping(address => BridgeLibrary.IncomingTokenDetails) incomingTokenDetails; //  Mapping of incoming token details
        mapping(address => address) outgoingDeployedTokenAddress;
        mapping(address => bool) isExemptFromFees;
    }

    /// @notice Retrieves the Bridge storage instance
    /// @return $ The Bridge storage instance
    function _getBridgeStorage() internal pure returns (BridgeStorageStruct storage $) {
        bytes32 position = BRIDGE_STORAGE_POSITION;
        assembly {
            $.slot := position
        }
    }
}
Diamond.sol 95 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

/******************************************************************************\
* Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
*
* Implementation of a diamond.
/******************************************************************************/

// Storage Imports
import {BridgeStorage} from "../Bases/Bridge/ERC20/BridgeStorage.sol";

import {LibDiamond} from "./LibDiamond.sol";
import {IDiamondCut} from "./IDiamondCut.sol";
import {AccessControlStorage, AccessControlInternal} from "../Bases/AccessControl/AccessControlInternal.sol";

/// @title Diamond
/// @notice Implements the diamond standard for contract composition
contract Diamond is AccessControlInternal {
    struct Initialization {
        address initContract; ///< Address of the contract to initialize
        bytes initData; ///< Initialization data
    }

    /// @notice Initializes the diamond
    /// @param _contractOwner The owner of the contract
    /// @param _diamondCut The list of facets to add
    /// @param _initializations The list of initialization pairs to execute
    constructor(
        address _contractOwner,
        IDiamondCut.FacetCut[] memory _diamondCut,
        Initialization[] memory _initializations
    ) payable {
        if (_contractOwner != address(0)) {
            _grantRole(DEFAULT_ADMIN_ROLE, _contractOwner);
            _grantRole(PROPOSER_ROLE, _contractOwner);
            _grantRole(CCIP_OPERATOR_ROLE, _contractOwner);
            _grantRole(PAUSER_ROLE, _contractOwner);
            _grantRole(MULTISIG_ROLE, _contractOwner);
        }

        AccessControlStorage._getAccessControlStorage().deployerAdmin = _contractOwner;

        LibDiamond.diamondCut(_diamondCut, address(0), "");

        for (uint256 i = 0; i < _initializations.length; i++) {
            LibDiamond.initializeDiamondCut(_initializations[i].initContract, _initializations[i].initData);
        }
    }

    /// @notice Returns the owner of the diamond
    /// @return The owner of the diamond
    function owner() external view returns (address) {
        return AccessControlStorage._getAccessControlStorage().deployerAdmin;
    }

    function transferDeployerAdmin(address newDeployerAdmin) external onlyRole(DEFAULT_ADMIN_ROLE) {
        AccessControlStorage._getAccessControlStorage().deployerAdmin = newDeployerAdmin;
    }

    // Find facet for function that is called and execute the
    // function if a facet is found and return any value.
    fallback() external payable {
        LibDiamond.DiamondStorage storage ds;
        bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;
        // get diamond storage
        assembly {
            ds.slot := position
        }
        // get facet from function selector
        address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;
        require(facet != address(0), "Diamond: Function does not exist");
        // Execute external function from facet using delegatecall and return any value.
        assembly {
            // copy function selector and any arguments
            calldatacopy(0, 0, calldatasize())
            // execute function call using the facet
            let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
            // get any return value
            returndatacopy(0, 0, returndatasize())
            // return any return value or error back to the caller
            switch result
            case 0 {
                revert(0, returndatasize())
            }
            default {
                return(0, returndatasize())
            }
        }
    }

    /// @notice Receives ETH
    receive() external payable {}
}
IDiamondCut.sol 32 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

/******************************************************************************\
* Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
/******************************************************************************/

/// @title IDiamondCut
/// @notice Interface defining the diamond cut operations.
interface IDiamondCut {
    enum FacetCutAction {
        Add, //	 Add a facet
        Replace, // Replace a facet
        Remove // Remove a facet
    }
    // Add=0, Replace=1, Remove=2

    struct FacetCut {
        address facetAddress; // Address of the facet
        FacetCutAction action; // Action to perform
        bytes4[] functionSelectors; // Function selectors to add, replace, or remove
    }

    /// @notice Add/replace/remove any number of functions and optionally execute
    ///         a function with delegatecall
    /// @param _diamondCut Contains the facet addresses and function selectors
    /// @param _init The address of the contract or facet to execute _calldata
    /// @param _calldata A function call, including function selector and arguments
    ///                  _calldata is executed with delegatecall on _init
    function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external;
}
LibDiamond.sol 228 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

/******************************************************************************\
* Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
/******************************************************************************/
import {IDiamondCut} from "./IDiamondCut.sol";

/// @title LibDiamond
/// @notice Library for managing diamond storage and facets.
library LibDiamond {
    bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");

    /// @title FacetAddressAndPosition
    /// @notice Struct for storing the address of a facet and its position in the facetFunctionSelectors array
    struct FacetAddressAndPosition {
        address facetAddress;
        uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array
    }

    /// @title FacetFunctionSelectors
    /// @notice Struct for storing the function selectors for a facet
    struct FacetFunctionSelectors {
        bytes4[] functionSelectors;
        uint256 facetAddressPosition; // position of facetAddress in facetAddresses array
    }

    /// @title DiamondStorage
    /// @notice Struct for storing the diamond storage
    struct DiamondStorage {
        // maps function selector to the facet address and
        // the position of the selector in the facetFunctionSelectors.selectors array
        mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;
        // maps facet addresses to function selectors
        mapping(address => FacetFunctionSelectors) facetFunctionSelectors;
        // facet addresses
        address[] facetAddresses;
        // Used to query if a contract implements an interface.
        // Used to implement ERC-165.
        mapping(bytes4 => bool) supportedInterfaces;
    }

    /// @notice Gets the diamond storage
    /// @return ds The diamond storage
    function diamondStorage() internal pure returns (DiamondStorage storage ds) {
        bytes32 position = DIAMOND_STORAGE_POSITION;
        assembly {
            ds.slot := position
        }
    }

    /// @notice Event emitted when the diamond cut
    event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);

    /// @notice Internal function version of diamondCut
    /// @param _diamondCut The diamond cut
    /// @param _init The init address
    /// @param _calldata The calldata
    function diamondCut(IDiamondCut.FacetCut[] memory _diamondCut, address _init, bytes memory _calldata) internal {
        for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
            IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;
            if (action == IDiamondCut.FacetCutAction.Add) {
                addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else if (action == IDiamondCut.FacetCutAction.Replace) {
                replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else if (action == IDiamondCut.FacetCutAction.Remove) {
                removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else {
                revert("LibDiamondCut: Incorrect FacetCutAction");
            }
        }
        emit DiamondCut(_diamondCut, _init, _calldata);
        initializeDiamondCut(_init, _calldata);
    }

    /// @notice Adds functions to the diamond
    /// @param _facetAddress The address of the facet
    /// @param _functionSelectors The function selectors
    function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();
        require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
        uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
        // add new facet address if it does not exist
        if (selectorPosition == 0) {
            addFacet(ds, _facetAddress);
        }
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;

            require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists");
            addFunction(ds, selector, selectorPosition, _facetAddress);
            selectorPosition++;
        }
    }

    /// @notice Replaces functions in the diamond
    /// @param _facetAddress The address of the facet
    /// @param _functionSelectors The function selectors
    function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();
        require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
        uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
        // add new facet address if it does not exist
        if (selectorPosition == 0) {
            addFacet(ds, _facetAddress);
        }
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function");
            removeFunction(ds, oldFacetAddress, selector);
            addFunction(ds, selector, selectorPosition, _facetAddress);
            selectorPosition++;
        }
    }

    /// @notice Removes functions from the diamond
    /// @param _facetAddress The address of the facet
    /// @param _functionSelectors The function selectors
    function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();
        // if function does not exist then do nothing and return
        require(_facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)");
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;

            removeFunction(ds, oldFacetAddress, selector);
        }
    }

    /// @notice Adds a facet to the diamond
    /// @param _facetAddress The address of the facet
    function addFacet(DiamondStorage storage ds, address _facetAddress) internal {
        enforceHasContractCode(_facetAddress, "LibDiamondCut: New facet has no code");
        ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;
        ds.facetAddresses.push(_facetAddress);
    }

    /// @notice Adds a function to the diamond
    /// @param _selector The selector
    /// @param _selectorPosition The selector position
    /// @param _facetAddress The address of the facet
    function addFunction(
        DiamondStorage storage ds,
        bytes4 _selector,
        uint96 _selectorPosition,
        address _facetAddress
    ) internal {
        ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;
        ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);
        ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;
    }

    /// @notice Removes a function from the diamond
    /// @param _facetAddress The address of the facet
    /// @param _selector The selector
    function removeFunction(DiamondStorage storage ds, address _facetAddress, bytes4 _selector) internal {
        require(_facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist");
        // an immutable function is a function defined directly in a diamond
        require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function");
        // replace selector with last selector, then delete last selector
        uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;
        uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;
        // if not the same then replace _selector with lastSelector
        if (selectorPosition != lastSelectorPosition) {
            bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];
            ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;
            ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);
        }
        // delete the last selector
        ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();
        delete ds.selectorToFacetAndPosition[_selector];

        // if no more selectors for facet address then delete the facet address
        if (lastSelectorPosition == 0) {
            // replace facet address with last facet address and delete last facet address
            uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;
            uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
            if (facetAddressPosition != lastFacetAddressPosition) {
                address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];
                ds.facetAddresses[facetAddressPosition] = lastFacetAddress;
                ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;
            }
            ds.facetAddresses.pop();
            delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
        }
    }

    /// @notice Initializes the diamond cut
    /// @param _init The init address
    /// @param _calldata The calldata
    function initializeDiamondCut(address _init, bytes memory _calldata) internal {
        if (_init == address(0)) {
            require(_calldata.length == 0, "LibDiamondCut: _init is address(0) but_calldata is not empty");
        } else {
            require(_calldata.length > 0, "LibDiamondCut: _calldata is empty but _init is not address(0)");
            if (_init != address(this)) {
                enforceHasContractCode(_init, "LibDiamondCut: _init address has no code");
            }
            (bool success, bytes memory error) = _init.delegatecall(_calldata);
            if (!success) {
                if (error.length > 0) {
                    // bubble up the error
                    revert(string(error));
                } else {
                    revert("LibDiamondCut: _init function reverted");
                }
            }
        }
    }

    /// @notice Enforces that a contract has code
    /// @param _contract The contract
    /// @param _errorMessage The error message
    function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {
        uint256 contractSize;
        assembly {
            contractSize := extcodesize(_contract)
        }
        require(contractSize > 0, _errorMessage);
    }
}
BridgeLibrary.sol 39 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {TokenMetadataLibrary} from "./TokenMetadataLibrary.sol";

/// @title BridgeLibrary
/// @notice Library for bridge-related operations.
library BridgeLibrary {
    error TokenDeploymentFailed();

    /// @notice Struct for incoming token details
    struct IncomingTokenDetails {
        address originToken; ///< Original token address
        address deployedToken; ///< Locally deployed token address
        TokenMetadataLibrary.TokenMetadata tokenMetadata; ///< Metadata of the transferred token
        uint64 originChainSelector; ///< Identifier of the source blockchain
        bool hasBurnMintAuthority; ///< Indicates if the token has burn/mint authority
    }

    /// @notice Struct for bridging token details
    struct BridgingTokenDetails {
        address owner; ///< Owner of the token
        address originToken; ///< Original token address
        address deployedToken; ///< Deployed token address
        TokenMetadataLibrary.TokenMetadata tokenMetadata; ///< Token metadata
        uint256 tokenAmount; ///< Amount of tokens being transferred
        uint64 originChainSelector; ///< Identifier of the origin blockchain
        uint64 sourceChainSelector; ///< Identifier of the source blockchain
        bool hasBurnMintAuthority; ///< Indicates if the token has burn/mint authority
        bool isExemptFromFees; ///< Indicates if the token is exempt from fees
    }

    /// @notice Struct for standard token details
    struct StandardTokenStruct {
        address owner; ///< Initial token owner
        address ccip_admin; ///< CCIP admin address
        TokenMetadataLibrary.TokenMetadata tokenMetadata; ///< Token metadata
    }
}
TokenMetadataLibrary.sol 14 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

/// @title TokenMetadataLibrary
/// @notice Library for managing token metadata.
library TokenMetadataLibrary {
    /// @notice Struct for token metadata
    struct TokenMetadata {
        string name; ///< Token name
        string symbol; ///< Token symbol
        uint8 decimals; ///< Number of decimal places
        uint256 maxSupply; ///< Maximum possible token supply
    }
}

Read Contract

owner 0x8da5cb5b → address

Write Contract 1 functions

These functions modify contract state and require a wallet transaction to execute.

transferDeployerAdmin 0x907be21a
address newDeployerAdmin

Token Balances (1)

View Transfers →
LINK 0.002

Recent Transactions

No transactions found for this address