FRAX Price: $0.81 (-19.94%)

Contract

0x151198A9770107F01219Dfc5fc18e168DD529055

Overview

FRAX Balance | FXTL Balance

0 FRAX | 19,961 FXTL

FRAX Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To

There are no matching entries

1 Internal Transaction and 1 Token Transfer found.

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
148650272025-01-10 20:26:05380 days ago1736540765  Contract Creation0 FRAX

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TokenHandler

Compiler Version
v0.8.27+commit.40a35a09

Optimization Enabled:
Yes with 1000 runs

Other Settings:
london EvmVersion
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { ITokenHandler } from './interfaces/ITokenHandler.sol';
import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol';
import { SafeTokenTransfer, SafeTokenTransferFrom, SafeTokenCall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/SafeTransfer.sol';
import { ReentrancyGuard } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/ReentrancyGuard.sol';
import { Create3AddressFixed } from './utils/Create3AddressFixed.sol';

import { ITokenManagerType } from './interfaces/ITokenManagerType.sol';
import { ITokenManager } from './interfaces/ITokenManager.sol';
import { ITokenManagerProxy } from './interfaces/ITokenManagerProxy.sol';
import { IERC20MintableBurnable } from './interfaces/IERC20MintableBurnable.sol';
import { IERC20BurnableFrom } from './interfaces/IERC20BurnableFrom.sol';

/**
 * @title TokenHandler
 * @notice This interface is responsible for handling tokens before initiating an interchain token transfer, or after receiving one.
 */
contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Create3AddressFixed {
    using SafeTokenTransferFrom for IERC20;
    using SafeTokenCall for IERC20;
    using SafeTokenTransfer for IERC20;

    /**
     * @notice This function gives token to a specified address from the token manager.
     * @param tokenId The token id of the tokenManager.
     * @param to The address to give tokens to.
     * @param amount The amount of tokens to give.
     * @return uint256 The amount of token actually given, which could be different for certain token type.
     * @return address the address of the token.
     */
    function giveToken(bytes32 tokenId, address to, uint256 amount) external returns (uint256, address) {
        address tokenManager = _create3Address(tokenId);

        (uint256 tokenManagerType, address tokenAddress) = ITokenManagerProxy(tokenManager).getImplementationTypeAndTokenAddress();

        /// @dev Track the flow amount being received via the message
        ITokenManager(tokenManager).addFlowIn(amount);

        if (tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN)) {
            _giveInterchainToken(tokenAddress, to, amount);
            return (amount, tokenAddress);
        }

        if (tokenManagerType == uint256(TokenManagerType.MINT_BURN) || tokenManagerType == uint256(TokenManagerType.MINT_BURN_FROM)) {
            _mintToken(tokenManager, tokenAddress, to, amount);
            return (amount, tokenAddress);
        }

        if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK)) {
            _transferTokenFrom(tokenAddress, tokenManager, to, amount);
            return (amount, tokenAddress);
        }

        if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK_FEE)) {
            amount = _transferTokenFromWithFee(tokenAddress, tokenManager, to, amount);
            return (amount, tokenAddress);
        }

        revert UnsupportedTokenManagerType(tokenManagerType);
    }

    /**
     * @notice This function takes token from a specified address to the token manager.
     * @param tokenId The tokenId for the token.
     * @param tokenOnly can only be called from the token.
     * @param from The address to take tokens from.
     * @param amount The amount of token to take.
     * @return uint256 The amount of token actually taken, which could be different for certain token type.
     */
    // slither-disable-next-line locked-ether
    function takeToken(bytes32 tokenId, bool tokenOnly, address from, uint256 amount) external payable returns (uint256) {
        address tokenManager = _create3Address(tokenId);
        (uint256 tokenManagerType, address tokenAddress) = ITokenManagerProxy(tokenManager).getImplementationTypeAndTokenAddress();

        if (tokenOnly && msg.sender != tokenAddress) revert NotToken(msg.sender, tokenAddress);

        if (tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN)) {
            _takeInterchainToken(tokenAddress, from, amount);
        } else if (tokenManagerType == uint256(TokenManagerType.MINT_BURN)) {
            _burnToken(tokenManager, tokenAddress, from, amount);
        } else if (tokenManagerType == uint256(TokenManagerType.MINT_BURN_FROM)) {
            _burnTokenFrom(tokenAddress, from, amount);
        } else if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK)) {
            _transferTokenFrom(tokenAddress, from, tokenManager, amount);
        } else if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK_FEE)) {
            amount = _transferTokenFromWithFee(tokenAddress, from, tokenManager, amount);
        } else {
            revert UnsupportedTokenManagerType(tokenManagerType);
        }

        /// @dev Track the flow amount being sent out as a message
        ITokenManager(tokenManager).addFlowOut(amount);

        return amount;
    }

    /**
     * @notice This function transfers token from and to a specified address.
     * @param tokenId The token id of the token manager.
     * @param from The address to transfer tokens from.
     * @param to The address to transfer tokens to.
     * @param amount The amount of token to transfer.
     * @return uint256 The amount of token actually transferred, which could be different for certain token type.
     * @return address The address of the token corresponding to the input tokenId.
     */
    function transferTokenFrom(bytes32 tokenId, address from, address to, uint256 amount) external returns (uint256, address) {
        address tokenManager = _create3Address(tokenId);
        (uint256 tokenManagerType, address tokenAddress) = ITokenManagerProxy(tokenManager).getImplementationTypeAndTokenAddress();

        if (
            tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN) ||
            tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK) ||
            tokenManagerType == uint256(TokenManagerType.MINT_BURN) ||
            tokenManagerType == uint256(TokenManagerType.MINT_BURN_FROM)
        ) {
            _transferTokenFrom(tokenAddress, from, to, amount);
            return (amount, tokenAddress);
        }

        if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK_FEE)) {
            amount = _transferTokenFromWithFee(tokenAddress, from, to, amount);
            return (amount, tokenAddress);
        }

        revert UnsupportedTokenManagerType(tokenManagerType);
    }

    /**
     * @notice This function prepares a token manager after it is deployed
     * @param tokenManagerType The token manager type.
     * @param tokenManager The address of the token manager.
     */
    // slither-disable-next-line locked-ether
    function postTokenManagerDeploy(uint256 tokenManagerType, address tokenManager) external payable {
        // For lock/unlock token managers, the ITS contract needs an approval from the token manager to transfer tokens on its behalf
        if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK) || tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK_FEE)) {
            ITokenManager(tokenManager).approveService();
        }
    }

    function _transferTokenFrom(address tokenAddress, address from, address to, uint256 amount) internal {
        // slither-disable-next-line arbitrary-send-erc20
        IERC20(tokenAddress).safeTransferFrom(from, to, amount);
    }

    function _transferTokenFromWithFee(
        address tokenAddress,
        address from,
        address to,
        uint256 amount
    ) internal noReEntrancy returns (uint256) {
        uint256 balanceBefore = IERC20(tokenAddress).balanceOf(to);

        _transferTokenFrom(tokenAddress, from, to, amount);

        uint256 diff = IERC20(tokenAddress).balanceOf(to) - balanceBefore;

        return diff < amount ? diff : amount;
    }

    function _giveInterchainToken(address tokenAddress, address to, uint256 amount) internal {
        IERC20(tokenAddress).safeCall(abi.encodeWithSelector(IERC20MintableBurnable.mint.selector, to, amount));
    }

    function _takeInterchainToken(address tokenAddress, address from, uint256 amount) internal {
        IERC20(tokenAddress).safeCall(abi.encodeWithSelector(IERC20MintableBurnable.burn.selector, from, amount));
    }

    function _mintToken(address tokenManager, address tokenAddress, address to, uint256 amount) internal {
        ITokenManager(tokenManager).mintToken(tokenAddress, to, amount);
    }

    function _burnToken(address tokenManager, address tokenAddress, address from, uint256 amount) internal {
        ITokenManager(tokenManager).burnToken(tokenAddress, from, amount);
    }

    function _burnTokenFrom(address tokenAddress, address from, uint256 amount) internal {
        IERC20(tokenAddress).safeCall(abi.encodeWithSelector(IERC20BurnableFrom.burnFrom.selector, from, amount));
    }
}

