Source Code
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 14865027 | 380 days ago | Contract Creation | 0 FRAX |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
TokenHandler
Compiler Version
v0.8.27+commit.40a35a09
Optimization Enabled:
Yes with 1000 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// 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));
}
}// 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;
}// 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);
}// 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')))));
}
}{
"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
- No Contract Security Audit Submitted- Submit Audit Here
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"}]Contract Creation Code
6080604052348015600f57600080fd5b50610f9c8061001f6000396000f3fe60806040526004361061003f5760003560e01c806320f75e0814610044578063dbd15f2f14610086578063ea5254831461009b578063fb1ea8cf146100bc575b600080fd5b34801561005057600080fd5b5061006461005f366004610c2c565b6100dc565b604080519283526001600160a01b039091166020830152015b60405180910390f35b610099610094366004610c74565b6101fc565b005b6100ae6100a9366004610cb2565b610268565b60405190815260200161007d565b3480156100c857600080fd5b506100646100d7366004610cda565b610425565b60008060006100ea87610597565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa15801561012c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101509190610d12565b90925090508115806101625750600282145b8061016d5750600482145b806101785750600182145b1561019657610189818989896106b2565b85945092506101f3915050565b600382036101b9576101aa818989896106cd565b955085945092506101f3915050565b6040517ff24fcfa1000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b94509492505050565b600282148061020b5750600382145b1561026457806001600160a01b031663274158386040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561024b57600080fd5b505af115801561025f573d6000803e3d6000fd5b505050505b5050565b60008061027486610597565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa1580156102b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102da9190610d12565b915091508680156102f45750336001600160a01b03821614155b1561033c576040517f409304db0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03821660248201526044016101ea565b816103515761034c81878761088d565b6103a3565b600482036103655761034c83828888610944565b600182036103785761034c8187876109ce565b6002820361038c5761034c818785886106b2565b600382036101b9576103a0818785886106cd565b94505b6040517fdce29136000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0384169063dce2913690602401600060405180830381600087803b1580156103fe57600080fd5b505af1158015610412573d6000803e3d6000fd5b505050508493505050505b949350505050565b600080600061043386610597565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa158015610475573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104999190610d12565b6040517f10d8d8e30000000000000000000000000000000000000000000000000000000081526004810189905291935091506001600160a01b038416906310d8d8e390602401600060405180830381600087803b1580156104f957600080fd5b505af115801561050d573d6000803e3d6000fd5b506000925061051a915050565b82036105385761052b818888610a15565b859450925061058f915050565b60048214806105475750600182145b156105585761052b83828989610a5c565b6002820361056c5761052b818489896106b2565b600382036101b957610580818489896106cd565b9550859450925061058f915050565b935093915050565b6000803083604051806101c001604052806101828152602001610de56101829139805160209182012060405161061a949392017fff00000000000000000000000000000000000000000000000000000000000000815260609390931b6bffffffffffffffffffffffff191660018401526015830191909152603582015260550190565b60408051601f1981840301815282825280516020918201207fd6940000000000000000000000000000000000000000000000000000000000008285015260601b6bffffffffffffffffffffffff191660228401527f0100000000000000000000000000000000000000000000000000000000000000603684015281516017818503018152603790930190915281519101209392505050565b6106c76001600160a01b038516848484610ab2565b50505050565b60006106fa7f1a771c70cada93a906f955a7dec24a83d7954ba2f75256be4febcf62b395d5325460021490565b15610731576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61075a60027f1a771c70cada93a906f955a7dec24a83d7954ba2f75256be4febcf62b395d53255565b6040516370a0823160e01b81526001600160a01b038481166004830152600091908716906370a0823190602401602060405180830381865afa1580156107a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c89190610d38565b90506107d6868686866106b2565b6040516370a0823160e01b81526001600160a01b03858116600483015260009183918916906370a0823190602401602060405180830381865afa158015610821573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108459190610d38565b61084f9190610d51565b905083811061085e5783610860565b805b9250505061041d60017f1a771c70cada93a906f955a7dec24a83d7954ba2f75256be4febcf62b395d53255565b6040516001600160a01b03831660248201526044810182905261093f907f9dc29fac00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526001600160a01b03851690610b36565b505050565b6040517f3416794d0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152838116602483015260448201839052851690633416794d906064015b600060405180830381600087803b1580156109b057600080fd5b505af11580156109c4573d6000803e3d6000fd5b5050505050505050565b6040516001600160a01b03831660248201526044810182905261093f907f79cc679000000000000000000000000000000000000000000000000000000000906064016108d0565b6040516001600160a01b03831660248201526044810182905261093f907f40c10f1900000000000000000000000000000000000000000000000000000000906064016108d0565b6040517f6bec32da0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152838116602483015260448201839052851690636bec32da90606401610996565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526106c79085905b600080836001600160a01b031683604051610b519190610d91565b6000604051808303816000865af19150503d8060008114610b8e576040519150601f19603f3d011682016040523d82523d6000602084013e610b93565b606091505b50915091506000828015610bbf575081511580610bbf575081806020019051810190610bbf9190610dc0565b9050801580610bd657506001600160a01b0385163b155b15610c0d576040517f045c4b0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6001600160a01b0381168114610c2957600080fd5b50565b60008060008060808587031215610c4257600080fd5b843593506020850135610c5481610c14565b92506040850135610c6481610c14565b9396929550929360600135925050565b60008060408385031215610c8757600080fd5b823591506020830135610c9981610c14565b809150509250929050565b8015158114610c2957600080fd5b60008060008060808587031215610cc857600080fd5b843593506020850135610c5481610ca4565b600080600060608486031215610cef57600080fd5b833592506020840135610d0181610c14565b929592945050506040919091013590565b60008060408385031215610d2557600080fd5b82516020840151909250610c9981610c14565b600060208284031215610d4a57600080fd5b5051919050565b81810381811115610d8b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b92915050565b6000825160005b81811015610db25760208186018101518583015201610d98565b506000920191825250919050565b600060208284031215610dd257600080fd5b8151610ddd81610ca4565b939250505056fe608060405234801561001057600080fd5b50610162806100206000396000f3fe60806040526004361061001d5760003560e01c806277436014610022575b600080fd5b61003561003036600461007b565b610037565b005b8051602082016000f061004957600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561008d57600080fd5b813567ffffffffffffffff808211156100a557600080fd5b818401915084601f8301126100b957600080fd5b8135818111156100cb576100cb61004c565b604051601f8201601f19908116603f011681019083821181831017156100f3576100f361004c565b8160405282815287602084870101111561010c57600080fd5b82602086016020830137600092810160200192909252509594505050505056fea264697066735822122094780ce55d28f1d568f4e0ab1b9dc230b96e952b73d2e06456fbff2289fa27f464736f6c63430008150033a2646970667358221220bd481061c7901aa7394be7532e7eb165ba693f95ddae103ae0330232ac37b5d064736f6c634300081b0033
Deployed Bytecode
0x60806040526004361061003f5760003560e01c806320f75e0814610044578063dbd15f2f14610086578063ea5254831461009b578063fb1ea8cf146100bc575b600080fd5b34801561005057600080fd5b5061006461005f366004610c2c565b6100dc565b604080519283526001600160a01b039091166020830152015b60405180910390f35b610099610094366004610c74565b6101fc565b005b6100ae6100a9366004610cb2565b610268565b60405190815260200161007d565b3480156100c857600080fd5b506100646100d7366004610cda565b610425565b60008060006100ea87610597565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa15801561012c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101509190610d12565b90925090508115806101625750600282145b8061016d5750600482145b806101785750600182145b1561019657610189818989896106b2565b85945092506101f3915050565b600382036101b9576101aa818989896106cd565b955085945092506101f3915050565b6040517ff24fcfa1000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b94509492505050565b600282148061020b5750600382145b1561026457806001600160a01b031663274158386040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561024b57600080fd5b505af115801561025f573d6000803e3d6000fd5b505050505b5050565b60008061027486610597565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa1580156102b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102da9190610d12565b915091508680156102f45750336001600160a01b03821614155b1561033c576040517f409304db0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03821660248201526044016101ea565b816103515761034c81878761088d565b6103a3565b600482036103655761034c83828888610944565b600182036103785761034c8187876109ce565b6002820361038c5761034c818785886106b2565b600382036101b9576103a0818785886106cd565b94505b6040517fdce29136000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0384169063dce2913690602401600060405180830381600087803b1580156103fe57600080fd5b505af1158015610412573d6000803e3d6000fd5b505050508493505050505b949350505050565b600080600061043386610597565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa158015610475573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104999190610d12565b6040517f10d8d8e30000000000000000000000000000000000000000000000000000000081526004810189905291935091506001600160a01b038416906310d8d8e390602401600060405180830381600087803b1580156104f957600080fd5b505af115801561050d573d6000803e3d6000fd5b506000925061051a915050565b82036105385761052b818888610a15565b859450925061058f915050565b60048214806105475750600182145b156105585761052b83828989610a5c565b6002820361056c5761052b818489896106b2565b600382036101b957610580818489896106cd565b9550859450925061058f915050565b935093915050565b6000803083604051806101c001604052806101828152602001610de56101829139805160209182012060405161061a949392017fff00000000000000000000000000000000000000000000000000000000000000815260609390931b6bffffffffffffffffffffffff191660018401526015830191909152603582015260550190565b60408051601f1981840301815282825280516020918201207fd6940000000000000000000000000000000000000000000000000000000000008285015260601b6bffffffffffffffffffffffff191660228401527f0100000000000000000000000000000000000000000000000000000000000000603684015281516017818503018152603790930190915281519101209392505050565b6106c76001600160a01b038516848484610ab2565b50505050565b60006106fa7f1a771c70cada93a906f955a7dec24a83d7954ba2f75256be4febcf62b395d5325460021490565b15610731576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61075a60027f1a771c70cada93a906f955a7dec24a83d7954ba2f75256be4febcf62b395d53255565b6040516370a0823160e01b81526001600160a01b038481166004830152600091908716906370a0823190602401602060405180830381865afa1580156107a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c89190610d38565b90506107d6868686866106b2565b6040516370a0823160e01b81526001600160a01b03858116600483015260009183918916906370a0823190602401602060405180830381865afa158015610821573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108459190610d38565b61084f9190610d51565b905083811061085e5783610860565b805b9250505061041d60017f1a771c70cada93a906f955a7dec24a83d7954ba2f75256be4febcf62b395d53255565b6040516001600160a01b03831660248201526044810182905261093f907f9dc29fac00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526001600160a01b03851690610b36565b505050565b6040517f3416794d0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152838116602483015260448201839052851690633416794d906064015b600060405180830381600087803b1580156109b057600080fd5b505af11580156109c4573d6000803e3d6000fd5b5050505050505050565b6040516001600160a01b03831660248201526044810182905261093f907f79cc679000000000000000000000000000000000000000000000000000000000906064016108d0565b6040516001600160a01b03831660248201526044810182905261093f907f40c10f1900000000000000000000000000000000000000000000000000000000906064016108d0565b6040517f6bec32da0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152838116602483015260448201839052851690636bec32da90606401610996565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526106c79085905b600080836001600160a01b031683604051610b519190610d91565b6000604051808303816000865af19150503d8060008114610b8e576040519150601f19603f3d011682016040523d82523d6000602084013e610b93565b606091505b50915091506000828015610bbf575081511580610bbf575081806020019051810190610bbf9190610dc0565b9050801580610bd657506001600160a01b0385163b155b15610c0d576040517f045c4b0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6001600160a01b0381168114610c2957600080fd5b50565b60008060008060808587031215610c4257600080fd5b843593506020850135610c5481610c14565b92506040850135610c6481610c14565b9396929550929360600135925050565b60008060408385031215610c8757600080fd5b823591506020830135610c9981610c14565b809150509250929050565b8015158114610c2957600080fd5b60008060008060808587031215610cc857600080fd5b843593506020850135610c5481610ca4565b600080600060608486031215610cef57600080fd5b833592506020840135610d0181610c14565b929592945050506040919091013590565b60008060408385031215610d2557600080fd5b82516020840151909250610c9981610c14565b600060208284031215610d4a57600080fd5b5051919050565b81810381811115610d8b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b92915050565b6000825160005b81811015610db25760208186018101518583015201610d98565b506000920191825250919050565b600060208284031215610dd257600080fd5b8151610ddd81610ca4565b939250505056fe608060405234801561001057600080fd5b50610162806100206000396000f3fe60806040526004361061001d5760003560e01c806277436014610022575b600080fd5b61003561003036600461007b565b610037565b005b8051602082016000f061004957600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561008d57600080fd5b813567ffffffffffffffff808211156100a557600080fd5b818401915084601f8301126100b957600080fd5b8135818111156100cb576100cb61004c565b604051601f8201601f19908116603f011681019083821181831017156100f3576100f361004c565b8160405282815287602084870101111561010c57600080fd5b82602086016020830137600092810160200192909252509594505050505056fea264697066735822122094780ce55d28f1d568f4e0ab1b9dc230b96e952b73d2e06456fbff2289fa27f464736f6c63430008150033a2646970667358221220bd481061c7901aa7394be7532e7eb165ba693f95ddae103ae0330232ac37b5d064736f6c634300081b0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in FRAX
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.