Address Contract Verified
Address
0x9D7553cb8B5E568AC317587722376f3207d6AaE4
Balance
0 ETH
Nonce
1
Code Size
3821 bytes
Creator
0xBa7684D0...BA4f at tx 0x8bec8e38...6c7b5e
Indexed Transactions
0
Contract Bytecode
3821 bytes
0x60806040526004361061007e575f3560e01c806397680cae1161004d57806397680cae14610113578063ad5c46481461012f578063e5711e8b14610159578063f33384c81461018157610085565b8063099a04e5146100895780632425371b146100b1578063720792bf146100cd5780638da5cb5b146100e957610085565b3661008557005b5f5ffd5b348015610094575f5ffd5b506100af60048036038101906100aa9190610c04565b61019d565b005b6100cb60048036038101906100c69190610ca3565b61035e565b005b6100e760048036038101906100e29190610ca3565b610493565b005b3480156100f4575f5ffd5b506100fd610603565b60405161010a9190610d0e565b60405180910390f35b61012d60048036038101906101289190610ca3565b610627565b005b34801561013a575f5ffd5b50610143610797565b6040516101509190610d0e565b60405180910390f35b348015610164575f5ffd5b5061017f600480360381019061017a9190610d51565b6107af565b005b61019b60048036038101906101969190610ca3565b610a3a565b005b7f000000000000000000000000ba7684d0d9a908bc75b34b016d07289b4613ba4f73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610222576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610287576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82146102b557816102b7565b475b90505f8373ffffffffffffffffffffffffffffffffffffffff16826040516102de90610dce565b5f6040518083038185875af1925050503d805f8114610318576040519150601f19603f3d011682016040523d82523d5f602084013e61031d565b606091505b5050905080610358576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b605882829050101561036e575f5ffd5b81803560601c601482013560601c602883013560801c603884013560801c604885013560801c6040516323b872dd60e01b815233600482015285602482015283604482015260205f6064835f895af16103c5575f5ffd5b3d5f81146103d957602081146103de575f5ffd5b6103e9565b5f516103e8575f5ffd5b5b5063022c0d9f60e01b81528260048201525f6024820152306044820152608060648201525f60848201525f5f60a4835f8a5af1610424575f5ffd5b632e1a7d4d60e01b81528260048201525f5f6024835f73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25af1610459575f5ffd5b5f5f5f5f86335af1610469575f5ffd5b8133311015610476575f5ffd5b5f341115610488575f5f5f5f34415af1505b505050505050505050565b60588282905010156104a3575f5ffd5b5f5f5f84803560601c601482013560601c602883013560801c603884013560801c604885013560801c97505f9650813411156104df5781340396505b60405163d0e30db060e01b81525f5f6004838673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25af1610511575f5ffd5b63a9059cbb60e01b81528460048201528260248201525f5f6044835f73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25af161054c575f5ffd5b63022c0d9f60e01b81528160048201525f6024820152336044820152608060648201525f60848201525f5f60a4835f895af1610586575f5ffd5b6370a0823160e01b8152336004820152602081602483875afa6105a7575f5ffd5b80519650505050505050828110156105eb576040517fbefa166000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82146105fc575f5f5f5f85415af1505b5050505050565b7f000000000000000000000000ba7684d0d9a908bc75b34b016d07289b4613ba4f81565b6058828290501015610637575f5ffd5b5f5f5f84803560601c601482013560601c602883013560801c603884013560801c604885013560801c97505f9650813411156106735781340396505b60405163d0e30db060e01b81525f5f6004838673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25af16106a5575f5ffd5b63a9059cbb60e01b81528460048201528260248201525f5f6044835f73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25af16106e0575f5ffd5b63022c0d9f60e01b81525f6004820152816024820152336044820152608060648201525f60848201525f5f60a4835f895af161071a575f5ffd5b6370a0823160e01b8152336004820152602081602483875afa61073b575f5ffd5b805196505050505050508281101561077f576040517fbefa166000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8214610790575f5f5f5f85415af1505b5050505050565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b7f000000000000000000000000ba7684d0d9a908bc75b34b016d07289b4613ba4f73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610834576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16148061089957505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b156108d0576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8390505f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8314610902578261097b565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161093b9190610d0e565b602060405180830381865afa158015610956573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097a9190610df6565b5b90505f8273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb86846040518363ffffffff1660e01b81526004016109b9929190610e30565b6020604051808303815f875af11580156109d5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109f99190610e8c565b905080610a32576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b6058828290501015610a4a575f5ffd5b81803560601c601482013560601c602883013560801c603884013560801c604885013560801c6040516323b872dd60e01b815233600482015285602482015283604482015260205f6064835f895af1610aa1575f5ffd5b3d5f8114610ab55760208114610aba575f5ffd5b610ac5565b5f51610ac4575f5ffd5b5b5063022c0d9f60e01b81525f6004820152826024820152306044820152608060648201525f60848201525f5f60a4835f8a5af1610b00575f5ffd5b632e1a7d4d60e01b81528260048201525f5f6024835f73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25af1610b35575f5ffd5b5f5f5f5f86335af1610b45575f5ffd5b8133311015610b52575f5ffd5b5f341115610b64575f5f5f5f34415af1505b505050505050505050565b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610ba082610b77565b9050919050565b610bb081610b96565b8114610bba575f5ffd5b50565b5f81359050610bcb81610ba7565b92915050565b5f819050919050565b610be381610bd1565b8114610bed575f5ffd5b50565b5f81359050610bfe81610bda565b92915050565b5f5f60408385031215610c1a57610c19610b6f565b5b5f610c2785828601610bbd565b9250506020610c3885828601610bf0565b9150509250929050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f840112610c6357610c62610c42565b5b8235905067ffffffffffffffff811115610c8057610c7f610c46565b5b602083019150836001820283011115610c9c57610c9b610c4a565b5b9250929050565b5f5f60208385031215610cb957610cb8610b6f565b5b5f83013567ffffffffffffffff811115610cd657610cd5610b73565b5b610ce285828601610c4e565b92509250509250929050565b5f610cf882610b77565b9050919050565b610d0881610cee565b82525050565b5f602082019050610d215f830184610cff565b92915050565b610d3081610cee565b8114610d3a575f5ffd5b50565b5f81359050610d4b81610d27565b92915050565b5f5f5f60608486031215610d6857610d67610b6f565b5b5f610d7586828701610d3d565b9350506020610d8686828701610d3d565b9250506040610d9786828701610bf0565b9150509250925092565b5f81905092915050565b50565b5f610db95f83610da1565b9150610dc482610dab565b5f82019050919050565b5f610dd882610dae565b9150819050919050565b5f81519050610df081610bda565b92915050565b5f60208284031215610e0b57610e0a610b6f565b5b5f610e1884828501610de2565b91505092915050565b610e2a81610bd1565b82525050565b5f604082019050610e435f830185610cff565b610e506020830184610e21565b9392505050565b5f8115159050919050565b610e6b81610e57565b8114610e75575f5ffd5b50565b5f81519050610e8681610e62565b92915050565b5f60208284031215610ea157610ea0610b6f565b5b5f610eae84828501610e78565b9150509291505056fea2646970667358221220183f39b1c6cdb4579e79cacf39630f0c27a3118dd0ecc1fcb6335bbb5391e88b64736f6c634300081f0033
Verified Source Code Full Match
Compiler: v0.8.31+commit.fd3a2265
EVM: osaka
Optimization: No
Dealer2.sol 307 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IWETH {
function deposit() external payable;
function withdraw(uint256) external;
function transfer(address to, uint256 value) external returns (bool);
}
interface IUniswapV2Pair {
function swap(
uint256 amount0Out,
uint256 amount1Out,
address to,
bytes calldata data
) external;
}
interface IERC20 {
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
function transfer(address to, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
}
contract Dealer {
error OutputNotReceived();
error NotAuthorized();
error ZeroAddress();
error TransferFailed();
address public immutable owner;
address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
// Packed calldata (fixed 88 bytes):
// [0..19] address pair
// [20..39] address token
// [40..55] uint128 amountIn
// [56..71] uint128 amountOut
// [72..87] uint128 minBalanceAfter
// BUY: msg.sender token balance must be >= minBalanceAfter
// SELL: msg.sender ETH balance must be >= minBalanceAfter
uint256 private constant _PACKED_LEN = 88;
/// @notice BUY (WETH -> Token): swap(0, amountOut).
/// @dev Off-chain you choose whether token is token0 or token1 by selecting this vs buyTokenWeth.
/// Bribe = msg.value - amountIn (if positive), paid only after verification.
function buyWethToken(bytes calldata data) external payable {
if (data.length < _PACKED_LEN) revert();
uint256 minBalanceAfter;
uint256 bribe;
uint256 afterBal;
assembly {
let o := data.offset
let pair := shr(96, calldataload(o))
let token := shr(96, calldataload(add(o, 20)))
let amountIn := shr(128, calldataload(add(o, 40)))
let amountOut := shr(128, calldataload(add(o, 56)))
minBalanceAfter := shr(128, calldataload(add(o, 72)))
// bribe = max(callvalue - amountIn, 0)
bribe := 0
if gt(callvalue(), amountIn) { bribe := sub(callvalue(), amountIn) }
// Use free memory (don't clobber 0x40/0x60 scratch slots)
let ptr := mload(0x40)
// WETH.deposit() selector 0xd0e30db0, value = amountIn
mstore(ptr, shl(224, 0xd0e30db0))
if iszero(call(gas(), WETH, amountIn, ptr, 4, 0, 0)) { revert(0, 0) }
// WETH.transfer(pair, amountIn) selector 0xa9059cbb
mstore(ptr, shl(224, 0xa9059cbb))
mstore(add(ptr, 4), pair)
mstore(add(ptr, 36), amountIn)
if iszero(call(gas(), WETH, 0, ptr, 68, 0, 0)) { revert(0, 0) }
// pair.swap(0, amountOut, caller(), "") selector 0x022c0d9f
mstore(ptr, shl(224, 0x022c0d9f))
mstore(add(ptr, 4), 0)
mstore(add(ptr, 36), amountOut)
mstore(add(ptr, 68), caller())
mstore(add(ptr, 100), 0x80)
mstore(add(ptr, 132), 0)
if iszero(call(gas(), pair, 0, ptr, 164, 0, 0)) { revert(0, 0) }
// token.balanceOf(caller()) selector 0x70a08231
mstore(ptr, shl(224, 0x70a08231))
mstore(add(ptr, 4), caller())
if iszero(staticcall(gas(), token, ptr, 36, ptr, 32)) { revert(0, 0) }
afterBal := mload(ptr)
}
if (afterBal < minBalanceAfter) revert OutputNotReceived();
if (bribe != 0) {
assembly {
// best-effort coinbase bribe
pop(call(gas(), coinbase(), bribe, 0, 0, 0, 0))
}
}
}
/// @notice BUY (WETH -> Token): swap(amountOut, 0).
function buyTokenWeth(bytes calldata data) external payable {
if (data.length < _PACKED_LEN) revert();
uint256 minBalanceAfter;
uint256 bribe;
uint256 afterBal;
assembly {
let o := data.offset
let pair := shr(96, calldataload(o))
let token := shr(96, calldataload(add(o, 20)))
let amountIn := shr(128, calldataload(add(o, 40)))
let amountOut := shr(128, calldataload(add(o, 56)))
minBalanceAfter := shr(128, calldataload(add(o, 72)))
bribe := 0
if gt(callvalue(), amountIn) { bribe := sub(callvalue(), amountIn) }
let ptr := mload(0x40)
mstore(ptr, shl(224, 0xd0e30db0))
if iszero(call(gas(), WETH, amountIn, ptr, 4, 0, 0)) { revert(0, 0) }
mstore(ptr, shl(224, 0xa9059cbb))
mstore(add(ptr, 4), pair)
mstore(add(ptr, 36), amountIn)
if iszero(call(gas(), WETH, 0, ptr, 68, 0, 0)) { revert(0, 0) }
// pair.swap(amountOut, 0, caller(), "")
mstore(ptr, shl(224, 0x022c0d9f))
mstore(add(ptr, 4), amountOut)
mstore(add(ptr, 36), 0)
mstore(add(ptr, 68), caller())
mstore(add(ptr, 100), 0x80)
mstore(add(ptr, 132), 0)
if iszero(call(gas(), pair, 0, ptr, 164, 0, 0)) { revert(0, 0) }
mstore(ptr, shl(224, 0x70a08231))
mstore(add(ptr, 4), caller())
if iszero(staticcall(gas(), token, ptr, 36, ptr, 32)) { revert(0, 0) }
afterBal := mload(ptr)
}
if (afterBal < minBalanceAfter) revert OutputNotReceived();
if (bribe != 0) {
assembly {
pop(call(gas(), coinbase(), bribe, 0, 0, 0, 0))
}
}
}
/// @notice SELL (Token -> WETH -> ETH): swap(0, amountOut) to this, unwrap, send ETH to msg.sender.
/// @dev Bribe = msg.value, paid only if msg.sender ETH balance >= minBalanceAfter.
function sellTokenWeth(bytes calldata data) external payable {
if (data.length < _PACKED_LEN) revert();
assembly {
let o := data.offset
let pair := shr(96, calldataload(o))
let token := shr(96, calldataload(add(o, 20)))
let amountIn := shr(128, calldataload(add(o, 40)))
let amountOut := shr(128, calldataload(add(o, 56)))
let minBalanceAfter := shr(128, calldataload(add(o, 72)))
let ptr := mload(0x40)
// token.transferFrom(caller(), pair, amountIn) selector 0x23b872dd
mstore(ptr, shl(224, 0x23b872dd))
mstore(add(ptr, 4), caller())
mstore(add(ptr, 36), pair)
mstore(add(ptr, 68), amountIn)
if iszero(call(gas(), token, 0, ptr, 100, 0, 32)) { revert(0, 0) }
// ERC20 return handling (SafeERC20-style):
// - no return data => assume success
// - 32 bytes return data => must be nonzero
// - other sizes => reject
switch returndatasize()
case 0 { }
case 32 {
if iszero(mload(0)) { revert(0, 0) }
}
default { revert(0, 0) }
// pair.swap(0, amountOut, address(), "") selector 0x022c0d9f
mstore(ptr, shl(224, 0x022c0d9f))
mstore(add(ptr, 4), 0)
mstore(add(ptr, 36), amountOut)
mstore(add(ptr, 68), address())
mstore(add(ptr, 100), 0x80)
mstore(add(ptr, 132), 0)
if iszero(call(gas(), pair, 0, ptr, 164, 0, 0)) { revert(0, 0) }
// WETH.withdraw(amountOut) selector 0x2e1a7d4d
mstore(ptr, shl(224, 0x2e1a7d4d))
mstore(add(ptr, 4), amountOut)
if iszero(call(gas(), WETH, 0, ptr, 36, 0, 0)) { revert(0, 0) }
// send ETH to caller()
if iszero(call(gas(), caller(), amountOut, 0, 0, 0, 0)) {
revert(0, 0)
}
// verify caller ETH balance
if lt(balance(caller()), minBalanceAfter) {
revert(0, 0)
}
// best-effort coinbase bribe
if gt(callvalue(), 0) {
pop(call(gas(), coinbase(), callvalue(), 0, 0, 0, 0))
}
}
}
/// @notice SELL (Token -> WETH -> ETH): swap(amountOut, 0) to this, unwrap, send ETH to msg.sender.
/// @dev Bribe = msg.value, paid only if msg.sender ETH balance >= minBalanceAfter.
function sellWethToken(bytes calldata data) external payable {
if (data.length < _PACKED_LEN) revert();
assembly {
let o := data.offset
let pair := shr(96, calldataload(o))
let token := shr(96, calldataload(add(o, 20)))
let amountIn := shr(128, calldataload(add(o, 40)))
let amountOut := shr(128, calldataload(add(o, 56)))
let minBalanceAfter := shr(128, calldataload(add(o, 72)))
let ptr := mload(0x40)
// token.transferFrom(caller(), pair, amountIn) selector 0x23b872dd
mstore(ptr, shl(224, 0x23b872dd))
mstore(add(ptr, 4), caller())
mstore(add(ptr, 36), pair)
mstore(add(ptr, 68), amountIn)
if iszero(call(gas(), token, 0, ptr, 100, 0, 32)) { revert(0, 0) }
switch returndatasize()
case 0 { }
case 32 {
if iszero(mload(0)) { revert(0, 0) }
}
default { revert(0, 0) }
// pair.swap(amountOut, 0, address(), "") selector 0x022c0d9f
mstore(ptr, shl(224, 0x022c0d9f))
mstore(add(ptr, 4), amountOut)
mstore(add(ptr, 36), 0)
mstore(add(ptr, 68), address())
mstore(add(ptr, 100), 0x80)
mstore(add(ptr, 132), 0)
if iszero(call(gas(), pair, 0, ptr, 164, 0, 0)) { revert(0, 0) }
// WETH.withdraw(amountOut) selector 0x2e1a7d4d
mstore(ptr, shl(224, 0x2e1a7d4d))
mstore(add(ptr, 4), amountOut)
if iszero(call(gas(), WETH, 0, ptr, 36, 0, 0)) { revert(0, 0) }
// send ETH to caller()
if iszero(call(gas(), caller(), amountOut, 0, 0, 0, 0)) {
revert(0, 0)
}
// verify caller ETH balance
if lt(balance(caller()), minBalanceAfter) {
revert(0, 0)
}
// best-effort coinbase bribe
if gt(callvalue(), 0) {
pop(call(gas(), coinbase(), callvalue(), 0, 0, 0, 0))
}
}
}
constructor() {
owner = msg.sender;
}
receive() external payable {}
modifier onlyOwner() {
if (msg.sender != owner) revert NotAuthorized();
_;
}
function rescueETH(address payable to, uint256 amount) external onlyOwner {
if (to == address(0)) revert ZeroAddress();
uint256 sendAmount = amount == type(uint256).max
? address(this).balance
: amount;
(bool ok, ) = to.call{value: sendAmount}("");
if (!ok) revert TransferFailed();
}
function rescueToken(
address token,
address to,
uint256 amount
) external onlyOwner {
if (token == address(0) || to == address(0)) revert ZeroAddress();
IERC20 tokenContract = IERC20(token);
uint256 sendAmount = amount == type(uint256).max
? tokenContract.balanceOf(address(this))
: amount;
bool success = tokenContract.transfer(to, sendAmount);
if (!success) revert TransferFailed();
}
}
Read Contract
WETH 0xad5c4648 → address
owner 0x8da5cb5b → address
Write Contract 6 functions
These functions modify contract state and require a wallet transaction to execute.
buyTokenWeth 0x720792bf
bytes data
buyWethToken 0x97680cae
bytes data
rescueETH 0x099a04e5
address to
uint256 amount
rescueToken 0xe5711e8b
address token
address to
uint256 amount
sellTokenWeth 0xf33384c8
bytes data
sellWethToken 0x2425371b
bytes data
Recent Transactions
No transactions found for this address