File 2 of 19 : IContractIdentifier.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// General interface for upgradable contracts
interface IContractIdentifier {
    /**
     * @notice Returns the contract ID. It can be used as a check during upgrades.
     * @dev Meant to be overridden in derived contracts.
     * @return bytes32 The contract ID
     */
    function contractId() external pure returns (bytes32);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    error InvalidAccount();

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IContractIdentifier } from './IContractIdentifier.sol';

interface IImplementation is IContractIdentifier {
    error NotProxy();

    function setup(bytes calldata data) external;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// General interface for upgradable contracts
interface IProxy {
    error InvalidOwner();
    error InvalidImplementation();
    error SetupFailed();
    error NotOwner();
    error AlreadyInitialized();

    function implementation() external view returns (address);

    function setup(bytes calldata setupParams) external;
}

File 6 of 19 : IReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title ReentrancyGuard
 * @notice This contract provides a mechanism to halt the execution of specific functions
 * if a pause condition is activated.
 */
interface IReentrancyGuard {
    error ReentrantCall();
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title IRolesBase Interface
 * @notice IRolesBase is an interface that abstracts the implementation of a
 * contract with role control internal functions.
 */
interface IRolesBase {
    error MissingRole(address account, uint8 role);
    error MissingAllRoles(address account, uint256 accountRoles);
    error MissingAnyOfRoles(address account, uint256 accountRoles);

    error InvalidProposedRoles(address fromAccount, address toAccount, uint256 accountRoles);

    event RolesProposed(address indexed fromAccount, address indexed toAccount, uint256 accountRoles);
    event RolesAdded(address indexed account, uint256 accountRoles);
    event RolesRemoved(address indexed account, uint256 accountRoles);

