Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00Multichain Info
N/A
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
TokenApprove
Compiler Version
v0.8.30+commit.73712a01
Optimization Enabled:
No with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "./interfaces/IERC20.sol"; import "./libraries/SafeERC20.sol"; /// @title Handle authorizations in dex platform /// @notice This contract is used to manage token approvals and ensure safe token transfers on a DEX platform. /// @dev This contract utilizes the SafeERC20 library for secure token transfers and provides functionality to update the approval proxy address. contract TokenApprove is OwnableUpgradeable { using SafeERC20 for IERC20; /// @notice The address authorized to initiate token transfers on behalf of users. address public tokenApproveProxy; /// @notice Initializes the contract by setting the token approval proxy address. /// @param _tokenApproveProxy The address authorized to initiate token transfers. function initialize(address _tokenApproveProxy) public initializer { __Ownable_init(); tokenApproveProxy = _tokenApproveProxy; } //------------------------------- //------- Events ---------------- //------------------------------- /// @notice Emitted when the token approval proxy address is updated. /// @param oldProxy The previous proxy address. /// @param newProxy The new proxy address. event ProxyUpdate(address indexed oldProxy, address indexed newProxy); //--------------------------------- //------- Admin functions --------- //--------------------------------- /// @notice Updates the token approval proxy address. /// @param _newTokenApproveProxy The new address authorized to initiate token transfers. /// @dev Can only be called by the contract owner. function setApproveProxy(address _newTokenApproveProxy) external onlyOwner { emit ProxyUpdate(tokenApproveProxy, _newTokenApproveProxy); tokenApproveProxy = _newTokenApproveProxy; } //--------------------------------- //------- User Functions -------- //--------------------------------- /// @notice Transfers tokens from one address to another on behalf of the token owner, using a pre-approved allowance. /// @param _token The address of the token to be transferred. /// @param _who The address of the token owner (the sender). /// @param _dest The address of the recipient (the receiver). /// @param _amount The amount of tokens to be transferred. /// @dev This function can only be called by the address set as `tokenApproveProxy`. function claimTokens( address _token, address _who, address _dest, uint256 _amount ) external { require( msg.sender == tokenApproveProxy, "TokenApprove: Access restricted" ); if (_amount > 0) { IERC20(_token).safeTransferFrom(_who, _dest, _amount); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IERC20 { event Approval( address indexed owner, address indexed spender, uint256 value ); event Transfer(address indexed from, address indexed to, uint256 value); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); }
/// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./SafeMath.sol"; import "./Address.sol"; import "./RevertReasonForwarder.sol"; import "../interfaces/IERC20.sol"; import "../interfaces/IERC20Permit.sol"; import "../interfaces/IDaiLikePermit.sol"; // File @1inch/solidity-utils/contracts/libraries/[email protected] library SafeERC20 { error SafeTransferFailed(); error SafeTransferFromFailed(); error ForceApproveFailed(); error SafeIncreaseAllowanceFailed(); error SafeDecreaseAllowanceFailed(); error SafePermitBadLength(); // Ensures method do not revert or return boolean `true`, admits call to non-smart-contract function safeTransferFrom(IERC20 token, address from, address to, uint256 amount) internal { bytes4 selector = token.transferFrom.selector; bool success; /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let data := mload(0x40) mstore(data, selector) mstore(add(data, 0x04), from) mstore(add(data, 0x24), to) mstore(add(data, 0x44), amount) success := call(gas(), token, 0, data, 100, 0x0, 0x20) if success { switch returndatasize() case 0 { success := gt(extcodesize(token), 0) } default { success := and(gt(returndatasize(), 31), eq(mload(0), 1)) } } } if (!success) revert SafeTransferFromFailed(); } // Ensures method do not revert or return boolean `true`, admits call to non-smart-contract function safeTransfer(IERC20 token, address to, uint256 value) internal { if (!_makeCall(token, token.transfer.selector, to, value)) { revert SafeTransferFailed(); } } function safeApprove(IERC20 token, address spender, uint256 value) internal { forceApprove(token, spender, value); } // If `approve(from, to, amount)` fails, try to `approve(from, to, 0)` before retry function forceApprove(IERC20 token, address spender, uint256 value) internal { if (!_makeCall(token, token.approve.selector, spender, value)) { if (!_makeCall(token, token.approve.selector, spender, 0) || !_makeCall(token, token.approve.selector, spender, value)) { revert ForceApproveFailed(); } } } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 allowance = token.allowance(address(this), spender); if (value > type(uint256).max - allowance) revert SafeIncreaseAllowanceFailed(); forceApprove(token, spender, allowance + value); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 allowance = token.allowance(address(this), spender); if (value > allowance) revert SafeDecreaseAllowanceFailed(); forceApprove(token, spender, allowance - value); } function safePermit(IERC20 token, bytes calldata permit) internal { bool success; if (permit.length == 32 * 7) { success = _makeCalldataCall(token, IERC20Permit.permit.selector, permit); } else if (permit.length == 32 * 8) { success = _makeCalldataCall(token, IDaiLikePermit.permit.selector, permit); } else { revert SafePermitBadLength(); } if (!success) RevertReasonForwarder.reRevert(); } function _makeCall(IERC20 token, bytes4 selector, address to, uint256 amount) private returns(bool success) { /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let data := mload(0x40) mstore(data, selector) mstore(add(data, 0x04), to) mstore(add(data, 0x24), amount) success := call(gas(), token, 0, data, 0x44, 0x0, 0x20) if success { switch returndatasize() case 0 { success := gt(extcodesize(token), 0) } default { success := and(gt(returndatasize(), 31), eq(mload(0), 1)) } } } } function _makeCalldataCall(IERC20 token, bytes4 selector, bytes calldata args) private returns(bool success) { /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let len := add(4, args.length) let data := mload(0x40) mstore(data, selector) calldatacopy(add(data, 0x04), args.offset, args.length) success := call(gas(), token, 0, data, len, 0x0, 0x20) if success { switch returndatasize() case 0 { success := gt(extcodesize(token), 0) } default { success := and(gt(returndatasize(), 31), eq(mload(0), 1)) } } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library SafeMath { uint256 constant WAD = 10**18; uint256 constant RAY = 10**27; function wad() public pure returns (uint256) { return WAD; } function ray() public pure returns (uint256) { return RAY; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a <= b ? a : b; } function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } function sqrt(uint256 a) internal pure returns (uint256 b) { if (a > 3) { b = a; uint256 x = a / 2 + 1; while (x < b) { b = x; x = (a / x + x) / 2; } } else if (a != 0) { b = 1; } } function wmul(uint256 a, uint256 b) internal pure returns (uint256) { return mul(a, b) / WAD; } function wmulRound(uint256 a, uint256 b) internal pure returns (uint256) { return add(mul(a, b), WAD / 2) / WAD; } function rmul(uint256 a, uint256 b) internal pure returns (uint256) { return mul(a, b) / RAY; } function rmulRound(uint256 a, uint256 b) internal pure returns (uint256) { return add(mul(a, b), RAY / 2) / RAY; } function wdiv(uint256 a, uint256 b) internal pure returns (uint256) { return div(mul(a, WAD), b); } function wdivRound(uint256 a, uint256 b) internal pure returns (uint256) { return add(mul(a, WAD), b / 2) / b; } function rdiv(uint256 a, uint256 b) internal pure returns (uint256) { return div(mul(a, RAY), b); } function rdivRound(uint256 a, uint256 b) internal pure returns (uint256) { return add(mul(a, RAY), b / 2) / b; } function wpow(uint256 x, uint256 n) internal pure returns (uint256) { uint256 result = WAD; while (n > 0) { if (n % 2 != 0) { result = wmul(result, x); } x = wmul(x, x); n /= 2; } return result; } function rpow(uint256 x, uint256 n) internal pure returns (uint256) { uint256 result = RAY; while (n > 0) { if (n % 2 != 0) { result = rmul(result, x); } x = rmul(x, x); n /= 2; } return result; } function divCeil(uint256 a, uint256 b) internal pure returns (uint256) { uint256 quotient = div(a, b); uint256 remainder = a - quotient * b; if (remainder > 0) { return quotient + 1; } else { return quotient; } } }
/// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Converts an `address` into `address payable`. Note that this is * simply a type cast: the actual underlying value is not changed. * * _Available since v2.4.0._ */ function toPayable(address account) internal pure returns (address payable) { return payable(account); } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. * * _Available since v2.4.0._ */ function sendValue(address recipient, uint256 amount) internal { require( address(this).balance >= amount, "Address: insufficient balance" ); // solhint-disable-next-line avoid-call-value (bool success, ) = recipient.call{value: amount}(""); require( success, "Address: unable to send value, recipient may have reverted" ); } }
/// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library RevertReasonForwarder { function reRevert() internal pure { // bubble up revert reason from latest external call /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens, * given `owner`'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for `permit`, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title Interface for DAI-style permits interface IDaiLikePermit { function permit( address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
{ "remappings": [ "@ensdomains/=node_modules/@ensdomains/", "@openzeppelin/=node_modules/@openzeppelin/", "ds-test/=lib/forge-std/lib/ds-test/src/", "eth-gas-reporter/=node_modules/eth-gas-reporter/", "forge-std/=lib/forge-std/src/", "hardhat/=node_modules/hardhat/", "@dex/=contracts/8/", "@uniswap/=node_modules/@uniswap/", "@zetachain/=node_modules/@zetachain/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "optimizer": { "enabled": false, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "cancun", "viaIR": false }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"SafeTransferFromFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldProxy","type":"address"},{"indexed":true,"internalType":"address","name":"newProxy","type":"address"}],"name":"ProxyUpdate","type":"event"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_who","type":"address"},{"internalType":"address","name":"_dest","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"claimTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenApproveProxy","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newTokenApproveProxy","type":"address"}],"name":"setApproveProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenApproveProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052348015600e575f5ffd5b50610c4c8061001c5f395ff3fe608060405234801561000f575f5ffd5b506004361061007b575f3560e01c80638da5cb5b116100595780638da5cb5b146100c3578063aad0ae5b146100e1578063c4d66de8146100fd578063f2fde38b146101195761007b565b80630a5ea4661461007f57806312ec8dcc1461009b578063715018a6146100b9575b5f5ffd5b6100996004803603810190610094919061086e565b610135565b005b6100a3610200565b6040516100b091906108e1565b60405180910390f35b6100c1610225565b005b6100cb610238565b6040516100d891906108e1565b60405180910390f35b6100fb60048036038101906100f691906108fa565b610260565b005b610117600480360381019061011291906108fa565b610326565b005b610133600480360381019061012e91906108fa565b6104a1565b005b60655f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101bb9061097f565b60405180910390fd5b5f8111156101fa576101f98383838773ffffffffffffffffffffffffffffffffffffffff16610523909392919063ffffffff16565b5b50505050565b60655f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61022d6105bb565b6102365f610639565b565b5f60335f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6102686105bb565b8073ffffffffffffffffffffffffffffffffffffffff1660655f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff213750e75b7d8975215501c91778a99d0e1d7e30453ea61619aba02b5e0d17d60405160405180910390a38060655f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f5f60019054906101000a900460ff16159050808015610356575060015f5f9054906101000a900460ff1660ff16105b806103835750610365306106fc565b158015610382575060015f5f9054906101000a900460ff1660ff16145b5b6103c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103b990610a0d565b60405180910390fd5b60015f5f6101000a81548160ff021916908360ff16021790555080156103fd5760015f60016101000a81548160ff0219169083151502179055505b61040561071e565b8160655f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550801561049d575f5f60016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104949190610a79565b60405180910390a15b5050565b6104a96105bb565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610517576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050e90610b02565b60405180910390fd5b61052081610639565b50565b5f6323b872dd60e01b90505f60405182815285600482015284602482015283604482015260205f6064835f8b5af19150811561057b573d5f81146105725760015f5114601f3d11169250610579565b5f883b1192505b505b50806105b3576040517ff405907100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b6105c3610776565b73ffffffffffffffffffffffffffffffffffffffff166105e1610238565b73ffffffffffffffffffffffffffffffffffffffff1614610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062e90610b6a565b60405180910390fd5b565b5f60335f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160335f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f5f8273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b5f60019054906101000a900460ff1661076c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076390610bf8565b60405180910390fd5b61077461077d565b565b5f33905090565b5f60019054906101000a900460ff166107cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107c290610bf8565b60405180910390fd5b6107db6107d6610776565b610639565b565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61080a826107e1565b9050919050565b61081a81610800565b8114610824575f5ffd5b50565b5f8135905061083581610811565b92915050565b5f819050919050565b61084d8161083b565b8114610857575f5ffd5b50565b5f8135905061086881610844565b92915050565b5f5f5f5f60808587031215610886576108856107dd565b5b5f61089387828801610827565b94505060206108a487828801610827565b93505060406108b587828801610827565b92505060606108c68782880161085a565b91505092959194509250565b6108db81610800565b82525050565b5f6020820190506108f45f8301846108d2565b92915050565b5f6020828403121561090f5761090e6107dd565b5b5f61091c84828501610827565b91505092915050565b5f82825260208201905092915050565b7f546f6b656e417070726f76653a204163636573732072657374726963746564005f82015250565b5f610969601f83610925565b915061097482610935565b602082019050919050565b5f6020820190508181035f8301526109968161095d565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c7265615f8201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b5f6109f7602e83610925565b9150610a028261099d565b604082019050919050565b5f6020820190508181035f830152610a24816109eb565b9050919050565b5f819050919050565b5f60ff82169050919050565b5f819050919050565b5f610a63610a5e610a5984610a2b565b610a40565b610a34565b9050919050565b610a7381610a49565b82525050565b5f602082019050610a8c5f830184610a6a565b92915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f610aec602683610925565b9150610af782610a92565b604082019050919050565b5f6020820190508181035f830152610b1981610ae0565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f610b54602083610925565b9150610b5f82610b20565b602082019050919050565b5f6020820190508181035f830152610b8181610b48565b9050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420695f8201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b5f610be2602b83610925565b9150610bed82610b88565b604082019050919050565b5f6020820190508181035f830152610c0f81610bd6565b905091905056fea264697066735822122089bfc386c8f71e8397737390c16d19be1ca59fa96287aa1a881e0fb98a9bc3ec64736f6c634300081e0033
Deployed Bytecode
0x608060405234801561000f575f5ffd5b506004361061007b575f3560e01c80638da5cb5b116100595780638da5cb5b146100c3578063aad0ae5b146100e1578063c4d66de8146100fd578063f2fde38b146101195761007b565b80630a5ea4661461007f57806312ec8dcc1461009b578063715018a6146100b9575b5f5ffd5b6100996004803603810190610094919061086e565b610135565b005b6100a3610200565b6040516100b091906108e1565b60405180910390f35b6100c1610225565b005b6100cb610238565b6040516100d891906108e1565b60405180910390f35b6100fb60048036038101906100f691906108fa565b610260565b005b610117600480360381019061011291906108fa565b610326565b005b610133600480360381019061012e91906108fa565b6104a1565b005b60655f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101bb9061097f565b60405180910390fd5b5f8111156101fa576101f98383838773ffffffffffffffffffffffffffffffffffffffff16610523909392919063ffffffff16565b5b50505050565b60655f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61022d6105bb565b6102365f610639565b565b5f60335f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6102686105bb565b8073ffffffffffffffffffffffffffffffffffffffff1660655f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff213750e75b7d8975215501c91778a99d0e1d7e30453ea61619aba02b5e0d17d60405160405180910390a38060655f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f5f60019054906101000a900460ff16159050808015610356575060015f5f9054906101000a900460ff1660ff16105b806103835750610365306106fc565b158015610382575060015f5f9054906101000a900460ff1660ff16145b5b6103c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103b990610a0d565b60405180910390fd5b60015f5f6101000a81548160ff021916908360ff16021790555080156103fd5760015f60016101000a81548160ff0219169083151502179055505b61040561071e565b8160655f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550801561049d575f5f60016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104949190610a79565b60405180910390a15b5050565b6104a96105bb565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610517576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050e90610b02565b60405180910390fd5b61052081610639565b50565b5f6323b872dd60e01b90505f60405182815285600482015284602482015283604482015260205f6064835f8b5af19150811561057b573d5f81146105725760015f5114601f3d11169250610579565b5f883b1192505b505b50806105b3576040517ff405907100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b6105c3610776565b73ffffffffffffffffffffffffffffffffffffffff166105e1610238565b73ffffffffffffffffffffffffffffffffffffffff1614610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062e90610b6a565b60405180910390fd5b565b5f60335f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160335f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f5f8273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b5f60019054906101000a900460ff1661076c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076390610bf8565b60405180910390fd5b61077461077d565b565b5f33905090565b5f60019054906101000a900460ff166107cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107c290610bf8565b60405180910390fd5b6107db6107d6610776565b610639565b565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61080a826107e1565b9050919050565b61081a81610800565b8114610824575f5ffd5b50565b5f8135905061083581610811565b92915050565b5f819050919050565b61084d8161083b565b8114610857575f5ffd5b50565b5f8135905061086881610844565b92915050565b5f5f5f5f60808587031215610886576108856107dd565b5b5f61089387828801610827565b94505060206108a487828801610827565b93505060406108b587828801610827565b92505060606108c68782880161085a565b91505092959194509250565b6108db81610800565b82525050565b5f6020820190506108f45f8301846108d2565b92915050565b5f6020828403121561090f5761090e6107dd565b5b5f61091c84828501610827565b91505092915050565b5f82825260208201905092915050565b7f546f6b656e417070726f76653a204163636573732072657374726963746564005f82015250565b5f610969601f83610925565b915061097482610935565b602082019050919050565b5f6020820190508181035f8301526109968161095d565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c7265615f8201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b5f6109f7602e83610925565b9150610a028261099d565b604082019050919050565b5f6020820190508181035f830152610a24816109eb565b9050919050565b5f819050919050565b5f60ff82169050919050565b5f819050919050565b5f610a63610a5e610a5984610a2b565b610a40565b610a34565b9050919050565b610a7381610a49565b82525050565b5f602082019050610a8c5f830184610a6a565b92915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f610aec602683610925565b9150610af782610a92565b604082019050919050565b5f6020820190508181035f830152610b1981610ae0565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f610b54602083610925565b9150610b5f82610b20565b602082019050919050565b5f6020820190508181035f830152610b8181610b48565b9050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420695f8201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b5f610be2602b83610925565b9150610bed82610b88565b604082019050919050565b5f6020820190508181035f830152610c0f81610bd6565b905091905056fea264697066735822122089bfc386c8f71e8397737390c16d19be1ca59fa96287aa1a881e0fb98a9bc3ec64736f6c634300081e0033
Loading...
Loading
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.