More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 2,537 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer ERC20 | 20298026 | 4 days ago | IN | 0 ETH | 0.00023066 | ||||
Transfer ERC20 | 20258837 | 9 days ago | IN | 0 ETH | 0.00022943 | ||||
Batch Transfer E... | 20252380 | 10 days ago | IN | 0 ETH | 0.00036522 | ||||
Transfer ERC20 | 20248521 | 10 days ago | IN | 0 ETH | 0.0010042 | ||||
Transfer ERC20 | 20248500 | 10 days ago | IN | 0 ETH | 0.00096176 | ||||
Transfer ERC20 | 20248489 | 10 days ago | IN | 0 ETH | 0.00098862 | ||||
Transfer ERC20 | 20248404 | 10 days ago | IN | 0 ETH | 0.00072395 | ||||
Transfer ERC20 | 20248394 | 10 days ago | IN | 0 ETH | 0.00103677 | ||||
Transfer ERC20 | 20248380 | 10 days ago | IN | 0 ETH | 0.00102703 | ||||
Transfer ERC20 | 20248362 | 10 days ago | IN | 0 ETH | 0.00046308 | ||||
Transfer ERC20 | 20248342 | 10 days ago | IN | 0 ETH | 0.00098743 | ||||
Transfer ERC20 | 20248296 | 10 days ago | IN | 0 ETH | 0.00057239 | ||||
Transfer ERC20 | 20248269 | 10 days ago | IN | 0 ETH | 0.0005139 | ||||
Transfer ERC20 | 20248266 | 10 days ago | IN | 0 ETH | 0.00098735 | ||||
Transfer ERC20 | 20247044 | 11 days ago | IN | 0 ETH | 0.00040421 | ||||
Transfer ERC20 | 20247008 | 11 days ago | IN | 0 ETH | 0.00054708 | ||||
Transfer ERC20 | 20246971 | 11 days ago | IN | 0 ETH | 0.00066875 | ||||
Transfer ERC20 | 20245065 | 11 days ago | IN | 0 ETH | 0.0005172 | ||||
Transfer ERC20 | 20245038 | 11 days ago | IN | 0 ETH | 0.00053042 | ||||
Transfer ERC20 | 20245006 | 11 days ago | IN | 0 ETH | 0.00053247 | ||||
Transfer ERC20 | 20244979 | 11 days ago | IN | 0 ETH | 0.0004334 | ||||
Transfer ERC20 | 20244968 | 11 days ago | IN | 0 ETH | 0.00026211 | ||||
Transfer ERC20 | 20244967 | 11 days ago | IN | 0 ETH | 0.00052514 | ||||
Transfer ERC20 | 20244757 | 11 days ago | IN | 0 ETH | 0.00047778 | ||||
Transfer ERC20 | 20244743 | 11 days ago | IN | 0 ETH | 0.00033554 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
Transfer
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// contracts/delegator.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "./Vault.sol"; /// @title Harpie Transfer Contract /// @author https://harpie.io, 2022 /// @notice This contract is designed to move ERC20s and ERC721s from user wallets into the noncustodial Vault contract. /// After receiving user Approval, it uses server-side EOAs to call below functions when we detect malicious transactions. contract Transfer { /// @dev We use safeERC20 to work with noncompliant ERC20s using SafeERC20 for IERC20; /// @dev ERC20Details and ERC721Details are used to define an individual /// token, along with its owner. these are used in our batchTransfer functions /// @param ownerAddress The owner of the token /// @param fee The fee we charge users as they recover their assets struct ERC20Details { address ownerAddress; address erc20Address; uint128 erc20Fee; } struct ERC721Details { address ownerAddress; address erc721Address; uint128 erc721Fee; uint256 erc721Id; } /// @notice We've hardcoded the address that this contract transfers tokens to, /// so your Approved tokens can only move to our noncustodial vault /// @dev vaultAddress is the address of our noncustodial Vault contract address immutable private vaultAddress; /// @dev transferEOASetter is an EOA that can set other EOAs as callers of the /// Transfer functions below address immutable private transferEOASetter; /// @dev This flag denotes if transferEOASetter is able to set more _transferEOAs /// Defaults to true bool private canSetAdditionalTransferEOAs = true; /// @dev a mapping of all possible EOAs that can call Transfer functions mapping(address => bool) private _transferEOAs; /// @dev Immutables are set upon contract construction for safety constructor(address _vaultAddress, address _transferEOASetter) { vaultAddress = _vaultAddress; transferEOASetter = _transferEOASetter; } /// @dev These events fire when a token transfer and subsequent logging is successful event successfulERC721Transfer(address ownerAddress, address erc721Address, uint256 tokenId); event successfulERC20Transfer(address ownerAddress, address erc20Address); /// @dev These events fire when an individual Transfer in a batchTransfer fails event failedERC721Transfer(address ownerAddress, address erc721Address, uint256 tokenId); event failedERC20Transfer(address ownerAddress, address erc20Address); /// @notice This function transfers ERC721s to a noncustodial vault contract. function transferERC721(address _ownerAddress, address _erc721Address, uint256 _erc721Id, uint128 _fee) public returns (bool) { require(_transferEOAs[msg.sender] == true || msg.sender == address(this), "Caller must be an approved caller."); require(_erc721Address != address(this)); (bool transferSuccess, bytes memory transferResult) = address(_erc721Address).call( abi.encodeCall(IERC721(_erc721Address).transferFrom, (_ownerAddress, vaultAddress, _erc721Id)) ); require(transferSuccess, string (transferResult)); (bool loggingSuccess, bytes memory loggingResult) = address(vaultAddress).call( abi.encodeCall(Vault.logIncomingERC721, (_ownerAddress, _erc721Address, _erc721Id, _fee)) ); require(loggingSuccess, string (loggingResult)); emit successfulERC721Transfer(_ownerAddress, _erc721Address, _erc721Id); return transferSuccess; } /// @notice Batch transfering ERC721s in case we need to handle a large set of addresses at once (ie. protocol attack) /// @dev Care must be taken to pass good data, this function does not revert when a single transaction throws function batchTransferERC721(ERC721Details[] memory _details) public returns (bool) { require(_transferEOAs[msg.sender] == true, "Caller must be an approved caller."); for (uint256 i=0; i<_details.length; i++ ) { // If statement adds a bit more gas cost, but allows us to continue the loop even if a // token is not in a user's wallet anymore, instead of reverting the whole batch try this.transferERC721{gas:400e3}(_details[i].ownerAddress, _details[i].erc721Address, _details[i].erc721Id, _details[i].erc721Fee) {} catch { emit failedERC721Transfer(_details[i].ownerAddress, _details[i].erc721Address, _details[i].erc721Id); } } return true; } /// @notice This function transfers ERC20s to a noncustodial vault contract. function transferERC20(address _ownerAddress, address _erc20Address, uint128 _fee) public returns (bool) { require (_transferEOAs[msg.sender] == true || msg.sender == address(this), "Caller must be an approved caller."); require(_erc20Address != address(this)); // Get balance of vault prior to our transfer uint256 vaultBalanceBeforeTransfer = IERC20(_erc20Address).balanceOf(vaultAddress); // Transfer a user's current balance in their wallet uint256 balance = IERC20(_erc20Address).balanceOf(_ownerAddress); IERC20(_erc20Address).safeTransferFrom( _ownerAddress, vaultAddress, balance ); // Instead of using that transferred balance as the logged balance, we use the change in vaultBalance // This is for fee-on-transfer tokens uint256 vaultBalanceAfterTransfer = IERC20(_erc20Address).balanceOf(vaultAddress) - vaultBalanceBeforeTransfer; (bool loggingSuccess, bytes memory loggingResult) = address(vaultAddress).call( abi.encodeCall(Vault.logIncomingERC20, (_ownerAddress, _erc20Address, vaultBalanceAfterTransfer, _fee)) ); require(loggingSuccess, string (loggingResult)); emit successfulERC20Transfer(_ownerAddress, _erc20Address); return loggingSuccess; } /// @notice Batch transfering ERC20s in case we need to handle a large set of addresses at once (ie. protocol attack) /// @dev Care must be taken to pass good data, this function does not revert when a single transaction throws function batchTransferERC20(ERC20Details[] memory _details) public returns (bool) { require(_transferEOAs[msg.sender] == true, "Caller must be an approved caller."); for (uint256 i=0; i<_details.length; i++ ) { try this.transferERC20{gas:400e3}(_details[i].ownerAddress, _details[i].erc20Address, _details[i].erc20Fee) {} catch { emit failedERC20Transfer(_details[i].ownerAddress, _details[i].erc20Address); } } return true; } /// @dev This adds or removes transferEOAs that can call the above functions function addTransferEOA(address _newTransferEOA) public { require(canSetAdditionalTransferEOAs, "Cannot add any additional transferEOAs."); require(msg.sender == transferEOASetter, "Caller must be an approved caller."); _transferEOAs[_newTransferEOA] = true; } /// @dev This removes transferEOAs that can call the above functions function removeTransferEOA(address _eoaToBeRemoved) public { require(msg.sender == transferEOASetter, "Caller must be an approved caller."); _transferEOAs[_eoaToBeRemoved] = false; } /// @notice This safeguard is in place to prevent the malicious setting of new transferEOAs /// @dev This removes the ability to set new transferEOAs PERMANENTLY function removeAbilityToSetNewTransferEOAs() public { require(msg.sender == transferEOASetter, "Caller must be an approved caller."); canSetAdditionalTransferEOAs = false; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// contracts/delegator.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/interfaces/IERC721.sol"; import "@openzeppelin/contracts/interfaces/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts/utils/math/SafeCast.sol"; /// @title Harpie Vault Contract /// @author https://harpie.io, 2022 /// @notice This contract is designed to hold ERC20s and ERC721s from user wallets and allow only them to withdraw. /// Users will have to pay a designated fee in order to withdraw their ERC20s and ERC721s. /// In case we need to reduce fees for each user, we have reduceFee functions we can call. contract Vault { using ECDSA for bytes32; using SafeCast for uint128; using SafeCast for uint256; /// @dev We use safeERC20 for noncompliant ERC20s using SafeERC20 for IERC20; /// @dev This struct defines the amount of an ERC20 stored, and the fee required to withdraw struct erc20Struct { uint128 amountStored; uint128 fee; } /// @dev This struct defines if an ERC721 id is stored, and the fee required to withdraw struct erc721Struct { bool isStored; uint128 fee; } /// @dev This struct stores the block.timestamp and new address of a changeFeeControllerRequest /// @dev A request is in the shape of newFeeController, block.timestamp struct changeFeeControllerStruct { address payable newFeeController; uint256 blocktime; } /// @dev The address of the Transfer contract linked to this contract address private immutable transferer; /// @notice The serverSigner is an EOA responsible for providing the signature of changeRecipientAddress address private immutable serverSigner; /// @notice The feeController is an EOA that's able to only reduce the fees of users and withdraw our fees address payable private feeController; /// @notice The emergencyFeeRemover is an EOA that has permission to zero out the fees across the platform /// The purpose of the emergencyFeeRemover is to react to protocol attacks and take action /// by allowing users to withdraw their assets from the platform without fees address private immutable emergencyFeeRemover; /// @notice When this flag is turned on, users will be able to freely withdraw their stored assets /// @dev This should only be turned on in case of a protocol attack bool private canWithdrawWithoutFeesEmergencyFlag = false; /// @dev This is the most recent changeFeeControllerRequest changeFeeControllerStruct public pendingFeeController; /// @dev This mapping is a one-to-one that defines who can withdraw a user's transfered funds mapping(address => address) private _recipientAddress; /// @dev These mappings define the tokens a user can withdraw from the Vault and the fees to withdraw mapping(address => mapping(address => erc20Struct)) private _erc20WithdrawalAllowances; mapping(address => mapping(address => mapping (uint256 => erc721Struct))) private _erc721WithdrawalAllowances; /// @dev This mapping prevents the reuse of a signature to changeRecipientAddress or an out-of-order usage mapping(address => uint256) private _changeRecipientNonces; /// @dev Immutables like transferer and serverSigner are set during construction for safety constructor(address _transferer, address _serverSigner, address payable _feeController, address _emergencyFeeRemover) { transferer = _transferer; serverSigner = _serverSigner; feeController = _feeController; emergencyFeeRemover = _emergencyFeeRemover; } /// @notice Allow users to set up a recipient address for collecting stored assets function setupRecipientAddress(address _recipient) external { require(_recipientAddress[msg.sender] == address(0), "You already have registered a recipient address"); _recipientAddress[msg.sender] = _recipient; } /// @notice Allow users to change their recipient address. Requires a signature from our serverSigner /// to allow this transaction to fire function changeRecipientAddress(bytes memory _signature, address _newRecipientAddress, uint256 expiry) external { /// @dev Have server sign a message in the format [protectedWalletAddress, newRecipientAddress, exp, nonce, vaultAddress, block.chainId] /// msg.sender == protectedWalletAddress (meaning that the protected wallet will submit this transaction) /// @notice We require the extra signature in case we add 2fa in some way in future bytes32 data = keccak256(abi.encodePacked(msg.sender, _newRecipientAddress, expiry, getNonce(msg.sender), address(this), block.chainid)); require(data.toEthSignedMessageHash().recover(_signature) == serverSigner, "Invalid signature. Signature source may be incorrect, or a provided parameter is invalid"); require(block.timestamp <= expiry, "Signature expired"); _changeRecipientNonces[msg.sender]++; _recipientAddress[msg.sender] = _newRecipientAddress; } /// @notice Get nonces for the above function function getNonce(address _caller) public view returns (uint256) { return _changeRecipientNonces[_caller]; } /// @notice View which address is authorized to withdraw assets function viewRecipientAddress(address _originalAddress) public view returns (address) { return _recipientAddress[_originalAddress]; } /// @notice Log functions fire when the vault receives an ERC20 or ER721 from Transfer.sol function logIncomingERC20(address _originalAddress, address _erc20Address, uint256 _amount, uint128 _fee) external{ require(msg.sender == transferer, "Only the transferer contract can log funds."); _erc20WithdrawalAllowances[_originalAddress][_erc20Address].fee += _fee; _erc20WithdrawalAllowances[_originalAddress][_erc20Address].amountStored += _amount.toUint128(); } function logIncomingERC721(address _originalAddress, address _erc721Address, uint256 _id, uint128 _fee) external { require(msg.sender == transferer, "Only the transferer contract can log funds."); _erc721WithdrawalAllowances[_originalAddress][_erc721Address][_id].fee += _fee; _erc721WithdrawalAllowances[_originalAddress][_erc721Address][_id].isStored = true; } /// @notice These functions can be called to view an addresses' stored balances and the fees to withdraw them function canWithdrawERC20(address _originalAddress, address _erc20Address) public view returns (uint256) { return _erc20WithdrawalAllowances[_originalAddress][_erc20Address].amountStored; } function canWithdrawERC721(address _originalAddress, address _erc721Address, uint256 _id) public view returns (bool) { return _erc721WithdrawalAllowances[_originalAddress][_erc721Address][_id].isStored; } function erc20Fee(address _originalAddress, address _erc20Address) public view returns (uint128) { return _erc20WithdrawalAllowances[_originalAddress][_erc20Address].fee; } function erc721Fee(address _originalAddress, address _erc721Address, uint256 _id) public view returns (uint128) { return _erc721WithdrawalAllowances[_originalAddress][_erc721Address][_id].fee; } /// @notice Withdrawal functions allow users to withdraw their assets after paying the ETH withdrawal fee /// @dev A few guards are placed to avoid erroneous withdrawals. /// - caller must be a recipient address of the assets of _originalAddress /// - there must be an allowance in the _originalAddress's withdrawal allowance /// - the _erc20Address must not be address(this) /// - the msg.value must be >= the withdrawal fee function withdrawERC20(address _originalAddress, address _erc20Address) payable external { require(_recipientAddress[_originalAddress] == msg.sender, "Function caller is not an authorized recipientAddress."); require(_erc20Address != address(this), "The vault is not a token address"); require(canWithdrawERC20(_originalAddress, _erc20Address) > 0, "No withdrawal allowance."); require(msg.value >= _erc20WithdrawalAllowances[_originalAddress][_erc20Address].fee, "Insufficient payment."); uint256 amount = canWithdrawERC20(_originalAddress, _erc20Address); _erc20WithdrawalAllowances[_originalAddress][_erc20Address].amountStored = 0; _erc20WithdrawalAllowances[_originalAddress][_erc20Address].fee = 0; IERC20(_erc20Address).safeTransfer(msg.sender, amount); } function withdrawERC721(address _originalAddress, address _erc721Address, uint256 _id) payable external { require(_recipientAddress[_originalAddress] == msg.sender, "Function caller is not an authorized recipientAddress."); require(_erc721Address != address(this), "The vault is not a token address"); require(canWithdrawERC721(_originalAddress, _erc721Address, _id), "Insufficient withdrawal allowance."); require(msg.value >= _erc721WithdrawalAllowances[_originalAddress][_erc721Address][_id].fee, "Insufficient payment."); _erc721WithdrawalAllowances[_originalAddress][_erc721Address][_id].isStored = false; _erc721WithdrawalAllowances[_originalAddress][_erc721Address][_id].fee = 0; IERC721(_erc721Address).safeTransferFrom(address(this), msg.sender, _id); } /// @notice Emergency withdrawal functions allow users to withdraw their assets without paying the ETH withdrawal fee /// @dev A few guards are placed to avoid erroneous withdrawals /// - The flag `canWithdrawWithoutFees` must be set to true /// - caller must be a recipient address of the assets of _originalAddress /// - there must be an allowance in the _originalAddress's withdrawal allowance /// - the _erc20Address must not be address(this) function withdrawERC20WithoutFees(address _originalAddress, address _erc20Address) external { require(canWithdrawWithoutFeesEmergencyFlag, "Emergency flag not set"); require(_recipientAddress[_originalAddress] == msg.sender, "Function caller is not an authorized recipientAddress."); require(_erc20Address != address(this), "The vault is not a token address"); require(canWithdrawERC20(_originalAddress, _erc20Address) > 0, "No withdrawal allowance."); uint256 amount = canWithdrawERC20(_originalAddress, _erc20Address); _erc20WithdrawalAllowances[_originalAddress][_erc20Address].amountStored = 0; _erc20WithdrawalAllowances[_originalAddress][_erc20Address].fee = 0; IERC20(_erc20Address).safeTransfer(msg.sender, amount); } function withdrawERC721WithoutFees(address _originalAddress, address _erc721Address, uint256 _id) external { require(canWithdrawWithoutFeesEmergencyFlag, "Emergency flag not set"); require(_recipientAddress[_originalAddress] == msg.sender, "Function caller is not an authorized recipientAddress."); require(_erc721Address != address(this), "The vault is not a token address"); require(canWithdrawERC721(_originalAddress, _erc721Address, _id), "Insufficient withdrawal allowance."); _erc721WithdrawalAllowances[_originalAddress][_erc721Address][_id].isStored = false; _erc721WithdrawalAllowances[_originalAddress][_erc721Address][_id].fee = 0; IERC721(_erc721Address).safeTransferFrom(address(this), msg.sender, _id); } /// @notice These functions allow Harpie to reduce (but never increase) the fee upon a user function reduceERC20Fee(address _originalAddress, address _erc20Address, uint128 _reduceBy) external returns (uint128) { require(msg.sender == feeController, "msg.sender must be feeController."); require(_erc20WithdrawalAllowances[_originalAddress][_erc20Address].fee >= _reduceBy, "You cannot reduce more than the current fee."); _erc20WithdrawalAllowances[_originalAddress][_erc20Address].fee -= _reduceBy; return _erc20WithdrawalAllowances[_originalAddress][_erc20Address].fee; } function reduceERC721Fee(address _originalAddress, address _erc721Address, uint256 _id, uint128 _reduceBy) external returns (uint128) { require(msg.sender == feeController, "msg.sender must be feeController."); require(_erc721WithdrawalAllowances[_originalAddress][_erc721Address][_id].fee >= _reduceBy, "You cannot reduce more than the current fee."); _erc721WithdrawalAllowances[_originalAddress][_erc721Address][_id].fee -= _reduceBy; return _erc721WithdrawalAllowances[_originalAddress][_erc721Address][_id].fee; } /// @notice This function allows us to withdraw the fees we collect in this contract function withdrawPayments(uint256 _amount) external { require(msg.sender == feeController, "msg.sender must be feeController."); require(address(this).balance >= _amount, "Cannot withdraw more than the amount in the contract."); (bool success, ) = feeController.call{value: _amount}(""); require(success, "Transfer failed"); } /// @notice This function creates a timelock for the changeFeeController functionality function changeFeeControllerRequest(address payable _newFeeController) external { require(msg.sender == feeController, "msg.sender must be the current feeController."); // This sets the pending request, regardless of if an existing request exists already pendingFeeController = changeFeeControllerStruct(_newFeeController, block.timestamp); } /// @notice This function allows us to change the signer that we use to reduce and withdraw fees function changeFeeController() external { require(msg.sender == feeController, "msg.sender must be the current feeController."); // If no timelock request is available, revert require(pendingFeeController.blocktime > 0, "Submit a timelock request before calling this function."); require(pendingFeeController.blocktime + 1209600 < block.timestamp, "Request must pass a two-week timelock."); require(pendingFeeController.blocktime + 1296000 > block.timestamp, "Request expired. Requests must occur within 24 hours of a completed timelock."); feeController = pendingFeeController.newFeeController; changeFeeControllerStruct memory newStruct; pendingFeeController = newStruct; } /// @notice This function toggles the canWithdrawWithoutFeesEmergencyFlag /// @dev This should only be turned to true in case of a protocol attack function toggleEmergencyFlag(bool _newSetting) external { require(msg.sender == emergencyFeeRemover, "Only callable by immutable emergencyFeeRemover role"); canWithdrawWithoutFeesEmergencyFlag = _newSetting; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) 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 // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * ==== * * [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://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]. */ 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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(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) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol) pragma solidity ^0.8.0; import "../token/ERC721/IERC721.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol) pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248) { require(value >= type(int248).min && value <= type(int248).max, "SafeCast: value doesn't fit in 248 bits"); return int248(value); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240) { require(value >= type(int240).min && value <= type(int240).max, "SafeCast: value doesn't fit in 240 bits"); return int240(value); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232) { require(value >= type(int232).min && value <= type(int232).max, "SafeCast: value doesn't fit in 232 bits"); return int232(value); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224) { require(value >= type(int224).min && value <= type(int224).max, "SafeCast: value doesn't fit in 224 bits"); return int224(value); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216) { require(value >= type(int216).min && value <= type(int216).max, "SafeCast: value doesn't fit in 216 bits"); return int216(value); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208) { require(value >= type(int208).min && value <= type(int208).max, "SafeCast: value doesn't fit in 208 bits"); return int208(value); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200) { require(value >= type(int200).min && value <= type(int200).max, "SafeCast: value doesn't fit in 200 bits"); return int200(value); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192) { require(value >= type(int192).min && value <= type(int192).max, "SafeCast: value doesn't fit in 192 bits"); return int192(value); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184) { require(value >= type(int184).min && value <= type(int184).max, "SafeCast: value doesn't fit in 184 bits"); return int184(value); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176) { require(value >= type(int176).min && value <= type(int176).max, "SafeCast: value doesn't fit in 176 bits"); return int176(value); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168) { require(value >= type(int168).min && value <= type(int168).max, "SafeCast: value doesn't fit in 168 bits"); return int168(value); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160) { require(value >= type(int160).min && value <= type(int160).max, "SafeCast: value doesn't fit in 160 bits"); return int160(value); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152) { require(value >= type(int152).min && value <= type(int152).max, "SafeCast: value doesn't fit in 152 bits"); return int152(value); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144) { require(value >= type(int144).min && value <= type(int144).max, "SafeCast: value doesn't fit in 144 bits"); return int144(value); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136) { require(value >= type(int136).min && value <= type(int136).max, "SafeCast: value doesn't fit in 136 bits"); return int136(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits"); return int128(value); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120) { require(value >= type(int120).min && value <= type(int120).max, "SafeCast: value doesn't fit in 120 bits"); return int120(value); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112) { require(value >= type(int112).min && value <= type(int112).max, "SafeCast: value doesn't fit in 112 bits"); return int112(value); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104) { require(value >= type(int104).min && value <= type(int104).max, "SafeCast: value doesn't fit in 104 bits"); return int104(value); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96) { require(value >= type(int96).min && value <= type(int96).max, "SafeCast: value doesn't fit in 96 bits"); return int96(value); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88) { require(value >= type(int88).min && value <= type(int88).max, "SafeCast: value doesn't fit in 88 bits"); return int88(value); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80) { require(value >= type(int80).min && value <= type(int80).max, "SafeCast: value doesn't fit in 80 bits"); return int80(value); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72) { require(value >= type(int72).min && value <= type(int72).max, "SafeCast: value doesn't fit in 72 bits"); return int72(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits"); return int64(value); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56) { require(value >= type(int56).min && value <= type(int56).max, "SafeCast: value doesn't fit in 56 bits"); return int56(value); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48) { require(value >= type(int48).min && value <= type(int48).max, "SafeCast: value doesn't fit in 48 bits"); return int48(value); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40) { require(value >= type(int40).min && value <= type(int40).max, "SafeCast: value doesn't fit in 40 bits"); return int40(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits"); return int32(value); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24) { require(value >= type(int24).min && value <= type(int24).max, "SafeCast: value doesn't fit in 24 bits"); return int24(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits"); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits"); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_vaultAddress","type":"address"},{"internalType":"address","name":"_transferEOASetter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"ownerAddress","type":"address"},{"indexed":false,"internalType":"address","name":"erc20Address","type":"address"}],"name":"failedERC20Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"ownerAddress","type":"address"},{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"failedERC721Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"ownerAddress","type":"address"},{"indexed":false,"internalType":"address","name":"erc20Address","type":"address"}],"name":"successfulERC20Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"ownerAddress","type":"address"},{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"successfulERC721Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"_newTransferEOA","type":"address"}],"name":"addTransferEOA","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"ownerAddress","type":"address"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"uint128","name":"erc20Fee","type":"uint128"}],"internalType":"struct Transfer.ERC20Details[]","name":"_details","type":"tuple[]"}],"name":"batchTransferERC20","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"ownerAddress","type":"address"},{"internalType":"address","name":"erc721Address","type":"address"},{"internalType":"uint128","name":"erc721Fee","type":"uint128"},{"internalType":"uint256","name":"erc721Id","type":"uint256"}],"internalType":"struct Transfer.ERC721Details[]","name":"_details","type":"tuple[]"}],"name":"batchTransferERC721","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"removeAbilityToSetNewTransferEOAs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_eoaToBeRemoved","type":"address"}],"name":"removeTransferEOA","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ownerAddress","type":"address"},{"internalType":"address","name":"_erc20Address","type":"address"},{"internalType":"uint128","name":"_fee","type":"uint128"}],"name":"transferERC20","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ownerAddress","type":"address"},{"internalType":"address","name":"_erc721Address","type":"address"},{"internalType":"uint256","name":"_erc721Id","type":"uint256"},{"internalType":"uint128","name":"_fee","type":"uint128"}],"name":"transferERC721","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c060405260016000806101000a81548160ff0219169083151502179055503480156200002b57600080fd5b50604051620021f9380380620021f983398181016040528101906200005191906200012b565b8173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1681525050505062000172565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000f382620000c6565b9050919050565b6200010581620000e6565b81146200011157600080fd5b50565b6000815190506200012581620000fa565b92915050565b60008060408385031215620001455762000144620000c1565b5b6000620001558582860162000114565b9250506020620001688582860162000114565b9150509250929050565b60805160a051612030620001c9600039600081816103dc01528181610846015261097c0152600081816105c0015281816106d101528181610b8501528181610c8701528181610cef0152610d7c01526120306000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80635016ff451161005b5780635016ff45146100ec578063cfeb243c14610108578063da335dda14610124578063dde5150f146101545761007d565b80630457be17146100825780630fe0522b146100b257806335332bfe146100bc575b600080fd5b61009c600480360381019061009791906116cf565b610184565b6040516100a99190611733565b60405180910390f35b6100ba6103da565b005b6100d660048036038101906100d1919061174e565b610484565b6040516100e39190611733565b60405180910390f35b610106600480360381019061010191906117b5565b610844565b005b610122600480360381019061011d91906117b5565b61092d565b005b61013e600480360381019061013991906117e2565b610a62565b60405161014b9190611733565b60405180910390f35b61016e6004803603810190610169919061195c565b610eed565b60405161017b9190611733565b60405180910390f35b600060011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514610219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161021090611a28565b60405180910390fd5b60005b82518110156103d0573073ffffffffffffffffffffffffffffffffffffffff166335332bfe62061a8085848151811061025857610257611a48565b5b60200260200101516000015186858151811061027757610276611a48565b5b60200260200101516020015187868151811061029657610295611a48565b5b6020026020010151606001518887815181106102b5576102b4611a48565b5b6020026020010151604001516040518663ffffffff1660e01b81526004016102e09493929190611aa4565b60206040518083038160008887f19350505050801561031d57506040513d601f19601f8201168201806040525081019061031a9190611b15565b60015b6103bb577f956d62b2c81b8b6384d5e4efa8b9058d517b234e29c20ea8064168ea5a57d3c783828151811061035557610354611a48565b5b60200260200101516000015184838151811061037457610373611a48565b5b60200260200101516020015185848151811061039357610392611a48565b5b6020026020010151606001516040516103ae93929190611b42565b60405180910390a16103bd565b505b80806103c890611ba8565b91505061021c565b5060019050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610468576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045f90611a28565b60405180910390fd5b60008060006101000a81548160ff021916908315150217905550565b600060011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515148061051057503073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61054f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161054690611a28565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361058757600080fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff166323b872dd897f0000000000000000000000000000000000000000000000000000000000000000896040516024016105f293929190611b42565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516106419190611c6a565b6000604051808303816000865af19150503d806000811461067e576040519150601f19603f3d011682016040523d82523d6000602084013e610683565b606091505b50915091508181906106cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c29190611cc5565b60405180910390fd5b506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168989898960405160240161071d9493929190611aa4565b60405160208183030381529060405263f574e2b660e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161076f9190611c6a565b6000604051808303816000865af19150503d80600081146107ac576040519150601f19603f3d011682016040523d82523d6000602084013e6107b1565b606091505b50915091508181906107f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f09190611cc5565b60405180910390fd5b507f3bec20ff024c042477bd629a21e97e55b8a5502c04b3773e699009e69fcb532089898960405161082d93929190611b42565b60405180910390a183945050505050949350505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c990611a28565b60405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008054906101000a900460ff1661097a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097190611d59565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a08576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ff90611a28565b60405180910390fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600060011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151480610aee57503073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610b2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b2490611a28565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b6557600080fd5b60008373ffffffffffffffffffffffffffffffffffffffff166370a082317f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401610bc09190611d79565b602060405180830381865afa158015610bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c019190611da9565b905060008473ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b8152600401610c3e9190611d79565b602060405180830381865afa158015610c5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7f9190611da9565b9050610cce867f0000000000000000000000000000000000000000000000000000000000000000838873ffffffffffffffffffffffffffffffffffffffff16611103909392919063ffffffff16565b6000828673ffffffffffffffffffffffffffffffffffffffff166370a082317f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401610d2a9190611d79565b602060405180830381865afa158015610d47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6b9190611da9565b610d759190611dd6565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168989858a604051602401610dc89493929190611aa4565b604051602081830303815290604052633d602dbe60e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610e1a9190611c6a565b6000604051808303816000865af19150503d8060008114610e57576040519150601f19603f3d011682016040523d82523d6000602084013e610e5c565b606091505b5091509150818190610ea4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9b9190611cc5565b60405180910390fd5b507ff93b052819f594a764a6b528a0d3d2296bf30fddd860b97bb1c7e571e226df2e8989604051610ed6929190611e0a565b60405180910390a181955050505050509392505050565b600060011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514610f82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7990611a28565b60405180910390fd5b60005b82518110156110f9573073ffffffffffffffffffffffffffffffffffffffff1663da335dda62061a80858481518110610fc157610fc0611a48565b5b602002602001015160000151868581518110610fe057610fdf611a48565b5b602002602001015160200151878681518110610fff57610ffe611a48565b5b6020026020010151604001516040518563ffffffff1660e01b815260040161102993929190611e33565b60206040518083038160008887f19350505050801561106657506040513d601f19601f820116820180604052508101906110639190611b15565b60015b6110e4577f74c0c46033bc849802ac56553afb987076b4c617bae4338fb0953bb9f47be7fa83828151811061109e5761109d611a48565b5b6020026020010151600001518483815181106110bd576110bc611a48565b5b6020026020010151602001516040516110d7929190611e0a565b60405180910390a16110e6565b505b80806110f190611ba8565b915050610f85565b5060019050919050565b611186846323b872dd60e01b85858560405160240161112493929190611b42565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061118c565b50505050565b60006111ee826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112539092919063ffffffff16565b905060008151111561124e578080602001905181019061120e9190611b15565b61124d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124490611edc565b60405180910390fd5b5b505050565b6060611262848460008561126b565b90509392505050565b6060824710156112b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a790611f6e565b60405180910390fd5b6112b98561137f565b6112f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ef90611fda565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516113219190611c6a565b60006040518083038185875af1925050503d806000811461135e576040519150601f19603f3d011682016040523d82523d6000602084013e611363565b606091505b50915091506113738282866113a2565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156113b257829050611402565b6000835111156113c55782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f99190611cc5565b60405180910390fd5b9392505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61146b82611422565b810181811067ffffffffffffffff8211171561148a57611489611433565b5b80604052505050565b600061149d611409565b90506114a98282611462565b919050565b600067ffffffffffffffff8211156114c9576114c8611433565b5b602082029050602081019050919050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061150f826114e4565b9050919050565b61151f81611504565b811461152a57600080fd5b50565b60008135905061153c81611516565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b61156781611542565b811461157257600080fd5b50565b6000813590506115848161155e565b92915050565b6000819050919050565b61159d8161158a565b81146115a857600080fd5b50565b6000813590506115ba81611594565b92915050565b6000608082840312156115d6576115d56114df565b5b6115e06080611493565b905060006115f08482850161152d565b60008301525060206116048482850161152d565b602083015250604061161884828501611575565b604083015250606061162c848285016115ab565b60608301525092915050565b600061164b611646846114ae565b611493565b9050808382526020820190506080840283018581111561166e5761166d6114da565b5b835b81811015611697578061168388826115c0565b845260208401935050608081019050611670565b5050509392505050565b600082601f8301126116b6576116b561141d565b5b81356116c6848260208601611638565b91505092915050565b6000602082840312156116e5576116e4611413565b5b600082013567ffffffffffffffff81111561170357611702611418565b5b61170f848285016116a1565b91505092915050565b60008115159050919050565b61172d81611718565b82525050565b60006020820190506117486000830184611724565b92915050565b6000806000806080858703121561176857611767611413565b5b60006117768782880161152d565b94505060206117878782880161152d565b9350506040611798878288016115ab565b92505060606117a987828801611575565b91505092959194509250565b6000602082840312156117cb576117ca611413565b5b60006117d98482850161152d565b91505092915050565b6000806000606084860312156117fb576117fa611413565b5b60006118098682870161152d565b935050602061181a8682870161152d565b925050604061182b86828701611575565b9150509250925092565b600067ffffffffffffffff8211156118505761184f611433565b5b602082029050602081019050919050565b600060608284031215611877576118766114df565b5b6118816060611493565b905060006118918482850161152d565b60008301525060206118a58482850161152d565b60208301525060406118b984828501611575565b60408301525092915050565b60006118d86118d384611835565b611493565b905080838252602082019050606084028301858111156118fb576118fa6114da565b5b835b8181101561192457806119108882611861565b8452602084019350506060810190506118fd565b5050509392505050565b600082601f8301126119435761194261141d565b5b81356119538482602086016118c5565b91505092915050565b60006020828403121561197257611971611413565b5b600082013567ffffffffffffffff8111156119905761198f611418565b5b61199c8482850161192e565b91505092915050565b600082825260208201905092915050565b7f43616c6c6572206d75737420626520616e20617070726f7665642063616c6c6560008201527f722e000000000000000000000000000000000000000000000000000000000000602082015250565b6000611a126022836119a5565b9150611a1d826119b6565b604082019050919050565b60006020820190508181036000830152611a4181611a05565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b611a8081611504565b82525050565b611a8f8161158a565b82525050565b611a9e81611542565b82525050565b6000608082019050611ab96000830187611a77565b611ac66020830186611a77565b611ad36040830185611a86565b611ae06060830184611a95565b95945050505050565b611af281611718565b8114611afd57600080fd5b50565b600081519050611b0f81611ae9565b92915050565b600060208284031215611b2b57611b2a611413565b5b6000611b3984828501611b00565b91505092915050565b6000606082019050611b576000830186611a77565b611b646020830185611a77565b611b716040830184611a86565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611bb38261158a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611be557611be4611b79565b5b600182019050919050565b600081519050919050565b600081905092915050565b60005b83811015611c24578082015181840152602081019050611c09565b83811115611c33576000848401525b50505050565b6000611c4482611bf0565b611c4e8185611bfb565b9350611c5e818560208601611c06565b80840191505092915050565b6000611c768284611c39565b915081905092915050565b600081519050919050565b6000611c9782611c81565b611ca181856119a5565b9350611cb1818560208601611c06565b611cba81611422565b840191505092915050565b60006020820190508181036000830152611cdf8184611c8c565b905092915050565b7f43616e6e6f742061646420616e79206164646974696f6e616c207472616e736660008201527f6572454f41732e00000000000000000000000000000000000000000000000000602082015250565b6000611d436027836119a5565b9150611d4e82611ce7565b604082019050919050565b60006020820190508181036000830152611d7281611d36565b9050919050565b6000602082019050611d8e6000830184611a77565b92915050565b600081519050611da381611594565b92915050565b600060208284031215611dbf57611dbe611413565b5b6000611dcd84828501611d94565b91505092915050565b6000611de18261158a565b9150611dec8361158a565b925082821015611dff57611dfe611b79565b5b828203905092915050565b6000604082019050611e1f6000830185611a77565b611e2c6020830184611a77565b9392505050565b6000606082019050611e486000830186611a77565b611e556020830185611a77565b611e626040830184611a95565b949350505050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000611ec6602a836119a5565b9150611ed182611e6a565b604082019050919050565b60006020820190508181036000830152611ef581611eb9565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000611f586026836119a5565b9150611f6382611efc565b604082019050919050565b60006020820190508181036000830152611f8781611f4b565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000611fc4601d836119a5565b9150611fcf82611f8e565b602082019050919050565b60006020820190508181036000830152611ff381611fb7565b905091905056fea264697066735822122028a5b7d7f203fdf26da28c5dbb9499441cefabe80ef5298e54f0701cf75aff1f64736f6c634300080d00330000000000000000000000009cde019f455b9a3c33d95912edceabbe0cad3444000000000000000000000000482c1f60c20244458846e5ca19bee60b811221c4
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80635016ff451161005b5780635016ff45146100ec578063cfeb243c14610108578063da335dda14610124578063dde5150f146101545761007d565b80630457be17146100825780630fe0522b146100b257806335332bfe146100bc575b600080fd5b61009c600480360381019061009791906116cf565b610184565b6040516100a99190611733565b60405180910390f35b6100ba6103da565b005b6100d660048036038101906100d1919061174e565b610484565b6040516100e39190611733565b60405180910390f35b610106600480360381019061010191906117b5565b610844565b005b610122600480360381019061011d91906117b5565b61092d565b005b61013e600480360381019061013991906117e2565b610a62565b60405161014b9190611733565b60405180910390f35b61016e6004803603810190610169919061195c565b610eed565b60405161017b9190611733565b60405180910390f35b600060011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514610219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161021090611a28565b60405180910390fd5b60005b82518110156103d0573073ffffffffffffffffffffffffffffffffffffffff166335332bfe62061a8085848151811061025857610257611a48565b5b60200260200101516000015186858151811061027757610276611a48565b5b60200260200101516020015187868151811061029657610295611a48565b5b6020026020010151606001518887815181106102b5576102b4611a48565b5b6020026020010151604001516040518663ffffffff1660e01b81526004016102e09493929190611aa4565b60206040518083038160008887f19350505050801561031d57506040513d601f19601f8201168201806040525081019061031a9190611b15565b60015b6103bb577f956d62b2c81b8b6384d5e4efa8b9058d517b234e29c20ea8064168ea5a57d3c783828151811061035557610354611a48565b5b60200260200101516000015184838151811061037457610373611a48565b5b60200260200101516020015185848151811061039357610392611a48565b5b6020026020010151606001516040516103ae93929190611b42565b60405180910390a16103bd565b505b80806103c890611ba8565b91505061021c565b5060019050919050565b7f000000000000000000000000482c1f60c20244458846e5ca19bee60b811221c473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610468576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045f90611a28565b60405180910390fd5b60008060006101000a81548160ff021916908315150217905550565b600060011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515148061051057503073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61054f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161054690611a28565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361058757600080fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff166323b872dd897f0000000000000000000000009cde019f455b9a3c33d95912edceabbe0cad3444896040516024016105f293929190611b42565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516106419190611c6a565b6000604051808303816000865af19150503d806000811461067e576040519150601f19603f3d011682016040523d82523d6000602084013e610683565b606091505b50915091508181906106cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c29190611cc5565b60405180910390fd5b506000807f0000000000000000000000009cde019f455b9a3c33d95912edceabbe0cad344473ffffffffffffffffffffffffffffffffffffffff168989898960405160240161071d9493929190611aa4565b60405160208183030381529060405263f574e2b660e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161076f9190611c6a565b6000604051808303816000865af19150503d80600081146107ac576040519150601f19603f3d011682016040523d82523d6000602084013e6107b1565b606091505b50915091508181906107f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f09190611cc5565b60405180910390fd5b507f3bec20ff024c042477bd629a21e97e55b8a5502c04b3773e699009e69fcb532089898960405161082d93929190611b42565b60405180910390a183945050505050949350505050565b7f000000000000000000000000482c1f60c20244458846e5ca19bee60b811221c473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c990611a28565b60405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008054906101000a900460ff1661097a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097190611d59565b60405180910390fd5b7f000000000000000000000000482c1f60c20244458846e5ca19bee60b811221c473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a08576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ff90611a28565b60405180910390fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600060011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151480610aee57503073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610b2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b2490611a28565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b6557600080fd5b60008373ffffffffffffffffffffffffffffffffffffffff166370a082317f0000000000000000000000009cde019f455b9a3c33d95912edceabbe0cad34446040518263ffffffff1660e01b8152600401610bc09190611d79565b602060405180830381865afa158015610bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c019190611da9565b905060008473ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b8152600401610c3e9190611d79565b602060405180830381865afa158015610c5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7f9190611da9565b9050610cce867f0000000000000000000000009cde019f455b9a3c33d95912edceabbe0cad3444838873ffffffffffffffffffffffffffffffffffffffff16611103909392919063ffffffff16565b6000828673ffffffffffffffffffffffffffffffffffffffff166370a082317f0000000000000000000000009cde019f455b9a3c33d95912edceabbe0cad34446040518263ffffffff1660e01b8152600401610d2a9190611d79565b602060405180830381865afa158015610d47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6b9190611da9565b610d759190611dd6565b90506000807f0000000000000000000000009cde019f455b9a3c33d95912edceabbe0cad344473ffffffffffffffffffffffffffffffffffffffff168989858a604051602401610dc89493929190611aa4565b604051602081830303815290604052633d602dbe60e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610e1a9190611c6a565b6000604051808303816000865af19150503d8060008114610e57576040519150601f19603f3d011682016040523d82523d6000602084013e610e5c565b606091505b5091509150818190610ea4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9b9190611cc5565b60405180910390fd5b507ff93b052819f594a764a6b528a0d3d2296bf30fddd860b97bb1c7e571e226df2e8989604051610ed6929190611e0a565b60405180910390a181955050505050509392505050565b600060011515600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514610f82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7990611a28565b60405180910390fd5b60005b82518110156110f9573073ffffffffffffffffffffffffffffffffffffffff1663da335dda62061a80858481518110610fc157610fc0611a48565b5b602002602001015160000151868581518110610fe057610fdf611a48565b5b602002602001015160200151878681518110610fff57610ffe611a48565b5b6020026020010151604001516040518563ffffffff1660e01b815260040161102993929190611e33565b60206040518083038160008887f19350505050801561106657506040513d601f19601f820116820180604052508101906110639190611b15565b60015b6110e4577f74c0c46033bc849802ac56553afb987076b4c617bae4338fb0953bb9f47be7fa83828151811061109e5761109d611a48565b5b6020026020010151600001518483815181106110bd576110bc611a48565b5b6020026020010151602001516040516110d7929190611e0a565b60405180910390a16110e6565b505b80806110f190611ba8565b915050610f85565b5060019050919050565b611186846323b872dd60e01b85858560405160240161112493929190611b42565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061118c565b50505050565b60006111ee826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112539092919063ffffffff16565b905060008151111561124e578080602001905181019061120e9190611b15565b61124d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124490611edc565b60405180910390fd5b5b505050565b6060611262848460008561126b565b90509392505050565b6060824710156112b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a790611f6e565b60405180910390fd5b6112b98561137f565b6112f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ef90611fda565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516113219190611c6a565b60006040518083038185875af1925050503d806000811461135e576040519150601f19603f3d011682016040523d82523d6000602084013e611363565b606091505b50915091506113738282866113a2565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156113b257829050611402565b6000835111156113c55782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f99190611cc5565b60405180910390fd5b9392505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61146b82611422565b810181811067ffffffffffffffff8211171561148a57611489611433565b5b80604052505050565b600061149d611409565b90506114a98282611462565b919050565b600067ffffffffffffffff8211156114c9576114c8611433565b5b602082029050602081019050919050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061150f826114e4565b9050919050565b61151f81611504565b811461152a57600080fd5b50565b60008135905061153c81611516565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b61156781611542565b811461157257600080fd5b50565b6000813590506115848161155e565b92915050565b6000819050919050565b61159d8161158a565b81146115a857600080fd5b50565b6000813590506115ba81611594565b92915050565b6000608082840312156115d6576115d56114df565b5b6115e06080611493565b905060006115f08482850161152d565b60008301525060206116048482850161152d565b602083015250604061161884828501611575565b604083015250606061162c848285016115ab565b60608301525092915050565b600061164b611646846114ae565b611493565b9050808382526020820190506080840283018581111561166e5761166d6114da565b5b835b81811015611697578061168388826115c0565b845260208401935050608081019050611670565b5050509392505050565b600082601f8301126116b6576116b561141d565b5b81356116c6848260208601611638565b91505092915050565b6000602082840312156116e5576116e4611413565b5b600082013567ffffffffffffffff81111561170357611702611418565b5b61170f848285016116a1565b91505092915050565b60008115159050919050565b61172d81611718565b82525050565b60006020820190506117486000830184611724565b92915050565b6000806000806080858703121561176857611767611413565b5b60006117768782880161152d565b94505060206117878782880161152d565b9350506040611798878288016115ab565b92505060606117a987828801611575565b91505092959194509250565b6000602082840312156117cb576117ca611413565b5b60006117d98482850161152d565b91505092915050565b6000806000606084860312156117fb576117fa611413565b5b60006118098682870161152d565b935050602061181a8682870161152d565b925050604061182b86828701611575565b9150509250925092565b600067ffffffffffffffff8211156118505761184f611433565b5b602082029050602081019050919050565b600060608284031215611877576118766114df565b5b6118816060611493565b905060006118918482850161152d565b60008301525060206118a58482850161152d565b60208301525060406118b984828501611575565b60408301525092915050565b60006118d86118d384611835565b611493565b905080838252602082019050606084028301858111156118fb576118fa6114da565b5b835b8181101561192457806119108882611861565b8452602084019350506060810190506118fd565b5050509392505050565b600082601f8301126119435761194261141d565b5b81356119538482602086016118c5565b91505092915050565b60006020828403121561197257611971611413565b5b600082013567ffffffffffffffff8111156119905761198f611418565b5b61199c8482850161192e565b91505092915050565b600082825260208201905092915050565b7f43616c6c6572206d75737420626520616e20617070726f7665642063616c6c6560008201527f722e000000000000000000000000000000000000000000000000000000000000602082015250565b6000611a126022836119a5565b9150611a1d826119b6565b604082019050919050565b60006020820190508181036000830152611a4181611a05565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b611a8081611504565b82525050565b611a8f8161158a565b82525050565b611a9e81611542565b82525050565b6000608082019050611ab96000830187611a77565b611ac66020830186611a77565b611ad36040830185611a86565b611ae06060830184611a95565b95945050505050565b611af281611718565b8114611afd57600080fd5b50565b600081519050611b0f81611ae9565b92915050565b600060208284031215611b2b57611b2a611413565b5b6000611b3984828501611b00565b91505092915050565b6000606082019050611b576000830186611a77565b611b646020830185611a77565b611b716040830184611a86565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611bb38261158a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611be557611be4611b79565b5b600182019050919050565b600081519050919050565b600081905092915050565b60005b83811015611c24578082015181840152602081019050611c09565b83811115611c33576000848401525b50505050565b6000611c4482611bf0565b611c4e8185611bfb565b9350611c5e818560208601611c06565b80840191505092915050565b6000611c768284611c39565b915081905092915050565b600081519050919050565b6000611c9782611c81565b611ca181856119a5565b9350611cb1818560208601611c06565b611cba81611422565b840191505092915050565b60006020820190508181036000830152611cdf8184611c8c565b905092915050565b7f43616e6e6f742061646420616e79206164646974696f6e616c207472616e736660008201527f6572454f41732e00000000000000000000000000000000000000000000000000602082015250565b6000611d436027836119a5565b9150611d4e82611ce7565b604082019050919050565b60006020820190508181036000830152611d7281611d36565b9050919050565b6000602082019050611d8e6000830184611a77565b92915050565b600081519050611da381611594565b92915050565b600060208284031215611dbf57611dbe611413565b5b6000611dcd84828501611d94565b91505092915050565b6000611de18261158a565b9150611dec8361158a565b925082821015611dff57611dfe611b79565b5b828203905092915050565b6000604082019050611e1f6000830185611a77565b611e2c6020830184611a77565b9392505050565b6000606082019050611e486000830186611a77565b611e556020830185611a77565b611e626040830184611a95565b949350505050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000611ec6602a836119a5565b9150611ed182611e6a565b604082019050919050565b60006020820190508181036000830152611ef581611eb9565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000611f586026836119a5565b9150611f6382611efc565b604082019050919050565b60006020820190508181036000830152611f8781611f4b565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000611fc4601d836119a5565b9150611fcf82611f8e565b602082019050919050565b60006020820190508181036000830152611ff381611fb7565b905091905056fea264697066735822122028a5b7d7f203fdf26da28c5dbb9499441cefabe80ef5298e54f0701cf75aff1f64736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000009cde019f455b9a3c33d95912edceabbe0cad3444000000000000000000000000482c1f60c20244458846e5ca19bee60b811221c4
-----Decoded View---------------
Arg [0] : _vaultAddress (address): 0x9cdE019F455b9a3C33d95912eDcEaBBe0cad3444
Arg [1] : _transferEOASetter (address): 0x482C1f60C20244458846E5Ca19Bee60b811221C4
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000009cde019f455b9a3c33d95912edceabbe0cad3444
Arg [1] : 000000000000000000000000482c1f60c20244458846e5ca19bee60b811221c4
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.