    /**
     * @notice Checks if an account has a role.
     * @param account The address to check
     * @param role The role to check
     * @return True if the account has the role, false otherwise
     */
    function hasRole(address account, uint8 role) external view returns (bool);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC20 } from '../interfaces/IERC20.sol';

error TokenTransferFailed();

/*
 * @title SafeTokenCall
 * @dev This library is used for performing safe token transfers.
 */
library SafeTokenCall {
    /*
     * @notice Make a safe call to a token contract.
     * @param token The token contract to interact with.
     * @param callData The function call data.
     * @throws TokenTransferFailed error if transfer of token is not successful.
     */
    function safeCall(IERC20 token, bytes memory callData) internal {
        (bool success, bytes memory returnData) = address(token).call(callData);
        bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool)));

        if (!transferred || address(token).code.length == 0) revert TokenTransferFailed();
    }
}

/*
 * @title SafeTokenTransfer
 * @dev This library safely transfers tokens from the contract to a recipient.
 */
library SafeTokenTransfer {
    /*
     * @notice Transfer tokens to a recipient.
     * @param token The token contract.
     * @param receiver The recipient of the tokens.
     * @param amount The amount of tokens to transfer.
     */
    function safeTransfer(
        IERC20 token,
        address receiver,
        uint256 amount
    ) internal {
        SafeTokenCall.safeCall(token, abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount));
    }
}

/*
 * @title SafeTokenTransferFrom
 * @dev This library helps to safely transfer tokens on behalf of a token holder.
 */
library SafeTokenTransferFrom {
    /*
     * @notice Transfer tokens on behalf of a token holder.
     * @param token The token contract.
     * @param from The address of the token holder.
     * @param to The address the tokens are to be sent to.
     * @param amount The amount of tokens to be transferred.
     */
    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        SafeTokenCall.safeCall(token, abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, amount));
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IReentrancyGuard } from '../interfaces/IReentrancyGuard.sol';

/**
 * @title ReentrancyGuard
 * @notice This contract provides a mechanism to halt the execution of specific functions
 * if a pause condition is activated.
 */
