Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 147 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Execute Multiple... | 24240923 | 49 days ago | IN | 0 ETH | 0.00017072 | ||||
| Execute Multiple... | 24175615 | 58 days ago | IN | 0 ETH | 0.0001775 | ||||
| Execute Multiple... | 24167670 | 60 days ago | IN | 0 ETH | 0.00017581 | ||||
| Execute Multiple... | 24167657 | 60 days ago | IN | 0 ETH | 0.00024672 | ||||
| Execute Multiple... | 24147025 | 62 days ago | IN | 0 ETH | 0.00017437 | ||||
| Execute Multiple... | 24147017 | 62 days ago | IN | 0 ETH | 0.00053093 | ||||
| Execute Multiple... | 24139678 | 63 days ago | IN | 0 ETH | 0.00024087 | ||||
| Execute Multiple... | 24135303 | 64 days ago | IN | 0 ETH | 0.00013601 | ||||
| Execute Multiple... | 24134099 | 64 days ago | IN | 0 ETH | 0.00028365 | ||||
| Execute Multiple... | 24132459 | 64 days ago | IN | 0 ETH | 0.00017323 | ||||
| Execute Multiple... | 24132189 | 64 days ago | IN | 0 ETH | 0.00013902 | ||||
| Execute Multiple... | 24131253 | 65 days ago | IN | 0 ETH | 0.0002062 | ||||
| Execute Multiple... | 24131240 | 65 days ago | IN | 0 ETH | 0.00045242 | ||||
| Execute Multiple... | 24126406 | 65 days ago | IN | 0 ETH | 0.00017554 | ||||
| Execute Multiple... | 24126309 | 65 days ago | IN | 0 ETH | 0.00018086 | ||||
| Execute Multiple... | 24125602 | 65 days ago | IN | 0 ETH | 0.00017388 | ||||
| Execute Multiple... | 24125496 | 65 days ago | IN | 0 ETH | 0.00014191 | ||||
| Execute Multiple... | 24125060 | 65 days ago | IN | 0 ETH | 0.00057834 | ||||
| Execute Multiple... | 24120540 | 66 days ago | IN | 0 ETH | 0.00038653 | ||||
| Execute Multiple... | 24120502 | 66 days ago | IN | 0 ETH | 0.00189127 | ||||
| Execute Multiple... | 24089403 | 70 days ago | IN | 0 ETH | 0.00017069 | ||||
| Execute Multiple... | 24082144 | 71 days ago | IN | 0 ETH | 0.0003458 | ||||
| Execute Multiple... | 24077093 | 72 days ago | IN | 0 ETH | 0.00017442 | ||||
| Execute Multiple... | 24076644 | 72 days ago | IN | 0 ETH | 0.00017297 | ||||
| Execute Multiple... | 24076477 | 72 days ago | IN | 0 ETH | 0.00039696 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
MultiTokenTransfer
Compiler Version
v0.8.27+commit.40a35a09
Optimization Enabled:
No with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./parts/SanderBusiness.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/// @title MultiTokenTransfer
/// @notice A contract for validating and executing multiple ERC20 token transfers
contract MultiTokenTransfer is SanderBusiness, Ownable {
constructor() Ownable(msg.sender) {}
/// @notice Validates multiple token transfer requests by checking contract presence and allowances.
/// @param tokenAddresses The address of the ERC20 token contract.
/// @param recipients An array of addresses to which the tokens are to be sent.
/// @param amounts An array of token amounts to be transferred to the corresponding recipients.
/// @return results array of Status structures indicating the possibility of each transfer.
/// @dev The lengths of the `recipients` and `amounts` arrays must be equal.
function validateMultipleSend(address[] memory tokenAddresses, address[] memory recipients, uint256[] memory amounts) external view returns (Status[] memory results) {
require(recipients.length == amounts.length, "Incorrect parameters");
return _validateMultipleSend(tokenAddresses, recipients, amounts);
}
/// @notice Executes multiple token transfers after validating them.
/// If a transfer fails, it will be skipped and the process will continue with the next one.
/// @param tokenAddresses The address of the ERC20 token contract.
/// @param recipients An array of addresses to which the tokens are to be sent.
/// @param amounts An array of token amounts to be transferred to the corresponding recipients.
/// @return results array of Status structures indicating the result of each transfer attempt.
function executeMultipleSend(address[] memory tokenAddresses, address[] memory recipients, uint256[] memory amounts) public onlyOwner returns (Status[] memory results) {
require(recipients.length == amounts.length, "Incorrect parameters");
return _executeMultipleSend(tokenAddresses, recipients, amounts);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./SanderLovlevel.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/// @title MultiCallSender
/// @notice A contract for validating and executing multiple ERC20 token transfers
contract SanderBusiness is SanderLovlevel {
/// @notice A structure to hold the status of a transfer to a recipient.
struct Status {
address recipient; /// @dev The address of the token transfer recipient.
bool isCompleted; /// @dev A boolean indicating if the transfer is possible.
string reason; /// @dev The reason why a transfer is not possible, if applicable.
}
/// @notice A structure to the token allowance
struct Token {
address tokenAddress; // The token contract address.
uint256 allowance; // The amount of the token that the contract is allowed to use.
}
/**
* @notice Initializes the allowance for each provided token address.
* @param tokenAddresses An array of addresses of ERC20 token contracts.
* @param owner The address of the token owner who granted the allowances.
* @return results array of Token structs with initialized allowance information for each provided token.
*/
function _initTokenAllowance(
address[] memory tokenAddresses,
address owner
) internal view returns (Token[] memory results) {
// Initialize temporary storage for unique token addresses.
address[] memory uniqueAddresses = new address[](tokenAddresses.length);
uint256 uniqueCount = 0;
// Identify unique token addresses.
for (uint256 i = 0; i < tokenAddresses.length; i++) {
bool isUnique = true;
for (uint256 j = 0; j < uniqueCount; j++) {
if (tokenAddresses[i] == uniqueAddresses[j]) {
isUnique = false;
break;
}
}
if (isUnique) {
uniqueAddresses[uniqueCount] = tokenAddresses[i];
uniqueCount++;
}
}
// Allocate and initialize the results array.
results = new Token[](uniqueCount);
for (uint256 i = 0; i < uniqueCount; i++) {
results[i] = Token({
tokenAddress: uniqueAddresses[i],
allowance: IERC20(uniqueAddresses[i]).allowance(
owner,
address(this)
)
});
}
}
/**
* @notice Retrieves the allowance and index for a specific token address within a list of Tokens.
* @param tokenAddress The address of the ERC20 token contract.
* @param tokens An array of Tokens to search within.
* @return allowance The amount of tokens the contract is allowed to spend.
* @return index The index of the token within the array.
*/
function _getTokenAllowance(
address tokenAddress,
Token[] memory tokens
) internal pure returns (uint256 allowance, uint256 index) {
for (index = 0; index < tokens.length; index++) {
if (tokens[index].tokenAddress == tokenAddress) {
allowance = tokens[index].allowance;
return (allowance, index);
}
}
revert("Token not found");
}
/// @notice Validates multiple token transfer requests by checking contract presence and allowances.
/// @param tokenAddresses The address of the ERC20 token contract.
/// @param recipients An array of addresses to which the tokens are to be sent.
/// @param amounts An array of token amounts to be transferred to the corresponding recipients.
/// @return results array of Status structures indicating the possibility of each transfer.
/// @dev The lengths of the `recipients` and `amounts` arrays must be equal.
function _validateMultipleSend(
address[] memory tokenAddresses,
address[] memory recipients,
uint256[] memory amounts
) internal view returns (Status[] memory results) {
require(
tokenAddresses.length == recipients.length &&
recipients.length == amounts.length,
"Incorrect parameters"
);
Token[] memory tokens = _initTokenAllowance(tokenAddresses, address(msg.sender));
results = new Status[](recipients.length);
for (uint256 i = 0; i < recipients.length; i++) {
address tokenAddress = tokenAddresses[i];
(uint256 token_allowance, uint256 token_index) = _getTokenAllowance(
tokenAddress,
tokens
);
if (isContract(recipients[i])) {
results[i] = Status({
recipient: recipients[i],
isCompleted: false,
reason: "contract"
});
continue;
}
if (token_allowance < amounts[i]) {
results[i] = Status({
recipient: recipients[i],
isCompleted: false,
reason: "insufficient"
});
continue;
}
tokens[token_index].allowance -= amounts[i];
results[i] = Status({
recipient: recipients[i],
isCompleted: true,
reason: "success"
});
}
return results;
}
/// @notice Executes multiple token transfers after validating them.
/// If a transfer fails, it will be skipped and the process will continue with the next one.
/// @param tokenAddresses An array of addresses to which the ERC20 token contracts.
/// @param recipients An array of addresses to which the tokens are to be sent.
/// @param amounts An array of token amounts to be transferred to the corresponding recipients.
/// @return results array of Status structures indicating the result of each transfer attempt.
function _executeMultipleSend(
address [] memory tokenAddresses,
address[] memory recipients,
uint256[] memory amounts
) internal returns (Status[] memory results) {
results = new Status[](recipients.length); // Initialize the array to hold the results.
for (uint256 i = 0; i < recipients.length; i++) {
// Attempt the transfer, catching any errors.
try
this.attemptTransfer(
IERC20(tokenAddresses[i]),
address(msg.sender),
recipients[i],
amounts[i]
)
{
// If the transfer succeeds, update the reason to 'transferred'.
results[i] = Status({
recipient: recipients[i],
isCompleted: true,
reason: "transferred"
});
} catch {
// If there's an error, update the result entry to reflect that the transfer failed.
results[i] = Status({
recipient: recipients[i],
isCompleted: false,
reason: "failed"
});
}
}
return results;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
contract SanderLovlevel {
using SafeERC20 for IERC20;
/// @dev Attempts to transfer tokens from one address to another.
/// @notice This function should only be called by this contract.
/// It uses the `safeTransferFrom` function from the OpenZeppelin SafeERC20 library
/// to move tokens safely, which includes handling tokens that do not throw on failure.
/// @param token The IERC20 token interface being transferred.
/// @param origin The address of the token holder (sender).
/// @param beneficiary The address of the token receiver.
/// @param amount The amount of tokens to be transferred.
///
/// Requirements:
/// - This function can only be called by the current contract instance.
/// - The origin address must have already granted the contract an allowance for at least `amount`.
function attemptTransfer(IERC20 token, address origin, address beneficiary, uint256 amount) external {
require(msg.sender == address(this), "Only the contract can invoke this function.");
token.safeTransferFrom(origin, beneficiary, amount);
}
/// @notice Check if the address is a contract.
/// @param addr The address to be checked.
/// @return True if the address is a contract, false otherwise.
function isContract(address addr) internal view returns (bool) {
uint256 codeSize;
assembly {
codeSize := extcodesize(addr)
}
return codeSize > 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
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 value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` 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 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 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 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
if (!_safeTransfer(token, to, value, true)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
if (!_safeTransferFrom(token, from, to, value, true)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _safeTransfer(token, to, value, false);
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _safeTransferFrom(token, from, to, value, false);
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
if (!_safeApprove(token, spender, value, false)) {
if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));
if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Oppositely, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity `token.transfer(to, value)` call, 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 to The recipient of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {
bytes4 selector = IERC20.transfer.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(to, shr(96, not(0))))
mstore(0x24, value)
success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0x00, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
}
}
/**
* @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, 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 from The sender of the tokens
* @param to The recipient of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value,
bool bubble
) private returns (bool success) {
bytes4 selector = IERC20.transferFrom.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(from, shr(96, not(0))))
mstore(0x24, and(to, shr(96, not(0))))
mstore(0x44, value)
success := call(gas(), token, 0, 0x00, 0x64, 0x00, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0x00, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
mstore(0x60, 0)
}
}
/**
* @dev Imitates a Solidity `token.approve(spender, value)` call, 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 spender The spender of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {
bytes4 selector = IERC20.approve.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(spender, shr(96, not(0))))
mstore(0x24, value)
success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0x00, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* 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[ERC 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);
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": false,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"origin","type":"address"},{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"attemptTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokenAddresses","type":"address[]"},{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"executeMultipleSend","outputs":[{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"isCompleted","type":"bool"},{"internalType":"string","name":"reason","type":"string"}],"internalType":"struct SanderBusiness.Status[]","name":"results","type":"tuple[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokenAddresses","type":"address[]"},{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"validateMultipleSend","outputs":[{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"isCompleted","type":"bool"},{"internalType":"string","name":"reason","type":"string"}],"internalType":"struct SanderBusiness.Status[]","name":"results","type":"tuple[]"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b5033600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100845760006040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161007b919061019e565b60405180910390fd5b6100938161009960201b60201c565b506101b9565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101888261015d565b9050919050565b6101988161017d565b82525050565b60006020820190506101b3600083018461018f565b92915050565b6119a7806101c86000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80631693074b1461006757806343f4b66a14610083578063715018a6146100b3578063773b4140146100bd5780638da5cb5b146100ed578063f2fde38b1461010b575b600080fd5b610081600480360381019061007c91906110a0565b610127565b005b61009d60048036038101906100989190611323565b6101c8565b6040516100aa9190611585565b60405180910390f35b6100bb610222565b005b6100d760048036038101906100d29190611323565b610236565b6040516100e49190611585565b60405180910390f35b6100f5610298565b60405161010291906115b6565b60405180910390f35b610125600480360381019061012091906115d1565b6102c1565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610195576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161018c90611681565b60405180910390fd5b6101c28383838773ffffffffffffffffffffffffffffffffffffffff16610347909392919063ffffffff16565b50505050565b6060815183511461020e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610205906116ed565b60405180910390fd5b61021984848461039c565b90509392505050565b61022a610734565b61023460006107bb565b565b6060610240610734565b8151835114610284576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027b906116ed565b60405180910390fd5b61028f84848461087f565b90509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6102c9610734565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361033b5760006040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161033291906115b6565b60405180910390fd5b610344816107bb565b50565b610355848484846001610afd565b61039657836040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161038d91906115b6565b60405180910390fd5b50505050565b6060825184511480156103b0575081518351145b6103ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e6906116ed565b60405180910390fd5b60006103fb8533610b78565b9050835167ffffffffffffffff8111156104185761041761111d565b5b60405190808252806020026020018201604052801561045157816020015b61043e610f51565b8152602001906001900390816104365790505b50915060005b845181101561072b5760008682815181106104755761047461170d565b5b6020026020010151905060008061048c8386610e5f565b915091506104b38885815181106104a6576104a561170d565b5b6020026020010151610f36565b156105615760405180606001604052808986815181106104d6576104d561170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020016000151581526020016040518060400160405280600881526020017f636f6e747261637400000000000000000000000000000000000000000000000081525081525086858151811061054e5761054d61170d565b5b602002602001018190525050505061071e565b8684815181106105745761057361170d565b5b602002602001015182101561062c5760405180606001604052808986815181106105a1576105a061170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020016000151581526020016040518060400160405280600c81526020017f696e73756666696369656e7400000000000000000000000000000000000000008152508152508685815181106106195761061861170d565b5b602002602001018190525050505061071e565b86848151811061063f5761063e61170d565b5b602002602001015185828151811061065a5761065961170d565b5b6020026020010151602001818151610672919061176b565b9150818152505060405180606001604052808986815181106106975761069661170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020016001151581526020016040518060400160405280600781526020017f737563636573730000000000000000000000000000000000000000000000000081525081525086858151811061070f5761070e61170d565b5b60200260200101819052505050505b8080600101915050610457565b50509392505050565b61073c610f49565b73ffffffffffffffffffffffffffffffffffffffff1661075a610298565b73ffffffffffffffffffffffffffffffffffffffff16146107b95761077d610f49565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016107b091906115b6565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6060825167ffffffffffffffff81111561089c5761089b61111d565b5b6040519080825280602002602001820160405280156108d557816020015b6108c2610f51565b8152602001906001900390816108ba5790505b50905060005b8351811015610af5573073ffffffffffffffffffffffffffffffffffffffff16631693074b8683815181106109135761091261170d565b5b60200260200101513387858151811061092f5761092e61170d565b5b602002602001015187868151811061094a5761094961170d565b5b60200260200101516040518563ffffffff1660e01b8152600401610971949392919061180d565b600060405180830381600087803b15801561098b57600080fd5b505af192505050801561099c575060015b610a465760405180606001604052808583815181106109be576109bd61170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020016000151581526020016040518060400160405280600681526020017f6661696c65640000000000000000000000000000000000000000000000000000815250815250828281518110610a3657610a3561170d565b5b6020026020010181905250610ae8565b6040518060600160405280858381518110610a6457610a6361170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020016001151581526020016040518060400160405280600b81526020017f7472616e73666572726564000000000000000000000000000000000000000000815250815250828281518110610adc57610adb61170d565b5b60200260200101819052505b80806001019150506108db565b509392505050565b6000806323b872dd60e01b90506040518160005260001960601c871660045260001960601c8616602452846044526020600060646000808c5af192506001600051148316610b64578383151615610b57573d6000823e3d81fd5b6000883b113d1516831692505b806040526000606052505095945050505050565b60606000835167ffffffffffffffff811115610b9757610b9661111d565b5b604051908082528060200260200182016040528015610bc55781602001602082028036833780820191505090505b5090506000805b8551811015610cef5760006001905060005b83811015610c6357848181518110610bf957610bf861170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16888481518110610c2a57610c2961170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610c565760009150610c63565b8080600101915050610bde565b508015610ce157868281518110610c7d57610c7c61170d565b5b6020026020010151848481518110610c9857610c9761170d565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508280610cdd90611852565b9350505b508080600101915050610bcc565b508067ffffffffffffffff811115610d0a57610d0961111d565b5b604051908082528060200260200182016040528015610d4357816020015b610d30610f8a565b815260200190600190039081610d285790505b50925060005b81811015610e56576040518060400160405280848381518110610d6f57610d6e61170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152602001848381518110610da557610da461170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e88306040518363ffffffff1660e01b8152600401610de792919061189a565b602060405180830381865afa158015610e04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2891906118d8565b815250848281518110610e3e57610e3d61170d565b5b60200260200101819052508080600101915050610d49565b50505092915050565b600080600090505b8251811015610ef4578373ffffffffffffffffffffffffffffffffffffffff16838281518110610e9a57610e9961170d565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610ee757828181518110610ed457610ed361170d565b5b6020026020010151602001519150610f2f565b8080600101915050610e67565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2690611951565b60405180910390fd5b9250929050565b600080823b905060008111915050919050565b600033905090565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001606081525090565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610ff982610fce565b9050919050565b600061100b82610fee565b9050919050565b61101b81611000565b811461102657600080fd5b50565b60008135905061103881611012565b92915050565b61104781610fee565b811461105257600080fd5b50565b6000813590506110648161103e565b92915050565b6000819050919050565b61107d8161106a565b811461108857600080fd5b50565b60008135905061109a81611074565b92915050565b600080600080608085870312156110ba576110b9610fc4565b5b60006110c887828801611029565b94505060206110d987828801611055565b93505060406110ea87828801611055565b92505060606110fb8782880161108b565b91505092959194509250565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6111558261110c565b810181811067ffffffffffffffff821117156111745761117361111d565b5b80604052505050565b6000611187610fba565b9050611193828261114c565b919050565b600067ffffffffffffffff8211156111b3576111b261111d565b5b602082029050602081019050919050565b600080fd5b60006111dc6111d784611198565b61117d565b905080838252602082019050602084028301858111156111ff576111fe6111c4565b5b835b8181101561122857806112148882611055565b845260208401935050602081019050611201565b5050509392505050565b600082601f83011261124757611246611107565b5b81356112578482602086016111c9565b91505092915050565b600067ffffffffffffffff82111561127b5761127a61111d565b5b602082029050602081019050919050565b600061129f61129a84611260565b61117d565b905080838252602082019050602084028301858111156112c2576112c16111c4565b5b835b818110156112eb57806112d7888261108b565b8452602084019350506020810190506112c4565b5050509392505050565b600082601f83011261130a57611309611107565b5b813561131a84826020860161128c565b91505092915050565b60008060006060848603121561133c5761133b610fc4565b5b600084013567ffffffffffffffff81111561135a57611359610fc9565b5b61136686828701611232565b935050602084013567ffffffffffffffff81111561138757611386610fc9565b5b61139386828701611232565b925050604084013567ffffffffffffffff8111156113b4576113b3610fc9565b5b6113c0868287016112f5565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6113ff81610fee565b82525050565b60008115159050919050565b61141a81611405565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561145a57808201518184015260208101905061143f565b60008484015250505050565b600061147182611420565b61147b818561142b565b935061148b81856020860161143c565b6114948161110c565b840191505092915050565b60006060830160008301516114b760008601826113f6565b5060208301516114ca6020860182611411565b50604083015184820360408601526114e28282611466565b9150508091505092915050565b60006114fb838361149f565b905092915050565b6000602082019050919050565b600061151b826113ca565b61152581856113d5565b935083602082028501611537856113e6565b8060005b85811015611573578484038952815161155485826114ef565b945061155f83611503565b925060208a0199505060018101905061153b565b50829750879550505050505092915050565b6000602082019050818103600083015261159f8184611510565b905092915050565b6115b081610fee565b82525050565b60006020820190506115cb60008301846115a7565b92915050565b6000602082840312156115e7576115e6610fc4565b5b60006115f584828501611055565b91505092915050565b600082825260208201905092915050565b7f4f6e6c792074686520636f6e74726163742063616e20696e766f6b652074686960008201527f732066756e6374696f6e2e000000000000000000000000000000000000000000602082015250565b600061166b602b836115fe565b91506116768261160f565b604082019050919050565b6000602082019050818103600083015261169a8161165e565b9050919050565b7f496e636f727265637420706172616d6574657273000000000000000000000000600082015250565b60006116d76014836115fe565b91506116e2826116a1565b602082019050919050565b60006020820190508181036000830152611706816116ca565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006117768261106a565b91506117818361106a565b92508282039050818111156117995761179861173c565b5b92915050565b6000819050919050565b60006117c46117bf6117ba84610fce565b61179f565b610fce565b9050919050565b60006117d6826117a9565b9050919050565b60006117e8826117cb565b9050919050565b6117f8816117dd565b82525050565b6118078161106a565b82525050565b600060808201905061182260008301876117ef565b61182f60208301866115a7565b61183c60408301856115a7565b61184960608301846117fe565b95945050505050565b600061185d8261106a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361188f5761188e61173c565b5b600182019050919050565b60006040820190506118af60008301856115a7565b6118bc60208301846115a7565b9392505050565b6000815190506118d281611074565b92915050565b6000602082840312156118ee576118ed610fc4565b5b60006118fc848285016118c3565b91505092915050565b7f546f6b656e206e6f7420666f756e640000000000000000000000000000000000600082015250565b600061193b600f836115fe565b915061194682611905565b602082019050919050565b6000602082019050818103600083015261196a8161192e565b905091905056fea2646970667358221220178c333b242eeb6aa90b0fd87b76f93afd308d8f8690266064c971dc3f801b3564736f6c634300081b0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100625760003560e01c80631693074b1461006757806343f4b66a14610083578063715018a6146100b3578063773b4140146100bd5780638da5cb5b146100ed578063f2fde38b1461010b575b600080fd5b610081600480360381019061007c91906110a0565b610127565b005b61009d60048036038101906100989190611323565b6101c8565b6040516100aa9190611585565b60405180910390f35b6100bb610222565b005b6100d760048036038101906100d29190611323565b610236565b6040516100e49190611585565b60405180910390f35b6100f5610298565b60405161010291906115b6565b60405180910390f35b610125600480360381019061012091906115d1565b6102c1565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610195576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161018c90611681565b60405180910390fd5b6101c28383838773ffffffffffffffffffffffffffffffffffffffff16610347909392919063ffffffff16565b50505050565b6060815183511461020e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610205906116ed565b60405180910390fd5b61021984848461039c565b90509392505050565b61022a610734565b61023460006107bb565b565b6060610240610734565b8151835114610284576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027b906116ed565b60405180910390fd5b61028f84848461087f565b90509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6102c9610734565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361033b5760006040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161033291906115b6565b60405180910390fd5b610344816107bb565b50565b610355848484846001610afd565b61039657836040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161038d91906115b6565b60405180910390fd5b50505050565b6060825184511480156103b0575081518351145b6103ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e6906116ed565b60405180910390fd5b60006103fb8533610b78565b9050835167ffffffffffffffff8111156104185761041761111d565b5b60405190808252806020026020018201604052801561045157816020015b61043e610f51565b8152602001906001900390816104365790505b50915060005b845181101561072b5760008682815181106104755761047461170d565b5b6020026020010151905060008061048c8386610e5f565b915091506104b38885815181106104a6576104a561170d565b5b6020026020010151610f36565b156105615760405180606001604052808986815181106104d6576104d561170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020016000151581526020016040518060400160405280600881526020017f636f6e747261637400000000000000000000000000000000000000000000000081525081525086858151811061054e5761054d61170d565b5b602002602001018190525050505061071e565b8684815181106105745761057361170d565b5b602002602001015182101561062c5760405180606001604052808986815181106105a1576105a061170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020016000151581526020016040518060400160405280600c81526020017f696e73756666696369656e7400000000000000000000000000000000000000008152508152508685815181106106195761061861170d565b5b602002602001018190525050505061071e565b86848151811061063f5761063e61170d565b5b602002602001015185828151811061065a5761065961170d565b5b6020026020010151602001818151610672919061176b565b9150818152505060405180606001604052808986815181106106975761069661170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020016001151581526020016040518060400160405280600781526020017f737563636573730000000000000000000000000000000000000000000000000081525081525086858151811061070f5761070e61170d565b5b60200260200101819052505050505b8080600101915050610457565b50509392505050565b61073c610f49565b73ffffffffffffffffffffffffffffffffffffffff1661075a610298565b73ffffffffffffffffffffffffffffffffffffffff16146107b95761077d610f49565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016107b091906115b6565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6060825167ffffffffffffffff81111561089c5761089b61111d565b5b6040519080825280602002602001820160405280156108d557816020015b6108c2610f51565b8152602001906001900390816108ba5790505b50905060005b8351811015610af5573073ffffffffffffffffffffffffffffffffffffffff16631693074b8683815181106109135761091261170d565b5b60200260200101513387858151811061092f5761092e61170d565b5b602002602001015187868151811061094a5761094961170d565b5b60200260200101516040518563ffffffff1660e01b8152600401610971949392919061180d565b600060405180830381600087803b15801561098b57600080fd5b505af192505050801561099c575060015b610a465760405180606001604052808583815181106109be576109bd61170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020016000151581526020016040518060400160405280600681526020017f6661696c65640000000000000000000000000000000000000000000000000000815250815250828281518110610a3657610a3561170d565b5b6020026020010181905250610ae8565b6040518060600160405280858381518110610a6457610a6361170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020016001151581526020016040518060400160405280600b81526020017f7472616e73666572726564000000000000000000000000000000000000000000815250815250828281518110610adc57610adb61170d565b5b60200260200101819052505b80806001019150506108db565b509392505050565b6000806323b872dd60e01b90506040518160005260001960601c871660045260001960601c8616602452846044526020600060646000808c5af192506001600051148316610b64578383151615610b57573d6000823e3d81fd5b6000883b113d1516831692505b806040526000606052505095945050505050565b60606000835167ffffffffffffffff811115610b9757610b9661111d565b5b604051908082528060200260200182016040528015610bc55781602001602082028036833780820191505090505b5090506000805b8551811015610cef5760006001905060005b83811015610c6357848181518110610bf957610bf861170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16888481518110610c2a57610c2961170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610c565760009150610c63565b8080600101915050610bde565b508015610ce157868281518110610c7d57610c7c61170d565b5b6020026020010151848481518110610c9857610c9761170d565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508280610cdd90611852565b9350505b508080600101915050610bcc565b508067ffffffffffffffff811115610d0a57610d0961111d565b5b604051908082528060200260200182016040528015610d4357816020015b610d30610f8a565b815260200190600190039081610d285790505b50925060005b81811015610e56576040518060400160405280848381518110610d6f57610d6e61170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152602001848381518110610da557610da461170d565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e88306040518363ffffffff1660e01b8152600401610de792919061189a565b602060405180830381865afa158015610e04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2891906118d8565b815250848281518110610e3e57610e3d61170d565b5b60200260200101819052508080600101915050610d49565b50505092915050565b600080600090505b8251811015610ef4578373ffffffffffffffffffffffffffffffffffffffff16838281518110610e9a57610e9961170d565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610ee757828181518110610ed457610ed361170d565b5b6020026020010151602001519150610f2f565b8080600101915050610e67565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2690611951565b60405180910390fd5b9250929050565b600080823b905060008111915050919050565b600033905090565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001606081525090565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610ff982610fce565b9050919050565b600061100b82610fee565b9050919050565b61101b81611000565b811461102657600080fd5b50565b60008135905061103881611012565b92915050565b61104781610fee565b811461105257600080fd5b50565b6000813590506110648161103e565b92915050565b6000819050919050565b61107d8161106a565b811461108857600080fd5b50565b60008135905061109a81611074565b92915050565b600080600080608085870312156110ba576110b9610fc4565b5b60006110c887828801611029565b94505060206110d987828801611055565b93505060406110ea87828801611055565b92505060606110fb8782880161108b565b91505092959194509250565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6111558261110c565b810181811067ffffffffffffffff821117156111745761117361111d565b5b80604052505050565b6000611187610fba565b9050611193828261114c565b919050565b600067ffffffffffffffff8211156111b3576111b261111d565b5b602082029050602081019050919050565b600080fd5b60006111dc6111d784611198565b61117d565b905080838252602082019050602084028301858111156111ff576111fe6111c4565b5b835b8181101561122857806112148882611055565b845260208401935050602081019050611201565b5050509392505050565b600082601f83011261124757611246611107565b5b81356112578482602086016111c9565b91505092915050565b600067ffffffffffffffff82111561127b5761127a61111d565b5b602082029050602081019050919050565b600061129f61129a84611260565b61117d565b905080838252602082019050602084028301858111156112c2576112c16111c4565b5b835b818110156112eb57806112d7888261108b565b8452602084019350506020810190506112c4565b5050509392505050565b600082601f83011261130a57611309611107565b5b813561131a84826020860161128c565b91505092915050565b60008060006060848603121561133c5761133b610fc4565b5b600084013567ffffffffffffffff81111561135a57611359610fc9565b5b61136686828701611232565b935050602084013567ffffffffffffffff81111561138757611386610fc9565b5b61139386828701611232565b925050604084013567ffffffffffffffff8111156113b4576113b3610fc9565b5b6113c0868287016112f5565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6113ff81610fee565b82525050565b60008115159050919050565b61141a81611405565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561145a57808201518184015260208101905061143f565b60008484015250505050565b600061147182611420565b61147b818561142b565b935061148b81856020860161143c565b6114948161110c565b840191505092915050565b60006060830160008301516114b760008601826113f6565b5060208301516114ca6020860182611411565b50604083015184820360408601526114e28282611466565b9150508091505092915050565b60006114fb838361149f565b905092915050565b6000602082019050919050565b600061151b826113ca565b61152581856113d5565b935083602082028501611537856113e6565b8060005b85811015611573578484038952815161155485826114ef565b945061155f83611503565b925060208a0199505060018101905061153b565b50829750879550505050505092915050565b6000602082019050818103600083015261159f8184611510565b905092915050565b6115b081610fee565b82525050565b60006020820190506115cb60008301846115a7565b92915050565b6000602082840312156115e7576115e6610fc4565b5b60006115f584828501611055565b91505092915050565b600082825260208201905092915050565b7f4f6e6c792074686520636f6e74726163742063616e20696e766f6b652074686960008201527f732066756e6374696f6e2e000000000000000000000000000000000000000000602082015250565b600061166b602b836115fe565b91506116768261160f565b604082019050919050565b6000602082019050818103600083015261169a8161165e565b9050919050565b7f496e636f727265637420706172616d6574657273000000000000000000000000600082015250565b60006116d76014836115fe565b91506116e2826116a1565b602082019050919050565b60006020820190508181036000830152611706816116ca565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006117768261106a565b91506117818361106a565b92508282039050818111156117995761179861173c565b5b92915050565b6000819050919050565b60006117c46117bf6117ba84610fce565b61179f565b610fce565b9050919050565b60006117d6826117a9565b9050919050565b60006117e8826117cb565b9050919050565b6117f8816117dd565b82525050565b6118078161106a565b82525050565b600060808201905061182260008301876117ef565b61182f60208301866115a7565b61183c60408301856115a7565b61184960608301846117fe565b95945050505050565b600061185d8261106a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361188f5761188e61173c565b5b600182019050919050565b60006040820190506118af60008301856115a7565b6118bc60208301846115a7565b9392505050565b6000815190506118d281611074565b92915050565b6000602082840312156118ee576118ed610fc4565b5b60006118fc848285016118c3565b91505092915050565b7f546f6b656e206e6f7420666f756e640000000000000000000000000000000000600082015250565b600061193b600f836115fe565b915061194682611905565b602082019050919050565b6000602082019050818103600083015261196a8161192e565b905091905056fea2646970667358221220178c333b242eeb6aa90b0fd87b76f93afd308d8f8690266064c971dc3f801b3564736f6c634300081b0033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.