Source Code
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Transfer | 21746209 | 290 days ago | 0.00133931 ETH | ||||
| Transfer | 21746209 | 290 days ago | 0.0861984 ETH | ||||
| Transfer | 21624694 | 307 days ago | 0.00908516 ETH | ||||
| Transfer | 21624694 | 307 days ago | 0.0140384 ETH | ||||
| Transfer | 21045347 | 388 days ago | 0.0140512 ETH | ||||
| Transfer | 20943617 | 402 days ago | 0.00017178 ETH | ||||
| Transfer | 20906894 | 407 days ago | 0.02895959 ETH | ||||
| Transfer | 20906894 | 407 days ago | 0.0146592 ETH | ||||
| Transfer | 19828126 | 558 days ago | 0.02536446 ETH | ||||
| Transfer | 19828102 | 558 days ago | 0.03420112 ETH | ||||
| Transfer | 19804942 | 561 days ago | 0.03265284 ETH | ||||
| Transfer | 19804942 | 561 days ago | 0.0216512 ETH | ||||
| Transfer | 19623765 | 586 days ago | 0.02699926 ETH | ||||
| Transfer | 19623765 | 586 days ago | 0.03184 ETH | ||||
| Transfer | 19508346 | 603 days ago | 0.02186325 ETH | ||||
| Transfer | 19493954 | 605 days ago | 0.13930763 ETH | ||||
| Transfer | 19481703 | 606 days ago | 0.044112 ETH | ||||
| Transfer | 19473246 | 608 days ago | 0.0409184 ETH | ||||
| Transfer | 19302121 | 631 days ago | 0.01034318 ETH | ||||
| Transfer | 19215187 | 644 days ago | 0.00517159 ETH | ||||
| Transfer | 19215187 | 644 days ago | 0.0102144 ETH | ||||
| Transfer | 18950565 | 681 days ago | 0.00515164 ETH | ||||
| Transfer | 18945569 | 682 days ago | 0.00515164 ETH | ||||
| Transfer | 18943040 | 682 days ago | 0.00515164 ETH | ||||
| Transfer | 18940680 | 682 days ago | 0.01030328 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
RoyaltyHandler
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import {ERC20} from "solmate/tokens/ERC20.sol";
import {Owned} from "solmate/auth/Owned.sol";
import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol";
contract RoyaltyHandler is Owned {
using SafeTransferLib for address payable;
using SafeTransferLib for ERC20;
constructor() Owned(msg.sender) {}
function sendETH(address payable to, uint256 amount) external onlyOwner {
to.safeTransferETH(amount);
}
function sendERC20(address to, address erc20Address, uint256 amount) external onlyOwner {
ERC20(erc20Address).safeTransfer(to, amount);
}
receive() external payable {}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
/*//////////////////////////////////////////////////////////////
METADATA STORAGE
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
uint8 public immutable decimals;
/*//////////////////////////////////////////////////////////////
ERC20 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
/*//////////////////////////////////////////////////////////////
EIP-2612 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
/*//////////////////////////////////////////////////////////////
ERC20 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
/*//////////////////////////////////////////////////////////////
EIP-2612 LOGIC
//////////////////////////////////////////////////////////////*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
// Unchecked because the only math done is incrementing
// the owner's nonce which cannot realistically overflow.
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
),
v,
r,
s
);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
/*//////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
// Cannot underflow because a user's balance
// will never be larger than the total supply.
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event OwnershipTransferred(address indexed user, address indexed newOwner);
/*//////////////////////////////////////////////////////////////
OWNERSHIP STORAGE
//////////////////////////////////////////////////////////////*/
address public owner;
modifier onlyOwner() virtual {
require(msg.sender == owner, "UNAUTHORIZED");
_;
}
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(address _owner) {
owner = _owner;
emit OwnershipTransferred(address(0), _owner);
}
/*//////////////////////////////////////////////////////////////
OWNERSHIP LOGIC
//////////////////////////////////////////////////////////////*/
function transferOwnership(address newOwner) public virtual onlyOwner {
owner = newOwner;
emit OwnershipTransferred(msg.sender, newOwner);
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
/*//////////////////////////////////////////////////////////////
ETH OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferETH(address to, uint256 amount) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Transfer the ETH and store if it succeeded or not.
success := call(gas(), to, amount, 0, 0, 0, 0)
}
require(success, "ETH_TRANSFER_FAILED");
}
/*//////////////////////////////////////////////////////////////
ERC20 OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument.
mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
)
}
require(success, "TRANSFER_FROM_FAILED");
}
function safeTransfer(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "TRANSFER_FAILED");
}
function safeApprove(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "APPROVE_FAILED");
}
}{
"remappings": [
"@manifoldxyz/=lib/lssvm2/lib/",
"@openzeppelin/contracts-upgradeable/=lib/lssvm2/lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/contracts/=lib/lssvm2/lib/openzeppelin-contracts/contracts/",
"@prb/math/=lib/lssvm2/lib/prb-math/src/",
"clones-with-immutable-args/=lib/lssvm2/lib/clones-with-immutable-args/src/",
"create2-helpers/=lib/lssvm2/lib/royalty-registry-solidity/lib/create2-helpers/",
"create3-factory/=lib/lssvm2/lib/create3-factory/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"foundry-huff/=lib/lssvm2/lib/foundry-huff/src/",
"huffmate/=lib/lssvm2/lib/huffmate/src/",
"libraries-solidity/=lib/lssvm2/lib/libraries-solidity/contracts/",
"lssvm2/=lib/lssvm2/src/",
"manifoldxyz/=lib/lssvm2/lib/royalty-registry-solidity/contracts/",
"openzeppelin-contracts-upgradeable/=lib/lssvm2/lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"openzeppelin/=lib/openzeppelin-contracts/contracts/",
"prb-math/=lib/lssvm2/lib/prb-math/src/",
"prb-test/=lib/lssvm2/lib/prb-math/lib/prb-test/src/",
"royalty-registry-solidity/=lib/lssvm2/lib/royalty-registry-solidity/",
"solady/=lib/solady/",
"solidity-stringutils/=lib/lssvm2/lib/foundry-huff/lib/solidity-stringutils/",
"solmate/=lib/solmate/src/",
"stringutils/=lib/lssvm2/lib/foundry-huff/lib/solidity-stringutils/",
"zipped-contracts/=lib/zipped-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sendERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sendETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
608060405234801561001057600080fd5b50600080546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506103cc806100616000396000f3fe6080604052600436106100435760003560e01c806364a197f31461004f5780638da5cb5b146100715780638f975a64146100ad578063f2fde38b146100cd57600080fd5b3661004a57005b600080fd5b34801561005b57600080fd5b5061006f61006a3660046102df565b6100ed565b005b34801561007d57600080fd5b50600054610091906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b3480156100b957600080fd5b5061006f6100c836600461030b565b610137565b3480156100d957600080fd5b5061006f6100e836600461034c565b61017a565b6000546001600160a01b031633146101205760405162461bcd60e51b815260040161011790610370565b60405180910390fd5b6101336001600160a01b038316826101ef565b5050565b6000546001600160a01b031633146101615760405162461bcd60e51b815260040161011790610370565b6101756001600160a01b0383168483610240565b505050565b6000546001600160a01b031633146101a45760405162461bcd60e51b815260040161011790610370565b600080546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b600080600080600085875af19050806101755760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b6044820152606401610117565b600060405163a9059cbb60e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806102c15760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610117565b50505050565b6001600160a01b03811681146102dc57600080fd5b50565b600080604083850312156102f257600080fd5b82356102fd816102c7565b946020939093013593505050565b60008060006060848603121561032057600080fd5b833561032b816102c7565b9250602084013561033b816102c7565b929592945050506040919091013590565b60006020828403121561035e57600080fd5b8135610369816102c7565b9392505050565b6020808252600c908201526b15539055551213d49256915160a21b60408201526060019056fea2646970667358221220f69a0c7c1200f108e1172c5c9c1b986a21d96b2fd0ae3aeeb690bf3227d0fd0564736f6c63430008140033
Deployed Bytecode
0x6080604052600436106100435760003560e01c806364a197f31461004f5780638da5cb5b146100715780638f975a64146100ad578063f2fde38b146100cd57600080fd5b3661004a57005b600080fd5b34801561005b57600080fd5b5061006f61006a3660046102df565b6100ed565b005b34801561007d57600080fd5b50600054610091906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b3480156100b957600080fd5b5061006f6100c836600461030b565b610137565b3480156100d957600080fd5b5061006f6100e836600461034c565b61017a565b6000546001600160a01b031633146101205760405162461bcd60e51b815260040161011790610370565b60405180910390fd5b6101336001600160a01b038316826101ef565b5050565b6000546001600160a01b031633146101615760405162461bcd60e51b815260040161011790610370565b6101756001600160a01b0383168483610240565b505050565b6000546001600160a01b031633146101a45760405162461bcd60e51b815260040161011790610370565b600080546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b600080600080600085875af19050806101755760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b6044820152606401610117565b600060405163a9059cbb60e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806102c15760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610117565b50505050565b6001600160a01b03811681146102dc57600080fd5b50565b600080604083850312156102f257600080fd5b82356102fd816102c7565b946020939093013593505050565b60008060006060848603121561032057600080fd5b833561032b816102c7565b9250602084013561033b816102c7565b929592945050506040919091013590565b60006020828403121561035e57600080fd5b8135610369816102c7565b9392505050565b6020808252600c908201526b15539055551213d49256915160a21b60408201526060019056fea2646970667358221220f69a0c7c1200f108e1172c5c9c1b986a21d96b2fd0ae3aeeb690bf3227d0fd0564736f6c63430008140033
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.