contract ReentrancyGuard is IReentrancyGuard {
    // uint256(keccak256('ReentrancyGuard:entered')) - 1
    uint256 internal constant ENTERED_SLOT = 0x1a771c70cada93a906f955a7dec24a83d7954ba2f75256be4febcf62b395d532;
    uint256 internal constant NOT_ENTERED = 1;
    uint256 internal constant ENTERED = 2;

    /**
     * @notice A modifier that throws a ReEntrancy custom error if the contract is entered
     * @dev This modifier should be used with functions that can be entered twice
     */
    modifier noReEntrancy() {
        if (_hasEntered()) revert ReentrantCall();
        _setEntered(ENTERED);
        _;
        _setEntered(NOT_ENTERED);
    }

    /**
     * @notice Check if the contract is already executing.
     * @return entered A boolean representing the entered status. True if already executing, false otherwise.
     */
    function _hasEntered() internal view returns (bool entered) {
        assembly {
            entered := eq(sload(ENTERED_SLOT), ENTERED)
        }
    }

    /**
     * @notice Sets the entered status of the contract
     * @param entered A boolean representing the entered status. True if already executing, false otherwise.
     */
    function _setEntered(uint256 entered) internal {
        assembly {
            sstore(ENTERED_SLOT, entered)
        }
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title IBaseTokenManager
 * @notice This contract is defines the base token manager interface implemented by all token managers.
 */
interface IBaseTokenManager {
    /**
     * @notice A function that returns the token id.
     */
    function interchainTokenId() external view returns (bytes32);

    /**
     * @notice A function that should return the address of the token.
     * Must be overridden in the inheriting contract.
     * @return address address of the token.
     */
    function tokenAddress() external view returns (address);

    /**
     * @notice A function that should return the token address from the init params.
     */
    function getTokenAddressFromParams(bytes calldata params) external pure returns (address);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title IERC20BurnableFrom Interface
 * @notice Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20BurnableFrom {
    /**
     * @notice Function to burn tokens.
     * @dev Requires the caller to have allowance for `amount` on `from`.
     * Can only be called by the minter address.
     * @param from The address that will have its tokens burnt.
     * @param amount The amount of tokens to burn.
     */
    function burnFrom(address from, uint256 amount) external;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title IERC20MintableBurnable Interface
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20MintableBurnable {
    /**
     * @notice Function to mint new tokens.
     * @dev Can only be called by the minter address.
     * @param to The address that will receive the minted tokens.
     * @param amount The amount of tokens to mint.
     */
    function mint(address to, uint256 amount) external;

    /**
     * @notice Function to burn tokens.
     * @dev Can only be called by the minter address.
     * @param from The address that will have its tokens burnt.
     * @param amount The amount of tokens to burn.
     */
    function burn(address from, uint256 amount) external;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title FlowLimit Interface
 * @notice Interface for flow limit logic for interchain token transfers.
 */
interface IFlowLimit {
    error FlowLimitExceeded(uint256 limit, uint256 flowAmount, address tokenManager);
    error FlowAdditionOverflow(uint256 flowAmount, uint256 flowToAdd, address tokenManager);
    error FlowLimitOverflow(uint256 flowLimit, uint256 flowToCompare, address tokenManager);

    event FlowLimitSet(bytes32 indexed tokenId, address operator, uint256 flowLimit_);

    /**
     * @notice Returns the current flow limit.
     * @return flowLimit_ The current flow limit value.
     */
    function flowLimit() external view returns (uint256 flowLimit_);

    /**
     * @notice Returns the current flow out amount.
     * @return flowOutAmount_ The current flow out amount.
     */
    function flowOutAmount() external view returns (uint256 flowOutAmount_);

    /**
     * @notice Returns the current flow in amount.
     * @return flowInAmount_ The current flow in amount.
     */
    function flowInAmount() external view returns (uint256 flowInAmount_);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IRolesBase } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IRolesBase.sol';

/**
 * @title IOperator Interface
 * @notice An interface for a contract module which provides a basic access control mechanism, where
 * there is an account (a operator) that can be granted exclusive access to specific functions.
 */
interface IOperator is IRolesBase {
    /**
     * @notice Change the operator of the contract.
     * @dev Can only be called by the current operator.
     * @param operator_ The address of the new operator.
     */
    function transferOperatorship(address operator_) external;

    /**
     * @notice Proposed a change of the operator of the contract.
     * @dev Can only be called by the current operator.
     * @param operator_ The address of the new operator.
     */
    function proposeOperatorship(address operator_) external;

    /**
     * @notice Accept a proposed change of operatorship.
     * @dev Can only be called by the proposed operator.
     * @param fromOperator The previous operator of the contract.
     */
    function acceptOperatorship(address fromOperator) external;

    /**
     * @notice Query if an address is a operator.
     * @param addr The address to query for.
     * @return bool Boolean value representing whether or not the address is an operator.
     */
    function isOperator(address addr) external view returns (bool);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title ITokenHandler Interface
 * @notice This interface is responsible for handling tokens before initiating an interchain token transfer, or after receiving one.
 */
interface ITokenHandler {
    error UnsupportedTokenManagerType(uint256 tokenManagerType);
    error NotToken(address caller, address token);

    /**
     * @notice This function gives token to a specified address from the token manager.
     * @param tokenId The token id of the tokenManager.
     * @param to The address to give tokens to.
     * @param amount The amount of tokens to give.
     * @return uint256 The amount of token actually given, which could be different for certain token type.
     * @return address the address of the token.
     */
    function giveToken(bytes32 tokenId, address to, uint256 amount) external returns (uint256, address);

    /**
     * @notice This function takes token from a specified address to the token manager.
     * @param tokenId The tokenId for the token.
     * @param tokenOnly can only be called from the token.
     * @param from The address to take tokens from.
     * @param amount The amount of token to take.
     * @return uint256 The amount of token actually taken, which could be different for certain token type.
     */
    // slither-disable-next-line locked-ether
    function takeToken(bytes32 tokenId, bool tokenOnly, address from, uint256 amount) external payable returns (uint256);

    /**
     * @notice This function transfers token from and to a specified address.
     * @param tokenId The token id of the token manager.
     * @param from The address to transfer tokens from.
     * @param to The address to transfer tokens to.
     * @param amount The amount of token to transfer.
     * @return uint256 The amount of token actually transferred, which could be different for certain token type.
     * @return address The address of the token corresponding to the input tokenId.
     */
    function transferTokenFrom(bytes32 tokenId, address from, address to, uint256 amount) external returns (uint256, address);

    /**
     * @notice This function prepares a token manager after it is deployed
     * @param tokenManagerType The token manager type.
     * @param tokenManager The address of the token manager.
     */
    function postTokenManagerDeploy(uint256 tokenManagerType, address tokenManager) external payable;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IImplementation } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IImplementation.sol';

import { IBaseTokenManager } from './IBaseTokenManager.sol';
import { IOperator } from './IOperator.sol';
import { IFlowLimit } from './IFlowLimit.sol';

/**
 * @title ITokenManager Interface
 * @notice This contract is responsible for managing tokens, such as setting locking token balances, or setting flow limits, for interchain transfers.
 */
interface ITokenManager is IBaseTokenManager, IOperator, IFlowLimit, IImplementation {
    error TokenLinkerZeroAddress();
    error NotService(address caller);
    error TakeTokenFailed();
    error GiveTokenFailed();
    error NotToken(address caller);
    error ZeroAddress();
    error AlreadyFlowLimiter(address flowLimiter);
    error NotFlowLimiter(address flowLimiter);
    error NotSupported();

    /**
     * @notice Returns implementation type of this token manager.
     * @return uint256 The implementation type of this token manager.
     */
    function implementationType() external view returns (uint256);

    function addFlowIn(uint256 amount) external;

    function addFlowOut(uint256 amount) external;

    /**
     * @notice This function adds a flow limiter for this TokenManager.
     * @dev Can only be called by the operator.
     * @param flowLimiter the address of the new flow limiter.
     */
    function addFlowLimiter(address flowLimiter) external;

    /**
     * @notice This function removes a flow limiter for this TokenManager.
     * @dev Can only be called by the operator.
     * @param flowLimiter the address of an existing flow limiter.
     */
    function removeFlowLimiter(address flowLimiter) external;

    /**
     * @notice Query if an address is a flow limiter.
     * @param addr The address to query for.
     * @return bool Boolean value representing whether or not the address is a flow limiter.
     */
    function isFlowLimiter(address addr) external view returns (bool);

    /**
     * @notice This function sets the flow limit for this TokenManager.
     * @dev Can only be called by the flow limiters.
     * @param flowLimit_ The maximum difference between the tokens flowing in and/or out at any given interval of time (6h).
     */
    function setFlowLimit(uint256 flowLimit_) external;

    /**
     * @notice A function to renew approval to the service if we need to.
     */
    function approveService() external;

    /**
     * @notice Getter function for the parameters of a lock/unlock TokenManager.
     * @dev This function will be mainly used by frontends.
     * @param operator_ The operator of the TokenManager.
     * @param tokenAddress_ The token to be managed.
     * @return params_ The resulting params to be passed to custom TokenManager deployments.
     */
    function params(bytes calldata operator_, address tokenAddress_) external pure returns (bytes memory params_);

    /**
     * @notice External function to allow the service to mint tokens through the tokenManager
     * @dev This function should revert if called by anyone but the service.
     * @param tokenAddress_ The address of the token, since its cheaper to pass it in instead of reading it as the token manager.
     * @param to The recipient.
     * @param amount The amount to mint.
     */
    function mintToken(address tokenAddress_, address to, uint256 amount) external;

    /**
     * @notice External function to allow the service to burn tokens through the tokenManager
     * @dev This function should revert if called by anyone but the service.
     * @param tokenAddress_ The address of the token, since its cheaper to pass it in instead of reading it as the token manager.
     * @param from The address to burn the token from.
     * @param amount The amount to burn.
     */
    function burnToken(address tokenAddress_, address from, uint256 amount) external;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IProxy } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IProxy.sol';

/**
 * @title ITokenManagerProxy Interface
 * @notice This interface is for a proxy for token manager contracts.
 */
interface ITokenManagerProxy is IProxy {
    error ZeroAddress();

    /**
     * @notice Returns implementation type of this token manager.
     * @return uint256 The implementation type of this token manager.
     */
    function implementationType() external view returns (uint256);

    /**
     * @notice Returns the interchain token ID of the token manager.
     * @return bytes32 The interchain token ID of the token manager.
     */
    function interchainTokenId() external view returns (bytes32);

    /**
     * @notice Returns token address that this token manager manages.
     * @return address The token address.
     */
    function tokenAddress() external view returns (address);

    /**
     * @notice Returns implementation type and token address.
     * @return uint256 The implementation type.
     * @return address The token address.
     */
    function getImplementationTypeAndTokenAddress() external view returns (uint256, address);
}

File 18 of 19 : ITokenManagerType.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title ITokenManagerType Interface
 * @notice A simple interface that defines all the token manager types.
 */
interface ITokenManagerType {
    enum TokenManagerType {
        NATIVE_INTERCHAIN_TOKEN, // This type is reserved for interchain tokens deployed by ITS, and can't be used by custom token managers.
        MINT_BURN_FROM, // The token will be minted/burned on transfers. The token needs to give mint permission to the token manager, but burning happens via an approval.
        LOCK_UNLOCK, // The token will be locked/unlocked at the token manager.
        LOCK_UNLOCK_FEE, // The token will be locked/unlocked at the token manager, which will account for any fee-on-transfer behaviour.
        MINT_BURN // The token will be minted/burned on transfers. The token needs to give mint and burn permission to the token manager.
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title Create3AddressFixed contract
 * @notice This contract can be used to predict the deterministic deployment address of a contract deployed with the `CREATE3` technique.
 * It is equivalent to the Create3Address found in axelar-gmp-sdk-solidity repo but uses a fixed bytecode for CreateDeploy,
 * which allows changing compilation options (like number of runs) without affecting the future deployment addresses.
 */
contract Create3AddressFixed {
    // slither-disable-next-line too-many-digits
    bytes internal constant CREATE_DEPLOY_BYTECODE =
        hex'608060405234801561001057600080fd5b50610162806100206000396000f3fe60806040526004361061001d5760003560e01c806277436014610022575b600080fd5b61003561003036600461007b565b610037565b005b8051602082016000f061004957600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561008d57600080fd5b813567ffffffffffffffff808211156100a557600080fd5b818401915084601f8301126100b957600080fd5b8135818111156100cb576100cb61004c565b604051601f8201601f19908116603f011681019083821181831017156100f3576100f361004c565b8160405282815287602084870101111561010c57600080fd5b82602086016020830137600092810160200192909252509594505050505056fea264697066735822122094780ce55d28f1d568f4e0ab1b9dc230b96e952b73d2e06456fbff2289fa27f464736f6c63430008150033';
    bytes32 internal constant CREATE_DEPLOY_BYTECODE_HASH = keccak256(CREATE_DEPLOY_BYTECODE);

    /**
     * @notice Compute the deployed address that will result from the `CREATE3` method.
     * @param deploySalt A salt to influence the contract address
     * @return deployed The deterministic contract address if it was deployed
     */
    function _create3Address(bytes32 deploySalt) internal view returns (address deployed) {
        address deployer = address(
            uint160(uint256(keccak256(abi.encodePacked(hex'ff', address(this), deploySalt, CREATE_DEPLOY_BYTECODE_HASH))))
        );

        deployed = address(uint160(uint256(keccak256(abi.encodePacked(hex'd6_94', deployer, hex'01')))));
    }
}

Settings
{
  "evmVersion": "london",
  "optimizer": {
    "enabled": true,
    "runs": 1000,
    "details": {
      "peephole": true,
      "inliner": true,
      "jumpdestRemover": true,
      "orderLiterals": true,
      "deduplicate": true,
      "cse": true,
      "constantOptimizer": true,
      "yul": true,
      "yulDetails": {
        "stackAllocation": true
      }
    }
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"NotToken","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[],"name":"TokenTransferFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenManagerType","type":"uint256"}],"name":"UnsupportedTokenManagerType","type":"error"},{"inputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"giveToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenManagerType","type":"uint256"},{"internalType":"address","name":"tokenManager","type":"address"}],"name":"postTokenManagerDeploy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"},{"internalType":"bool","name":"tokenOnly","type":"bool"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"takeToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferTokenFrom","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}]

6080604052348015600f57600080fd5b50610f9c8061001f6000396000f3fe60806040526004361061003f5760003560e01c806320f75e0814610044578063dbd15f2f14610086578063ea5254831461009b578063fb1ea8cf146100bc575b600080fd5b34801561005057600080fd5b5061006461005f366004610c2c565b6100dc565b604080519283526001600160a01b039091166020830152015b60405180910390f35b610099610094366004610c74565b6101fc565b005b6100ae6100a9366004610cb2565b610268565b60405190815260200161007d565b3480156100c857600080fd5b506100646100d7366004610cda565b610425565b60008060006100ea87610597565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa15801561012c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101509190610d12565b90925090508115806101625750600282145b8061016d5750600482145b806101785750600182145b1561019657610189818989896106b2565b85945092506101f3915050565b600382036101b9576101aa818989896106cd565b955085945092506101f3915050565b6040517ff24fcfa1000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b94509492505050565b600282148061020b5750600382145b1561026457806001600160a01b031663274158386040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561024b57600080fd5b505af115801561025f573d6000803e3d6000fd5b505050505b5050565b60008061027486610597565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa1580156102b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102da9190610d12565b915091508680156102f45750336001600160a01b03821614155b1561033c576040517f409304db0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03821660248201526044016101ea565b816103515761034c81878761088d565b6103a3565b600482036103655761034c83828888610944565b600182036103785761034c8187876109ce565b6002820361038c5761034c818785886106b2565b600382036101b9576103a0818785886106cd565b94505b6040517fdce29136000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0384169063dce2913690602401600060405180830381600087803b1580156103fe57600080fd5b505af1158015610412573d6000803e3d6000fd5b505050508493505050505b949350505050565b600080600061043386610597565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa158015610475573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104999190610d12565b6040517f10d8d8e30000000000000000000000000000000000000000000000000000000081526004810189905291935091506001600160a01b038416906310d8d8e390602401600060405180830381600087803b1580156104f957600080fd5b505af115801561050d573d6000803e3d6000fd5b506000925061051a915050565b82036105385761052b818888610a15565b859450925061058f915050565b60048214806105475750600182145b156105585761052b83828989610a5c565b6002820361056c5761052b818489896106b2565b600382036101b957610580818489896106cd565b9550859450925061058f915050565b935093915050565b6000803083604051806101c001604052806101828152602001610de56101829139805160209182012060405161061a949392017fff00000000000000000000000000000000000000000000000000000000000000815260609390931b6bffffffffffffffffffffffff191660018401526015830191909152603582015260550190565b60408051601f1981840301815282825280516020918201207fd6940000000000000000000000000000000000000000000000000000000000008285015260601b6bffffffffffffffffffffffff191660228401527f0100000000000000000000000000000000000000000000000000000000000000603684015281516017818503018152603790930190915281519101209392505050565b6106c76001600160a01b038516848484610ab2565b50505050565b60006106fa7f1a771c70cada93a906f955a7dec24a83d7954ba2f75256be4febcf62b395d5325460021490565b15610731576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61075a60027f1a771c70cada93a906f955a7dec24a83d7954ba2f75256be4febcf62b395d53255565b6040516370a0823160e01b81526001600160a01b038481166004830152600091908716906370a0823190602401602060405180830381865afa1580156107a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c89190610d38565b90506107d6868686866106b2565b6040516370a0823160e01b81526001600160a01b03858116600483015260009183918916906370a0823190602401602060405180830381865afa158015610821573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108459190610d38565b61084f9190610d51565b905083811061085e5783610860565b805b9250505061041d60017f1a771c70cada93a906f955a7dec24a83d7954ba2f75256be4febcf62b395d53255565b6040516001600160a01b03831660248201526044810182905261093f907f9dc29fac00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526001600160a01b03851690610b36565b505050565b6040517f3416794d0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152838116602483015260448201839052851690633416794d906064015b600060405180830381600087803b1580156109b057600080fd5b505af11580156109c4573d6000803e3d6000fd5b5050505050505050565b6040516001600160a01b03831660248201526044810182905261093f907f79cc679000000000000000000000000000000000000000000000000000000000906064016108d0565b6040516001600160a01b03831660248201526044810182905261093f907f40c10f1900000000000000000000000000000000000000000000000000000000906064016108d0565b6040517f6bec32da0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152838116602483015260448201839052851690636bec32da90606401610996565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526106c79085905b600080836001600160a01b031683604051610b519190610d91565b6000604051808303816000865af19150503d8060008114610b8e576040519150601f19603f3d011682016040523d82523d6000602084013e610b93565b606091505b50915091506000828015610bbf575081511580610bbf575081806020019051810190610bbf9190610dc0565b9050801580610bd657506001600160a01b0385163b155b15610c0d576040517f045c4b0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6001600160a01b0381168114610c2957600080fd5b50565b60008060008060808587031215610c4257600080fd5b843593506020850135610c5481610c14565b92506040850135610c6481610c14565b9396929550929360600135925050565b60008060408385031215610c8757600080fd5b823591506020830135610c9981610c14565b809150509250929050565b8015158114610c2957600080fd5b60008060008060808587031215610cc857600080fd5b843593506020850135610c5481610ca4565b600080600060608486031215610cef57600080fd5b833592506020840135610d0181610c14565b929592945050506040919091013590565b60008060408385031215610d2557600080fd5b82516020840151909250610c9981610c14565b600060208284031215610d4a57600080fd5b5051919050565b81810381811115610d8b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b92915050565b6000825160005b81811015610db25760208186018101518583015201610d98565b506000920191825250919050565b600060208284031215610dd257600080fd5b8151610ddd81610ca4565b939250505056fe608060405234801561001057600080fd5b50610162806100206000396000f3fe60806040526004361061001d5760003560e01c806277436014610022575b600080fd5b61003561003036600461007b565b610037565b005b8051602082016000f061004957600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561008d57600080fd5b813567ffffffffffffffff808211156100a557600080fd5b818401915084601f8301126100b957600080fd5b8135818111156100cb576100cb61004c565b604051601f8201601f19908116603f011681019083821181831017156100f3576100f361004c565b8160405282815287602084870101111561010c57600080fd5b82602086016020830137600092810160200192909252509594505050505056fea264697066735822122094780ce55d28f1d568f4e0ab1b9dc230b96e952b73d2e06456fbff2289fa27f464736f6c63430008150033a2646970667358221220bd481061c7901aa7394be7532e7eb165ba693f95ddae103ae0330232ac37b5d064736f6c634300081b0033

Deployed Bytecode

0x60806040526004361061003f5760003560e01c806320f75e0814610044578063dbd15f2f14610086578063ea5254831461009b578063fb1ea8cf146100bc575b600080fd5b34801561005057600080fd5b5061006461005f366004610c2c565b6100dc565b604080519283526001600160a01b039091166020830152015b60405180910390f35b610099610094366004610c74565b6101fc565b005b6100ae6100a9366004610cb2565b610268565b60405190815260200161007d565b3480156100c857600080fd5b506100646100d7366004610cda565b610425565b60008060006100ea87610597565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa15801561012c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101509190610d12565b90925090508115806101625750600282145b8061016d5750600482145b806101785750600182145b1561019657610189818989896106b2565b85945092506101f3915050565b600382036101b9576101aa818989896106cd565b955085945092506101f3915050565b6040517ff24fcfa1000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b94509492505050565b600282148061020b5750600382145b1561026457806001600160a01b031663274158386040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561024b57600080fd5b505af115801561025f573d6000803e3d6000fd5b505050505b5050565b60008061027486610597565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa1580156102b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102da9190610d12565b915091508680156102f45750336001600160a01b03821614155b1561033c576040517f409304db0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03821660248201526044016101ea565b816103515761034c81878761088d565b6103a3565b600482036103655761034c83828888610944565b600182036103785761034c8187876109ce565b6002820361038c5761034c818785886106b2565b600382036101b9576103a0818785886106cd565b94505b6040517fdce29136000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0384169063dce2913690602401600060405180830381600087803b1580156103fe57600080fd5b505af1158015610412573d6000803e3d6000fd5b505050508493505050505b949350505050565b600080600061043386610597565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa158015610475573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104999190610d12565b6040517f10d8d8e30000000000000000000000000000000000000000000000000000000081526004810189905291935091506001600160a01b038416906310d8d8e390602401600060405180830381600087803b1580156104f957600080fd5b505af115801561050d573d6000803e3d6000fd5b506000925061051a915050565b82036105385761052b818888610a15565b859450925061058f915050565b60048214806105475750600182145b156105585761052b83828989610a5c565b6002820361056c5761052b818489896106b2565b600382036101b957610580818489896106cd565b9550859450925061058f915050565b935093915050565b6000803083604051806101c001604052806101828152602001610de56101829139805160209182012060405161061a949392017fff00000000000000000000000000000000000000000000000000000000000000815260609390931b6bffffffffffffffffffffffff191660018401526015830191909152603582015260550190565b60408051601f1981840301815282825280516020918201207fd6940000000000000000000000000000000000000000000000000000000000008285015260601b6bffffffffffffffffffffffff191660228401527f0100000000000000000000000000000000000000000000000000000000000000603684015281516017818503018152603790930190915281519101209392505050565b6106c76001600160a01b038516848484610ab2565b50505050565b60006106fa7f1a771c70cada93a906f955a7dec24a83d7954ba2f75256be4febcf62b395d5325460021490565b15610731576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61075a60027f1a771c70cada93a906f955a7dec24a83d7954ba2f75256be4febcf62b395d53255565b6040516370a0823160e01b81526001600160a01b038481166004830152600091908716906370a0823190602401602060405180830381865afa1580156107a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c89190610d38565b90506107d6868686866106b2565b6040516370a0823160e01b81526001600160a01b03858116600483015260009183918916906370a0823190602401602060405180830381865afa158015610821573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108459190610d38565b61084f9190610d51565b905083811061085e5783610860565b805b9250505061041d60017f1a771c70cada93a906f955a7dec24a83d7954ba2f75256be4febcf62b395d53255565b6040516001600160a01b03831660248201526044810182905261093f907f9dc29fac00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526001600160a01b03851690610b36565b505050565b6040517f3416794d0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152838116602483015260448201839052851690633416794d906064015b600060405180830381600087803b1580156109b057600080fd5b505af11580156109c4573d6000803e3d6000fd5b5050505050505050565b6040516001600160a01b03831660248201526044810182905261093f907f79cc679000000000000000000000000000000000000000000000000000000000906064016108d0565b6040516001600160a01b03831660248201526044810182905261093f907f40c10f1900000000000000000000000000000000000000000000000000000000906064016108d0565b6040517f6bec32da0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152838116602483015260448201839052851690636bec32da90606401610996565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526106c79085905b600080836001600160a01b031683604051610b519190610d91565b6000604051808303816000865af19150503d8060008114610b8e576040519150601f19603f3d011682016040523d82523d6000602084013e610b93565b606091505b50915091506000828015610bbf575081511580610bbf575081806020019051810190610bbf9190610dc0565b9050801580610bd657506001600160a01b0385163b155b15610c0d576040517f045c4b0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6001600160a01b0381168114610c2957600080fd5b50565b60008060008060808587031215610c4257600080fd5b843593506020850135610c5481610c14565b92506040850135610c6481610c14565b9396929550929360600135925050565b60008060408385031215610c8757600080fd5b823591506020830135610c9981610c14565b809150509250929050565b8015158114610c2957600080fd5b60008060008060808587031215610cc857600080fd5b843593506020850135610c5481610ca4565b600080600060608486031215610cef57600080fd5b833592506020840135610d0181610c14565b929592945050506040919091013590565b60008060408385031215610d2557600080fd5b82516020840151909250610c9981610c14565b600060208284031215610d4a57600080fd5b5051919050565b81810381811115610d8b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b92915050565b6000825160005b81811015610db25760208186018101518583015201610d98565b506000920191825250919050565b600060208284031215610dd257600080fd5b8151610ddd81610ca4565b939250505056fe608060405234801561001057600080fd5b50610162806100206000396000f3fe60806040526004361061001d5760003560e01c806277436014610022575b600080fd5b61003561003036600461007b565b610037565b005b8051602082016000f061004957600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561008d57600080fd5b813567ffffffffffffffff808211156100a557600080fd5b818401915084601f8301126100b957600080fd5b8135818111156100cb576100cb61004c565b604051601f8201601f19908116603f011681019083821181831017156100f3576100f361004c565b8160405282815287602084870101111561010c57600080fd5b82602086016020830137600092810160200192909252509594505050505056fea264697066735822122094780ce55d28f1d568f4e0ab1b9dc230b96e952b73d2e06456fbff2289fa27f464736f6c63430008150033a2646970667358221220bd481061c7901aa7394be7532e7eb165ba693f95ddae103ae0330232ac37b5d064736f6c634300081b0033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
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.