Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 3,763 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Create Safe And ... | 23567034 | 21 mins ago | IN | 0 ETH | 0.0000188 | ||||
| Create Safe And ... | 23566802 | 1 hr ago | IN | 0 ETH | 0.00001173 | ||||
| Create Safe And ... | 23566499 | 2 hrs ago | IN | 0 ETH | 0.00001224 | ||||
| Create Safe And ... | 23566332 | 2 hrs ago | IN | 0 ETH | 0.00001236 | ||||
| Create Safe And ... | 23566221 | 3 hrs ago | IN | 0 ETH | 0.00001248 | ||||
| Create Safe And ... | 23565845 | 4 hrs ago | IN | 0 ETH | 0.00001548 | ||||
| Create Safe And ... | 23565488 | 5 hrs ago | IN | 0 ETH | 0.00001376 | ||||
| Create Safe And ... | 23565426 | 5 hrs ago | IN | 0 ETH | 0.00001351 | ||||
| Create Safe And ... | 23565337 | 6 hrs ago | IN | 0 ETH | 0.0000133 | ||||
| Create Safe And ... | 23565147 | 6 hrs ago | IN | 0 ETH | 0.00001351 | ||||
| Create Safe And ... | 23565142 | 6 hrs ago | IN | 0 ETH | 0.00001367 | ||||
| Create Safe And ... | 23565137 | 6 hrs ago | IN | 0 ETH | 0.00001349 | ||||
| Create Safe And ... | 23565024 | 7 hrs ago | IN | 0 ETH | 0.00001577 | ||||
| Create Safe And ... | 23564966 | 7 hrs ago | IN | 0 ETH | 0.00001611 | ||||
| Create Safe And ... | 23564963 | 7 hrs ago | IN | 0 ETH | 0.00001626 | ||||
| Create Safe And ... | 23564890 | 7 hrs ago | IN | 0 ETH | 0.00001731 | ||||
| Create Safe And ... | 23564871 | 7 hrs ago | IN | 0 ETH | 0.00001734 | ||||
| Create Safe And ... | 23564870 | 7 hrs ago | IN | 0 ETH | 0.00001653 | ||||
| Create Safe And ... | 23564836 | 7 hrs ago | IN | 0 ETH | 0.00001497 | ||||
| Create Safe And ... | 23564512 | 8 hrs ago | IN | 0 ETH | 0.00003262 | ||||
| Create Safe And ... | 23564265 | 9 hrs ago | IN | 0 ETH | 0.00003653 | ||||
| Create Safe And ... | 23564155 | 10 hrs ago | IN | 0 ETH | 0.0000485 | ||||
| Create Safe And ... | 23564084 | 10 hrs ago | IN | 0 ETH | 0.00004726 | ||||
| Create Safe And ... | 23564047 | 10 hrs ago | IN | 0 ETH | 0.00003354 | ||||
| Create Safe And ... | 23563952 | 10 hrs ago | IN | 0 ETH | 0.00003099 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
To
|
|||
|---|---|---|---|---|---|---|---|
| 0x3d602d80 | 23567034 | 21 mins ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23566802 | 1 hr ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23566499 | 2 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23566332 | 2 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23566221 | 3 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23565845 | 4 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23565488 | 5 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23565426 | 5 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23565337 | 6 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23565147 | 6 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23565142 | 6 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23565137 | 6 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23565024 | 7 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23564966 | 7 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23564963 | 7 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23564890 | 7 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23564871 | 7 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23564870 | 7 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23564836 | 7 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23564512 | 8 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23564265 | 9 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23564155 | 10 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23564084 | 10 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23564047 | 10 hrs ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23563952 | 10 hrs ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
SafeFactory
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
No with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.26;
import "@openzeppelin/contracts/proxy/Clones.sol";
import "contracts/Safe.sol";
contract SafeFactory {
// The address of the safe implementation
address public immutable safeImplementation;
address public constant OWNER = 0xe883Cd7ADfe55CD84798a8129468e106b32CDC7A;
address public constant CALLER = 0x078Bf499222bFcbbFB50EbB191270A9baC93ce44;
constructor() {
safeImplementation = address(new Safe());
}
function createSafeAndWithdraw(address withdrawToken, uint256 withdrawAmount, string memory dstChainID, string memory dstAddress, string memory dstToken, string memory salt) external returns (Safe) {
require(msg.sender == OWNER || msg.sender == CALLER, "Sender is not owner or caller");
bytes32 safeSalt = _generateSalt(dstChainID, dstAddress, dstToken, salt);
address safeAddress = Clones.predictDeterministicAddress(safeImplementation, safeSalt);
Safe safe;
if (safeAddress.code.length == 0) {
safe = Safe(payable(Clones.cloneDeterministic(safeImplementation, safeSalt)));
} else {
safe = Safe(payable(safeAddress));
}
safe.withdraw(withdrawToken, withdrawAmount);
return safe;
}
function getAddressForSafe(string memory dstChainID, string memory dstAddress, string memory dstToken, string memory salt) public view returns (address) {
bytes32 safeSalt = _generateSalt(dstChainID, dstAddress, dstToken, salt);
return Clones.predictDeterministicAddress(safeImplementation, safeSalt);
}
function _generateSalt(string memory dstChainID, string memory dstAddress, string memory dstToken, string memory salt) internal pure returns (bytes32) {
require(bytes(dstChainID).length > 0, "Chain ID cannot be empty");
require(bytes(dstAddress).length > 0, "dstAddress cannot be empty");
require(bytes(dstToken).length > 0, "dstToken cannot be empty");
require(bytes(salt).length > 0, "Salt cannot be empty");
return keccak256(abi.encodePacked(dstChainID, dstAddress, dstToken, salt));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol)
pragma solidity ^0.8.20;
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.0.0) (interfaces/IERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (proxy/Clones.sol)
pragma solidity ^0.8.20;
import {Create2} from "../utils/Create2.sol";
import {Errors} from "../utils/Errors.sol";
/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[ERC-1167] is a standard for
* deploying minimal proxy contracts, also known as "clones".
*
* > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
* > a minimal bytecode implementation that delegates all calls to a known, fixed address.
*
* The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
* (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
* deterministic method.
*/
library Clones {
error CloneArgumentsTooLong();
/**
* @dev Deploys and returns the address of a clone that mimics the behavior of `implementation`.
*
* This function uses the create opcode, which should never revert.
*/
function clone(address implementation) internal returns (address instance) {
return clone(implementation, 0);
}
/**
* @dev Same as {xref-Clones-clone-address-}[clone], but with a `value` parameter to send native currency
* to the new contract.
*
* NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
* to always have enough balance for new deployments. Consider exposing this function under a payable method.
*/
function clone(address implementation, uint256 value) internal returns (address instance) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
assembly ("memory-safe") {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create(value, 0x09, 0x37)
}
if (instance == address(0)) {
revert Errors.FailedDeployment();
}
}
/**
* @dev Deploys and returns the address of a clone that mimics the behavior of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple times will revert, since
* the clones cannot be deployed twice at the same address.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
return cloneDeterministic(implementation, salt, 0);
}
/**
* @dev Same as {xref-Clones-cloneDeterministic-address-bytes32-}[cloneDeterministic], but with
* a `value` parameter to send native currency to the new contract.
*
* NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
* to always have enough balance for new deployments. Consider exposing this function under a payable method.
*/
function cloneDeterministic(
address implementation,
bytes32 salt,
uint256 value
) internal returns (address instance) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
assembly ("memory-safe") {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create2(value, 0x09, 0x37, salt)
}
if (instance == address(0)) {
revert Errors.FailedDeployment();
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
assembly ("memory-safe") {
let ptr := mload(0x40)
mstore(add(ptr, 0x38), deployer)
mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)
mstore(add(ptr, 0x14), implementation)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
mstore(add(ptr, 0x58), salt)
mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
predicted := and(keccak256(add(ptr, 0x43), 0x55), 0xffffffffffffffffffffffffffffffffffffffff)
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt
) internal view returns (address predicted) {
return predictDeterministicAddress(implementation, salt, address(this));
}
/**
* @dev Deploys and returns the address of a clone that mimics the behavior of `implementation` with custom
* immutable arguments. These are provided through `args` and cannot be changed after deployment. To
* access the arguments within the implementation, use {fetchCloneArgs}.
*
* This function uses the create opcode, which should never revert.
*/
function cloneWithImmutableArgs(address implementation, bytes memory args) internal returns (address instance) {
return cloneWithImmutableArgs(implementation, args, 0);
}
/**
* @dev Same as {xref-Clones-cloneWithImmutableArgs-address-bytes-}[cloneWithImmutableArgs], but with a `value`
* parameter to send native currency to the new contract.
*
* NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
* to always have enough balance for new deployments. Consider exposing this function under a payable method.
*/
function cloneWithImmutableArgs(
address implementation,
bytes memory args,
uint256 value
) internal returns (address instance) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args);
assembly ("memory-safe") {
instance := create(value, add(bytecode, 0x20), mload(bytecode))
}
if (instance == address(0)) {
revert Errors.FailedDeployment();
}
}
/**
* @dev Deploys and returns the address of a clone that mimics the behavior of `implementation` with custom
* immutable arguments. These are provided through `args` and cannot be changed after deployment. To
* access the arguments within the implementation, use {fetchCloneArgs}.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy the clone. Using the same
* `implementation`, `args` and `salt` multiple times will revert, since the clones cannot be deployed twice
* at the same address.
*/
function cloneDeterministicWithImmutableArgs(
address implementation,
bytes memory args,
bytes32 salt
) internal returns (address instance) {
return cloneDeterministicWithImmutableArgs(implementation, args, salt, 0);
}
/**
* @dev Same as {xref-Clones-cloneDeterministicWithImmutableArgs-address-bytes-bytes32-}[cloneDeterministicWithImmutableArgs],
* but with a `value` parameter to send native currency to the new contract.
*
* NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
* to always have enough balance for new deployments. Consider exposing this function under a payable method.
*/
function cloneDeterministicWithImmutableArgs(
address implementation,
bytes memory args,
bytes32 salt,
uint256 value
) internal returns (address instance) {
bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args);
return Create2.deploy(value, salt, bytecode);
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministicWithImmutableArgs}.
*/
function predictDeterministicAddressWithImmutableArgs(
address implementation,
bytes memory args,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args);
return Create2.computeAddress(salt, keccak256(bytecode), deployer);
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministicWithImmutableArgs}.
*/
function predictDeterministicAddressWithImmutableArgs(
address implementation,
bytes memory args,
bytes32 salt
) internal view returns (address predicted) {
return predictDeterministicAddressWithImmutableArgs(implementation, args, salt, address(this));
}
/**
* @dev Get the immutable args attached to a clone.
*
* - If `instance` is a clone that was deployed using `clone` or `cloneDeterministic`, this
* function will return an empty array.
* - If `instance` is a clone that was deployed using `cloneWithImmutableArgs` or
* `cloneDeterministicWithImmutableArgs`, this function will return the args array used at
* creation.
* - If `instance` is NOT a clone deployed using this library, the behavior is undefined. This
* function should only be used to check addresses that are known to be clones.
*/
function fetchCloneArgs(address instance) internal view returns (bytes memory) {
bytes memory result = new bytes(instance.code.length - 45); // revert if length is too short
assembly ("memory-safe") {
extcodecopy(instance, add(result, 32), 45, mload(result))
}
return result;
}
/**
* @dev Helper that prepares the initcode of the proxy with immutable args.
*
* An assembly variant of this function requires copying the `args` array, which can be efficiently done using
* `mcopy`. Unfortunately, that opcode is not available before cancun. A pure solidity implementation using
* abi.encodePacked is more expensive but also more portable and easier to review.
*
* NOTE: https://eips.ethereum.org/EIPS/eip-170[EIP-170] limits the length of the contract code to 24576 bytes.
* With the proxy code taking 45 bytes, that limits the length of the immutable args to 24531 bytes.
*/
function _cloneCodeWithImmutableArgs(
address implementation,
bytes memory args
) private pure returns (bytes memory) {
if (args.length > 24531) revert CloneArgumentsTooLong();
return
abi.encodePacked(
hex"61",
uint16(args.length + 45),
hex"3d81600a3d39f3363d3d373d3d3d363d73",
implementation,
hex"5af43d82803e903d91602b57fd5bf3",
args
);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @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.3.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 {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @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 {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @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 _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @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 _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @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 {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @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 rely 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 rely 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}.
* Opposedly, 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 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).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @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).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Create2.sol)
pragma solidity ^0.8.20;
import {Errors} from "./Errors.sol";
/**
* @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.
* `CREATE2` can be used to compute in advance the address where a smart
* contract will be deployed, which allows for interesting new mechanisms known
* as 'counterfactual interactions'.
*
* See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more
* information.
*/
library Create2 {
/**
* @dev There's no code to deploy.
*/
error Create2EmptyBytecode();
/**
* @dev Deploys a contract using `CREATE2`. The address where the contract
* will be deployed can be known in advance via {computeAddress}.
*
* The bytecode for a contract can be obtained from Solidity with
* `type(contractName).creationCode`.
*
* Requirements:
*
* - `bytecode` must not be empty.
* - `salt` must have not been used for `bytecode` already.
* - the factory must have a balance of at least `amount`.
* - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
*/
function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address addr) {
if (address(this).balance < amount) {
revert Errors.InsufficientBalance(address(this).balance, amount);
}
if (bytecode.length == 0) {
revert Create2EmptyBytecode();
}
assembly ("memory-safe") {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
// if no address was created, and returndata is not empty, bubble revert
if and(iszero(addr), not(iszero(returndatasize()))) {
let p := mload(0x40)
returndatacopy(p, 0, returndatasize())
revert(p, returndatasize())
}
}
if (addr == address(0)) {
revert Errors.FailedDeployment();
}
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the
* `bytecodeHash` or `salt` will result in a new destination address.
*/
function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
return computeAddress(salt, bytecodeHash, address(this));
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
* `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
*/
function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) {
assembly ("memory-safe") {
let ptr := mload(0x40) // Get free memory pointer
// | | ↓ ptr ... ↓ ptr + 0x0B (start) ... ↓ ptr + 0x20 ... ↓ ptr + 0x40 ... |
// |-------------------|---------------------------------------------------------------------------|
// | bytecodeHash | CCCCCCCCCCCCC...CC |
// | salt | BBBBBBBBBBBBB...BB |
// | deployer | 000000...0000AAAAAAAAAAAAAAAAAAA...AA |
// | 0xFF | FF |
// |-------------------|---------------------------------------------------------------------------|
// | memory | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC |
// | keccak(start, 85) | ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ |
mstore(add(ptr, 0x40), bytecodeHash)
mstore(add(ptr, 0x20), salt)
mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes
let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff
mstore8(start, 0xff)
addr := and(keccak256(start, 85), 0xffffffffffffffffffffffffffffffffffffffff)
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of common custom errors used in multiple contracts
*
* IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.
* It is recommended to avoid relying on the error API for critical functionality.
*
* _Available since v5.1._
*/
library Errors {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error InsufficientBalance(uint256 balance, uint256 needed);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedCall();
/**
* @dev The deployment failed.
*/
error FailedDeployment();
/**
* @dev A necessary precompile is missing.
*/
error MissingPrecompile(address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @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);
}// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0.0
pragma solidity ^0.8.22;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
contract Safe {
using SafeERC20 for IERC20;
event Withdrawal(
address indexed token,
uint256 value
);
address public constant GLIDE_ADDRESS = 0x078Bf499222bFcbbFB50EbB191270A9baC93ce44; // paywithglide.eth
receive() external payable {}
function withdraw(address token, uint256 amount) external {
require(amount > 0, "Amount must be greater than zero");
if (token == address(0)) {
require(amount <= address(this).balance, "Insufficient ETH balance");
(bool sent, ) = payable(GLIDE_ADDRESS).call{value: amount}("");
require(sent, "Failed to withdraw eth");
} else {
require(amount <= IERC20(token).balanceOf(address(this)), "Insufficient token balance");
IERC20(token).safeTransfer(GLIDE_ADDRESS, amount);
}
emit Withdrawal(token, amount);
}
}{
"evmVersion": "paris",
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"FailedDeployment","type":"error"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"CALLER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OWNER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"withdrawToken","type":"address"},{"internalType":"uint256","name":"withdrawAmount","type":"uint256"},{"internalType":"string","name":"dstChainID","type":"string"},{"internalType":"string","name":"dstAddress","type":"string"},{"internalType":"string","name":"dstToken","type":"string"},{"internalType":"string","name":"salt","type":"string"}],"name":"createSafeAndWithdraw","outputs":[{"internalType":"contract Safe","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"dstChainID","type":"string"},{"internalType":"string","name":"dstAddress","type":"string"},{"internalType":"string","name":"dstToken","type":"string"},{"internalType":"string","name":"salt","type":"string"}],"name":"getAddressForSafe","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"safeImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a060405234801561001057600080fd5b5060405161001d90610072565b604051809103906000f080158015610039573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505061007f565b61088880610efa83390190565b608051610e4b6100af6000396000818161014401528181610271015281816102bd015261036c0152610e4b6000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063117803e31461005c5780637030ccf71461007a578063863dabb4146100aa578063ac20c54b146100c8578063ceb99fc4146100f8575b600080fd5b610064610116565b60405161007191906106b3565b60405180910390f35b610094600480360381019061008f9190610828565b61012e565b6040516100a191906106b3565b60405180910390f35b6100b2610174565b6040516100bf91906106b3565b60405180910390f35b6100e260048036038101906100dd9190610961565b61018c565b6040516100ef9190610abd565b60405180910390f35b61010061036a565b60405161010d91906106b3565b60405180910390f35b73e883cd7adfe55cd84798a8129468e106b32cdc7a81565b60008061013d8686868661038e565b90506101697f0000000000000000000000000000000000000000000000000000000000000000826104d6565b915050949350505050565b73078bf499222bfcbbfb50ebb191270a9bac93ce4481565b600073e883cd7adfe55cd84798a8129468e106b32cdc7a73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061021b575073078bf499222bfcbbfb50ebb191270a9bac93ce4473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61025a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025190610b35565b60405180910390fd5b60006102688686868661038e565b905060006102967f0000000000000000000000000000000000000000000000000000000000000000836104d6565b90506000808273ffffffffffffffffffffffffffffffffffffffff163b036102e9576102e27f0000000000000000000000000000000000000000000000000000000000000000846104eb565b90506102ed565b8190505b8073ffffffffffffffffffffffffffffffffffffffff1663f3fef3a38b8b6040518363ffffffff1660e01b8152600401610328929190610b64565b600060405180830381600087803b15801561034257600080fd5b505af1158015610356573d6000803e3d6000fd5b505050508093505050509695505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000808551116103d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ca90610bd9565b60405180910390fd5b6000845111610417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161040e90610c45565b60405180910390fd5b600083511161045b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045290610cb1565b60405180910390fd5b600082511161049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049690610d1d565b60405180910390fd5b848484846040516020016104b69493929190610dae565b604051602081830303815290604052805190602001209050949350505050565b60006104e3838330610501565b905092915050565b60006104f983836000610578565b905092915050565b60006040518260388201526f5af43d82803e903d91602b57fd5bf3ff6024820152846014820152733d602d80600a3d3981f3363d3d373d3d3d363d7381528360588201526037600c820120607882015273ffffffffffffffffffffffffffffffffffffffff60556043830120169150509392505050565b6000814710156105c15747826040517fcf4791810000000000000000000000000000000000000000000000000000000081526004016105b8929190610dec565b60405180910390fd5b763d602d80600a3d3981f3363d3d373d3d3d363d730000008460601b60e81c176000526e5af43d82803e903d91602b57fd5bf38460781b17602052826037600984f59050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361066b576040517fb06ebf3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061069d82610672565b9050919050565b6106ad81610692565b82525050565b60006020820190506106c860008301846106a4565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610735826106ec565b810181811067ffffffffffffffff82111715610754576107536106fd565b5b80604052505050565b60006107676106ce565b9050610773828261072c565b919050565b600067ffffffffffffffff821115610793576107926106fd565b5b61079c826106ec565b9050602081019050919050565b82818337600083830152505050565b60006107cb6107c684610778565b61075d565b9050828152602081018484840111156107e7576107e66106e7565b5b6107f28482856107a9565b509392505050565b600082601f83011261080f5761080e6106e2565b5b813561081f8482602086016107b8565b91505092915050565b60008060008060808587031215610842576108416106d8565b5b600085013567ffffffffffffffff8111156108605761085f6106dd565b5b61086c878288016107fa565b945050602085013567ffffffffffffffff81111561088d5761088c6106dd565b5b610899878288016107fa565b935050604085013567ffffffffffffffff8111156108ba576108b96106dd565b5b6108c6878288016107fa565b925050606085013567ffffffffffffffff8111156108e7576108e66106dd565b5b6108f3878288016107fa565b91505092959194509250565b61090881610692565b811461091357600080fd5b50565b600081359050610925816108ff565b92915050565b6000819050919050565b61093e8161092b565b811461094957600080fd5b50565b60008135905061095b81610935565b92915050565b60008060008060008060c0878903121561097e5761097d6106d8565b5b600061098c89828a01610916565b965050602061099d89828a0161094c565b955050604087013567ffffffffffffffff8111156109be576109bd6106dd565b5b6109ca89828a016107fa565b945050606087013567ffffffffffffffff8111156109eb576109ea6106dd565b5b6109f789828a016107fa565b935050608087013567ffffffffffffffff811115610a1857610a176106dd565b5b610a2489828a016107fa565b92505060a087013567ffffffffffffffff811115610a4557610a446106dd565b5b610a5189828a016107fa565b9150509295509295509295565b6000819050919050565b6000610a83610a7e610a7984610672565b610a5e565b610672565b9050919050565b6000610a9582610a68565b9050919050565b6000610aa782610a8a565b9050919050565b610ab781610a9c565b82525050565b6000602082019050610ad26000830184610aae565b92915050565b600082825260208201905092915050565b7f53656e646572206973206e6f74206f776e6572206f722063616c6c6572000000600082015250565b6000610b1f601d83610ad8565b9150610b2a82610ae9565b602082019050919050565b60006020820190508181036000830152610b4e81610b12565b9050919050565b610b5e8161092b565b82525050565b6000604082019050610b7960008301856106a4565b610b866020830184610b55565b9392505050565b7f436861696e2049442063616e6e6f7420626520656d7074790000000000000000600082015250565b6000610bc3601883610ad8565b9150610bce82610b8d565b602082019050919050565b60006020820190508181036000830152610bf281610bb6565b9050919050565b7f647374416464726573732063616e6e6f7420626520656d707479000000000000600082015250565b6000610c2f601a83610ad8565b9150610c3a82610bf9565b602082019050919050565b60006020820190508181036000830152610c5e81610c22565b9050919050565b7f647374546f6b656e2063616e6e6f7420626520656d7074790000000000000000600082015250565b6000610c9b601883610ad8565b9150610ca682610c65565b602082019050919050565b60006020820190508181036000830152610cca81610c8e565b9050919050565b7f53616c742063616e6e6f7420626520656d707479000000000000000000000000600082015250565b6000610d07601483610ad8565b9150610d1282610cd1565b602082019050919050565b60006020820190508181036000830152610d3681610cfa565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610d71578082015181840152602081019050610d56565b60008484015250505050565b6000610d8882610d3d565b610d928185610d48565b9350610da2818560208601610d53565b80840191505092915050565b6000610dba8287610d7d565b9150610dc68286610d7d565b9150610dd28285610d7d565b9150610dde8284610d7d565b915081905095945050505050565b6000604082019050610e016000830185610b55565b610e0e6020830184610b55565b939250505056fea264697066735822122010c7bcf304023cdbc189bbb7ef860c6133af98ae6280040693c52a79a84f714964736f6c634300081c00336080604052348015600f57600080fd5b506108698061001f6000396000f3fe60806040526004361061002d5760003560e01c8063d488559814610039578063f3fef3a31461006457610034565b3661003457005b600080fd5b34801561004557600080fd5b5061004e61008d565b60405161005b91906104d5565b60405180910390f35b34801561007057600080fd5b5061008b60048036038101906100869190610557565b6100a5565b005b73078bf499222bfcbbfb50ebb191270a9bac93ce4481565b600081116100e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100df906105f4565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610225574781111561015f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161015690610660565b60405180910390fd5b600073078bf499222bfcbbfb50ebb191270a9bac93ce4473ffffffffffffffffffffffffffffffffffffffff1682604051610199906106b1565b60006040518083038185875af1925050503d80600081146101d6576040519150601f19603f3d011682016040523d82523d6000602084013e6101db565b606091505b505090508061021f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161021690610712565b60405180910390fd5b50610321565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161025e91906104d5565b602060405180830381865afa15801561027b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029f9190610747565b8111156102e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102d8906107c0565b60405180910390fd5b61032073078bf499222bfcbbfb50ebb191270a9bac93ce44828473ffffffffffffffffffffffffffffffffffffffff166103739092919063ffffffff16565b5b8173ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b658260405161036791906107ef565b60405180910390a25050565b6103ed838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85856040516024016103a692919061080a565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506103f2565b505050565b600080602060008451602086016000885af180610415576040513d6000823e3d81fd5b3d92506000519150506000821461043057600181141561044c565b60008473ffffffffffffffffffffffffffffffffffffffff163b145b1561048e57836040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161048591906104d5565b60405180910390fd5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006104bf82610494565b9050919050565b6104cf816104b4565b82525050565b60006020820190506104ea60008301846104c6565b92915050565b600080fd5b6104fe816104b4565b811461050957600080fd5b50565b60008135905061051b816104f5565b92915050565b6000819050919050565b61053481610521565b811461053f57600080fd5b50565b6000813590506105518161052b565b92915050565b6000806040838503121561056e5761056d6104f0565b5b600061057c8582860161050c565b925050602061058d85828601610542565b9150509250929050565b600082825260208201905092915050565b7f416d6f756e74206d7573742062652067726561746572207468616e207a65726f600082015250565b60006105de602083610597565b91506105e9826105a8565b602082019050919050565b6000602082019050818103600083015261060d816105d1565b9050919050565b7f496e73756666696369656e74204554482062616c616e63650000000000000000600082015250565b600061064a601883610597565b915061065582610614565b602082019050919050565b600060208201905081810360008301526106798161063d565b9050919050565b600081905092915050565b50565b600061069b600083610680565b91506106a68261068b565b600082019050919050565b60006106bc8261068e565b9150819050919050565b7f4661696c656420746f2077697468647261772065746800000000000000000000600082015250565b60006106fc601683610597565b9150610707826106c6565b602082019050919050565b6000602082019050818103600083015261072b816106ef565b9050919050565b6000815190506107418161052b565b92915050565b60006020828403121561075d5761075c6104f0565b5b600061076b84828501610732565b91505092915050565b7f496e73756666696369656e7420746f6b656e2062616c616e6365000000000000600082015250565b60006107aa601a83610597565b91506107b582610774565b602082019050919050565b600060208201905081810360008301526107d98161079d565b9050919050565b6107e981610521565b82525050565b600060208201905061080460008301846107e0565b92915050565b600060408201905061081f60008301856104c6565b61082c60208301846107e0565b939250505056fea26469706673582212206321f039845f65d38979dd662fb5bb65d3ede4ab2bae6dbca929848604724e9864736f6c634300081c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100575760003560e01c8063117803e31461005c5780637030ccf71461007a578063863dabb4146100aa578063ac20c54b146100c8578063ceb99fc4146100f8575b600080fd5b610064610116565b60405161007191906106b3565b60405180910390f35b610094600480360381019061008f9190610828565b61012e565b6040516100a191906106b3565b60405180910390f35b6100b2610174565b6040516100bf91906106b3565b60405180910390f35b6100e260048036038101906100dd9190610961565b61018c565b6040516100ef9190610abd565b60405180910390f35b61010061036a565b60405161010d91906106b3565b60405180910390f35b73e883cd7adfe55cd84798a8129468e106b32cdc7a81565b60008061013d8686868661038e565b90506101697f0000000000000000000000007aa475e148b35878094bb1946d04a081fad5bd80826104d6565b915050949350505050565b73078bf499222bfcbbfb50ebb191270a9bac93ce4481565b600073e883cd7adfe55cd84798a8129468e106b32cdc7a73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061021b575073078bf499222bfcbbfb50ebb191270a9bac93ce4473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61025a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025190610b35565b60405180910390fd5b60006102688686868661038e565b905060006102967f0000000000000000000000007aa475e148b35878094bb1946d04a081fad5bd80836104d6565b90506000808273ffffffffffffffffffffffffffffffffffffffff163b036102e9576102e27f0000000000000000000000007aa475e148b35878094bb1946d04a081fad5bd80846104eb565b90506102ed565b8190505b8073ffffffffffffffffffffffffffffffffffffffff1663f3fef3a38b8b6040518363ffffffff1660e01b8152600401610328929190610b64565b600060405180830381600087803b15801561034257600080fd5b505af1158015610356573d6000803e3d6000fd5b505050508093505050509695505050505050565b7f0000000000000000000000007aa475e148b35878094bb1946d04a081fad5bd8081565b6000808551116103d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ca90610bd9565b60405180910390fd5b6000845111610417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161040e90610c45565b60405180910390fd5b600083511161045b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045290610cb1565b60405180910390fd5b600082511161049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049690610d1d565b60405180910390fd5b848484846040516020016104b69493929190610dae565b604051602081830303815290604052805190602001209050949350505050565b60006104e3838330610501565b905092915050565b60006104f983836000610578565b905092915050565b60006040518260388201526f5af43d82803e903d91602b57fd5bf3ff6024820152846014820152733d602d80600a3d3981f3363d3d373d3d3d363d7381528360588201526037600c820120607882015273ffffffffffffffffffffffffffffffffffffffff60556043830120169150509392505050565b6000814710156105c15747826040517fcf4791810000000000000000000000000000000000000000000000000000000081526004016105b8929190610dec565b60405180910390fd5b763d602d80600a3d3981f3363d3d373d3d3d363d730000008460601b60e81c176000526e5af43d82803e903d91602b57fd5bf38460781b17602052826037600984f59050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361066b576040517fb06ebf3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061069d82610672565b9050919050565b6106ad81610692565b82525050565b60006020820190506106c860008301846106a4565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610735826106ec565b810181811067ffffffffffffffff82111715610754576107536106fd565b5b80604052505050565b60006107676106ce565b9050610773828261072c565b919050565b600067ffffffffffffffff821115610793576107926106fd565b5b61079c826106ec565b9050602081019050919050565b82818337600083830152505050565b60006107cb6107c684610778565b61075d565b9050828152602081018484840111156107e7576107e66106e7565b5b6107f28482856107a9565b509392505050565b600082601f83011261080f5761080e6106e2565b5b813561081f8482602086016107b8565b91505092915050565b60008060008060808587031215610842576108416106d8565b5b600085013567ffffffffffffffff8111156108605761085f6106dd565b5b61086c878288016107fa565b945050602085013567ffffffffffffffff81111561088d5761088c6106dd565b5b610899878288016107fa565b935050604085013567ffffffffffffffff8111156108ba576108b96106dd565b5b6108c6878288016107fa565b925050606085013567ffffffffffffffff8111156108e7576108e66106dd565b5b6108f3878288016107fa565b91505092959194509250565b61090881610692565b811461091357600080fd5b50565b600081359050610925816108ff565b92915050565b6000819050919050565b61093e8161092b565b811461094957600080fd5b50565b60008135905061095b81610935565b92915050565b60008060008060008060c0878903121561097e5761097d6106d8565b5b600061098c89828a01610916565b965050602061099d89828a0161094c565b955050604087013567ffffffffffffffff8111156109be576109bd6106dd565b5b6109ca89828a016107fa565b945050606087013567ffffffffffffffff8111156109eb576109ea6106dd565b5b6109f789828a016107fa565b935050608087013567ffffffffffffffff811115610a1857610a176106dd565b5b610a2489828a016107fa565b92505060a087013567ffffffffffffffff811115610a4557610a446106dd565b5b610a5189828a016107fa565b9150509295509295509295565b6000819050919050565b6000610a83610a7e610a7984610672565b610a5e565b610672565b9050919050565b6000610a9582610a68565b9050919050565b6000610aa782610a8a565b9050919050565b610ab781610a9c565b82525050565b6000602082019050610ad26000830184610aae565b92915050565b600082825260208201905092915050565b7f53656e646572206973206e6f74206f776e6572206f722063616c6c6572000000600082015250565b6000610b1f601d83610ad8565b9150610b2a82610ae9565b602082019050919050565b60006020820190508181036000830152610b4e81610b12565b9050919050565b610b5e8161092b565b82525050565b6000604082019050610b7960008301856106a4565b610b866020830184610b55565b9392505050565b7f436861696e2049442063616e6e6f7420626520656d7074790000000000000000600082015250565b6000610bc3601883610ad8565b9150610bce82610b8d565b602082019050919050565b60006020820190508181036000830152610bf281610bb6565b9050919050565b7f647374416464726573732063616e6e6f7420626520656d707479000000000000600082015250565b6000610c2f601a83610ad8565b9150610c3a82610bf9565b602082019050919050565b60006020820190508181036000830152610c5e81610c22565b9050919050565b7f647374546f6b656e2063616e6e6f7420626520656d7074790000000000000000600082015250565b6000610c9b601883610ad8565b9150610ca682610c65565b602082019050919050565b60006020820190508181036000830152610cca81610c8e565b9050919050565b7f53616c742063616e6e6f7420626520656d707479000000000000000000000000600082015250565b6000610d07601483610ad8565b9150610d1282610cd1565b602082019050919050565b60006020820190508181036000830152610d3681610cfa565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610d71578082015181840152602081019050610d56565b60008484015250505050565b6000610d8882610d3d565b610d928185610d48565b9350610da2818560208601610d53565b80840191505092915050565b6000610dba8287610d7d565b9150610dc68286610d7d565b9150610dd28285610d7d565b9150610dde8284610d7d565b915081905095945050505050565b6000604082019050610e016000830185610b55565b610e0e6020830184610b55565b939250505056fea264697066735822122010c7bcf304023cdbc189bbb7ef860c6133af98ae6280040693c52a79a84f714964736f6c634300081c0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.