Address Contract Verified
Address
0x8fe4131eDdb5a603C098Ce974CdaBC105D1F70FC
Balance
0 ETH
Nonce
1
Code Size
3984 bytes
Creator
0xc4266409...6F84 at tx 0xbb7903da...91334c
Indexed Transactions
0
Contract Bytecode
3984 bytes
0x608060405234801561000f575f80fd5b506004361061011c575f3560e01c80639a84a860116100a9578063cef028e81161006e578063cef028e814610283578063dcbf137d14610296578063ddb6dfc4146102a9578063e086e5ec146102b2578063eb87eb38146102ba575f80fd5b80639a84a860146102065780639c54a51914610219578063b31c710a1461023b578063b91816111461024e578063c42bd05a14610270575f80fd5b806363ef1605116100ef57806363ef16051461017d578063664daa3e146101905780636fdca5e0146101a7578063735de9f7146101ba57806373b2e80e146101e4575f80fd5b806322cb804a1461012057806343156db61461013557806347535d7b14610148578063476e5f451461016a575b5f80fd5b61013361012e366004610c3c565b6102cd565b005b610133610143366004610c3c565b610376565b6005546101559060ff1681565b60405190151581526020015b60405180910390f35b610133610178366004610c64565b6103de565b61013361018b366004610ce9565b610625565b6101996103be81565b604051908152602001610161565b6101336101b5366004610d1e565b61067e565b5f546101cc906001600160a01b031681565b6040516001600160a01b039091168152602001610161565b6101556101f2366004610d39565b60076020525f908152604090205460ff1681565b610133610214366004610d39565b6106c0565b610155610227366004610d39565b60086020525f908152604090205460ff1681565b6001546101cc906001600160a01b031681565b61015561025c366004610d39565b60066020525f908152604090205460ff1681565b6002546101cc906001600160a01b031681565b610155610291366004610d66565b610712565b6101336102a4366004610e25565b610758565b61019960045481565b61013361078c565b6101336102c8366004610d39565b610845565b335f9081526006602052604090205460ff166102fc5760405163ea8e4eb560e01b815260040160405180910390fd5b60025460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb906044015b6020604051808303815f875af115801561034d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103719190610e3c565b505050565b335f9081526006602052604090205460ff166103a55760405163ea8e4eb560e01b815260040160405180910390fd5b60015460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb90604401610331565b8181808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525086925061041e915083905082610712565b61043b576040516309bde33960e01b815260040160405180910390fd5b335f9081526007602052604090205460ff161561046b57604051630c8d9eab60e31b815260040160405180910390fd5b335f9081526008602052604090205460ff161561049b5760405163763c9be160e01b815260040160405180910390fd5b6001546040516323b872dd60e01b8152336004820152306024820152604481018790526001600160a01b03909116906323b872dd906064016020604051808303815f875af11580156104ef573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105139190610e3c565b6105565760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064015b60405180910390fd5b60055460ff166105795760405163085de62560e01b815260040160405180910390fd5b61058285610894565b505f6105906103be87610e6b565b60025460405163a9059cbb60e01b8152336004820152602481018390529192506001600160a01b03169063a9059cbb906044016020604051808303815f875af11580156105df573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106039190610e3c565b5050335f908152600760205260409020805460ff191660011790555050505050565b335f9081526006602052604090205460ff166106545760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03919091165f908152600660205260409020805460ff1916911515919091179055565b335f9081526006602052604090205460ff166106ad5760405163ea8e4eb560e01b815260040160405180910390fd5b6005805460ff1916911515919091179055565b335f9081526006602052604090205460ff166106ef5760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03165f908152600860205260409020805460ff19166001179055565b604080513360208201529081018290525f90819060600160405160208183030381529060405280519060200120905061074e8460045483610b91565b9150505b92915050565b335f9081526006602052604090205460ff166107875760405163ea8e4eb560e01b815260040160405180910390fd5b600455565b335f9081526006602052604090205460ff166107bb5760405163ea8e4eb560e01b815260040160405180910390fd5b6040515f90339047908381818185875af1925050503d805f81146107fa576040519150601f19603f3d011682016040523d82523d5f602084013e6107ff565b606091505b50509050806108425760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b604482015260640161054d565b50565b335f9081526006602052604090205460ff166108745760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03165f908152600860205260409020805460ff19169055565b604080516003808252608082019092525f9182919060208201606080368337505060015482519293506001600160a01b0316918391505f906108d8576108d8610e82565b6001600160a01b03928316602091820292909201015260035482519116908290600190811061090957610909610e82565b6001600160a01b039283166020918202929092010152600280548351921691839190811061093957610939610e82565b6001600160a01b0392831660209182029290920101526002546040516370a0823160e01b81523060048201525f9291909116906370a0823190602401602060405180830381865afa158015610990573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109b49190610e96565b6001545f5460405163095ea7b360e01b81526001600160a01b03918216600482015260248101889052929350169063095ea7b3906044016020604051808303815f875af1158015610a07573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a2b9190610e3c565b505f80546001600160a01b0316906338ed17399086908530610a4e4260b4610ead565b6040518663ffffffff1660e01b8152600401610a6e959493929190610ec0565b5f604051808303815f87803b158015610a85575f80fd5b505af1158015610a97573d5f803e3d5ffd5b50506002546040516370a0823160e01b81523060048201525f93508492506001600160a01b03909116906370a0823190602401602060405180830381865afa158015610ae5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b099190610e96565b610b139190610f2f565b60025460405163a9059cbb60e01b815261dead6004820152602481018390529192506001600160a01b03169063a9059cbb906044016020604051808303815f875af1158015610b64573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b889190610e3c565b50949350505050565b5f82610b9d8584610ba6565b14949350505050565b5f81815b8451811015610bea57610bd682868381518110610bc957610bc9610e82565b6020026020010151610bf2565b915080610be281610f42565b915050610baa565b509392505050565b5f818310610c0c575f828152602084905260409020610c1a565b5f8381526020839052604090205b9392505050565b80356001600160a01b0381168114610c37575f80fd5b919050565b5f8060408385031215610c4d575f80fd5b610c5683610c21565b946020939093013593505050565b5f805f60408486031215610c76575f80fd5b83359250602084013567ffffffffffffffff80821115610c94575f80fd5b818601915086601f830112610ca7575f80fd5b813581811115610cb5575f80fd5b8760208260051b8501011115610cc9575f80fd5b6020830194508093505050509250925092565b8015158114610842575f80fd5b5f8060408385031215610cfa575f80fd5b610d0383610c21565b91506020830135610d1381610cdc565b809150509250929050565b5f60208284031215610d2e575f80fd5b8135610c1a81610cdc565b5f60208284031215610d49575f80fd5b610c1a82610c21565b634e487b7160e01b5f52604160045260245ffd5b5f8060408385031215610d77575f80fd5b823567ffffffffffffffff80821115610d8e575f80fd5b818501915085601f830112610da1575f80fd5b8135602082821115610db557610db5610d52565b8160051b604051601f19603f83011681018181108682111715610dda57610dda610d52565b604052928352818301935084810182019289841115610df7575f80fd5b948201945b83861015610e1557853585529482019493820193610dfc565b9997909101359750505050505050565b5f60208284031215610e35575f80fd5b5035919050565b5f60208284031215610e4c575f80fd5b8151610c1a81610cdc565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761075257610752610e57565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215610ea6575f80fd5b5051919050565b8082018082111561075257610752610e57565b5f60a082018783526020878185015260a0604085015281875180845260c08601915082890193505f5b81811015610f0e5784516001600160a01b031683529383019391830191600101610ee9565b50506001600160a01b03969096166060850152505050608001529392505050565b8181038181111561075257610752610e57565b5f60018201610f5357610f53610e57565b506001019056fea2646970667358221220e94290bf813dafe6e1c88d595f3e53cf4ba49f576dc4d1fae471f4797083e0a564736f6c63430008150033
Verified Source Code Full Match
Compiler: v0.8.21+commit.d9974bed
EVM: shanghai
Optimization: Yes (200 runs)
Migrator.sol 344 lines
// SPDX-License-Identifier: None
pragma solidity =0.8.21;
interface newIERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
interface oldIERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
library MerkleProof {
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
function verifyCalldata(
bytes32[] calldata proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
return processProofCalldata(proof, leaf) == root;
}
function processProof(
bytes32[] memory proof,
bytes32 leaf
) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
function processProofCalldata(
bytes32[] calldata proof,
bytes32 leaf
) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
function multiProofVerify(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProof(proof, proofFlags, leaves) == root;
}
function multiProofVerifyCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProofCalldata(proof, proofFlags, leaves) == root;
}
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
uint256 leavesLen = leaves.length;
uint256 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
// Check proof validity.
require(
leavesLen + proofLen - 1 == totalHashes,
"MerkleProof: invalid multiproof"
);
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen
? leaves[leafPos++]
: hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
require(proofPos == proofLen, "MerkleProof: invalid multiproof");
unchecked {
return hashes[totalHashes - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
uint256 leavesLen = leaves.length;
uint256 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
require(
leavesLen + proofLen - 1 == totalHashes,
"MerkleProof: invalid multiproof"
);
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen
? leaves[leafPos++]
: hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
require(proofPos == proofLen, "MerkleProof: invalid multiproof");
unchecked {
return hashes[totalHashes - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
}
function _efficientHash(
bytes32 a,
bytes32 b
) private pure returns (bytes32 value) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}
interface IUniswapV2Router02 {
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
error NoSwap4U();
error NotAuthorized();
error InvalidProof();
error AlreadyClaimed();
error TooEarly();
contract TokenSwap {
uint256 public constant NEW_TOKEN_PER_OLD = 958;
IUniswapV2Router02 public uniswapRouter;
oldIERC20 public oldToken;
newIERC20 public newToken;
address private WETH;
bytes32 public merkleRootHash;
bool public isOpen;
mapping(address => bool) public authorized;
mapping(address => bool) public hasClaimed;
mapping(address => bool) public noswap4u;
constructor(address _oldToken, address _newToken) {
if (block.chainid == 1) {
WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
} else if (block.chainid == 5) {
WETH = 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6;
}
uniswapRouter = IUniswapV2Router02(
0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
);
oldToken = oldIERC20(_oldToken);
newToken = newIERC20(_newToken);
authorized[msg.sender] = true;
}
modifier onlyAuthorized() {
if (!authorized[msg.sender]) {
revert NotAuthorized();
}
_;
}
function verify(
bytes32[] memory proof,
uint256 amount
) public view returns (bool) {
bytes32 leaf = keccak256(abi.encode(msg.sender, amount));
return MerkleProof.verify(proof, merkleRootHash, leaf);
}
modifier onlyMerkleVerified(bytes32[] memory proof, uint256 amount) {
if (!verify(proof, amount)) {
revert InvalidProof();
}
if (hasClaimed[msg.sender]) {
revert AlreadyClaimed();
}
if (noswap4u[msg.sender]) {
revert NoSwap4U();
}
_;
}
function setOpen(bool _value) external onlyAuthorized {
isOpen = _value;
}
function modifyAuthorized(
address _address,
bool _value
) public onlyAuthorized {
authorized[_address] = _value;
}
function noswap4uAdd(address _address) external onlyAuthorized {
noswap4u[_address] = true;
}
function okfineucanswap(address _address) external onlyAuthorized {
noswap4u[_address] = false;
}
function modifyRoot(bytes32 _merkleRoot) external onlyAuthorized {
merkleRootHash = _merkleRoot;
}
function swapExactTokensForTokens(
uint256 amount,
bytes32[] calldata proof
) external onlyMerkleVerified(proof, amount) {
require(
oldToken.transferFrom(msg.sender, address(this), amount),
"Transfer failed"
);
if (!isOpen) {
revert TooEarly();
}
migrateSwap(amount);
uint256 newAmount = amount * NEW_TOKEN_PER_OLD;
newToken.transfer(msg.sender, newAmount);
hasClaimed[msg.sender] = true;
}
function migrateSwap(uint256 amount) internal returns (uint256) {
address[] memory path = new address[](3);
path[0] = address(oldToken);
path[1] = WETH;
path[2] = address(newToken);
// Record balance before swap
uint256 newTokenBalanceBefore = newToken.balanceOf(address(this));
// Approve and swap
oldToken.approve(address(uniswapRouter), amount);
uniswapRouter.swapExactTokensForTokens(
amount,
0, // No slippage protection
path,
address(this),
block.timestamp + 180
);
// Calculate received amount
uint256 receivedNewToken = newToken.balanceOf(address(this)) - newTokenBalanceBefore;
// Transfer to burn address
newToken.transfer(address(0xdead), receivedNewToken);
return receivedNewToken;
}
function withdrawOldToken(
address receiver,
uint256 amount
) external onlyAuthorized {
oldToken.transfer(receiver, amount);
}
function withdrawNewToken(
address receiver,
uint256 amount
) external onlyAuthorized {
newToken.transfer(receiver, amount);
}
function withdrawETH() external onlyAuthorized {
(bool success, ) = payable(msg.sender).call{value: address(this).balance}(
""
);
require(success, "Transfer failed");
}
}
Read Contract
NEW_TOKEN_PER_OLD 0x664daa3e → uint256
authorized 0xb9181611 → bool
hasClaimed 0x73b2e80e → bool
isOpen 0x47535d7b → bool
merkleRootHash 0xddb6dfc4 → bytes32
newToken 0xc42bd05a → address
noswap4u 0x9c54a519 → bool
oldToken 0xb31c710a → address
uniswapRouter 0x735de9f7 → address
verify 0xcef028e8 → bool
Write Contract 9 functions
These functions modify contract state and require a wallet transaction to execute.
modifyAuthorized 0x63ef1605
address _address
bool _value
modifyRoot 0xdcbf137d
bytes32 _merkleRoot
noswap4uAdd 0x9a84a860
address _address
okfineucanswap 0xeb87eb38
address _address
setOpen 0x6fdca5e0
bool _value
swapExactTokensForTokens 0x476e5f45
uint256 amount
bytes32[] proof
withdrawETH 0xe086e5ec
No parameters
withdrawNewToken 0x22cb804a
address receiver
uint256 amount
withdrawOldToken 0x43156db6
address receiver
uint256 amount
Recent Transactions
No transactions found for this address