Address Contract Verified
Address
0x16BCbaCB2F9A2FbD8C825d3c3Da41961Fb6213B7
Balance
0 ETH
Nonce
1
Code Size
3606 bytes
Creator
0x4cbeECcb...466b at tx 0xcd9216ac...3421d0
Indexed Transactions
0 (1 on-chain, 1.2% indexed)
Contract Bytecode
3606 bytes
0x60806040526004361061003f5760003560e01c80630c888d6914610044578063454594081461007557806384796caf146100a0578063c9fbfbfa146100cb575b600080fd5b61005e60048036038101906100599190610933565b610109565b60405161006c929190610a81565b60405180910390f35b34801561008157600080fd5b5061008a6102ff565b6040516100979190610ac0565b60405180910390f35b3480156100ac57600080fd5b506100b5610323565b6040516100c29190610ac0565b60405180910390f35b3480156100d757600080fd5b506100f260048036038101906100ed9190610adb565b610347565b604051610100929190610a81565b60405180910390f35b60006060600034141561014e57610122853330866104a8565b61014d857f000000000000000000000000216b4b4ba9f3e719726886d34a177484278bfcae85610547565b5b7f000000000000000000000000def171fe48cf0115b1d80b88dc8eab59176fee5773ffffffffffffffffffffffffffffffffffffffff16348989604051610196929190610ba2565b60006040518083038185875af1925050503d80600081146101d3576040519150601f19603f3d011682016040523d82523d6000602084013e6101d8565b606091505b5080925081935050508161022357806040517f113ab42700000000000000000000000000000000000000000000000000000000815260040161021a9190610bbb565b60405180910390fd5b6102b684878673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016102619190610ac0565b60206040518083038186803b15801561027957600080fd5b505afa15801561028d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b19190610bf2565b6105df565b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146102f4576102f385610677565b5b965096945050505050565b7f000000000000000000000000def171fe48cf0115b1d80b88dc8eab59176fee5781565b7f000000000000000000000000216b4b4ba9f3e719726886d34a177484278bfcae81565b60006060610357843330866104a8565b610382847f000000000000000000000000216b4b4ba9f3e719726886d34a177484278bfcae85610547565b7f000000000000000000000000def171fe48cf0115b1d80b88dc8eab59176fee5773ffffffffffffffffffffffffffffffffffffffff1687876040516103c9929190610ba2565b6000604051808303816000865af19150503d8060008114610406576040519150601f19603f3d011682016040523d82523d6000602084013e61040b565b606091505b5080925081935050508161045657806040517f113ab42700000000000000000000000000000000000000000000000000000000815260040161044d9190610bbb565b60405180910390fd5b610460854761079f565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461049e5761049d84610677565b5b9550959350505050565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080610540576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053790610c7c565b60405180910390fd5b5050505050565b60006040517f095ea7b3000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806105d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d090610ce8565b60405180910390fd5b50505050565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080610671576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066890610d54565b60405180910390fd5b50505050565b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016106b29190610ac0565b60206040518083038186803b1580156106ca57600080fd5b505afa1580156106de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107029190610bf2565b111561079c5761079b81338373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016107469190610ac0565b60206040518083038186803b15801561075e57600080fd5b505afa158015610772573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107969190610bf2565b6105df565b5b50565b600080600080600085875af19050806107ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e490610dc0565b60405180910390fd5b505050565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f840112610821576108206107fc565b5b8235905067ffffffffffffffff81111561083e5761083d610801565b5b60208301915083600182028301111561085a57610859610806565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061088c82610861565b9050919050565b61089c81610881565b81146108a757600080fd5b50565b6000813590506108b981610893565b92915050565b60006108ca82610881565b9050919050565b6108da816108bf565b81146108e557600080fd5b50565b6000813590506108f7816108d1565b92915050565b6000819050919050565b610910816108fd565b811461091b57600080fd5b50565b60008135905061092d81610907565b92915050565b60008060008060008060a087890312156109505761094f6107f2565b5b600087013567ffffffffffffffff81111561096e5761096d6107f7565b5b61097a89828a0161080b565b9650965050602061098d89828a016108aa565b945050604061099e89828a016108e8565b93505060606109af89828a016108e8565b92505060806109c089828a0161091e565b9150509295509295509295565b60008115159050919050565b6109e2816109cd565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a22578082015181840152602081019050610a07565b83811115610a31576000848401525b50505050565b6000601f19601f8301169050919050565b6000610a53826109e8565b610a5d81856109f3565b9350610a6d818560208601610a04565b610a7681610a37565b840191505092915050565b6000604082019050610a9660008301856109d9565b8181036020830152610aa88184610a48565b90509392505050565b610aba81610881565b82525050565b6000602082019050610ad56000830184610ab1565b92915050565b600080600080600060808688031215610af757610af66107f2565b5b600086013567ffffffffffffffff811115610b1557610b146107f7565b5b610b218882890161080b565b95509550506020610b34888289016108aa565b9350506040610b45888289016108e8565b9250506060610b568882890161091e565b9150509295509295909350565b600081905092915050565b82818337600083830152505050565b6000610b898385610b63565b9350610b96838584610b6e565b82840190509392505050565b6000610baf828486610b7d565b91508190509392505050565b60006020820190508181036000830152610bd58184610a48565b905092915050565b600081519050610bec81610907565b92915050565b600060208284031215610c0857610c076107f2565b5b6000610c1684828501610bdd565b91505092915050565b600082825260208201905092915050565b7f5452414e534645525f46524f4d5f4641494c4544000000000000000000000000600082015250565b6000610c66601483610c1f565b9150610c7182610c30565b602082019050919050565b60006020820190508181036000830152610c9581610c59565b9050919050565b7f415050524f56455f4641494c4544000000000000000000000000000000000000600082015250565b6000610cd2600e83610c1f565b9150610cdd82610c9c565b602082019050919050565b60006020820190508181036000830152610d0181610cc5565b9050919050565b7f5452414e534645525f4641494c45440000000000000000000000000000000000600082015250565b6000610d3e600f83610c1f565b9150610d4982610d08565b602082019050919050565b60006020820190508181036000830152610d6d81610d31565b9050919050565b7f4554485f5452414e534645525f4641494c454400000000000000000000000000600082015250565b6000610daa601383610c1f565b9150610db582610d74565b602082019050919050565b60006020820190508181036000830152610dd981610d9d565b905091905056fea264697066735822122051b44dde03ba77d7567181d4a437b840a4e086af1b9b2b39671376c42f466e1264736f6c63430008090033
Verified Source Code Full Match
Compiler: v0.8.9+commit.e5eed63a
EVM: london
Optimization: No
Wrapper.sol 83 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import {ERC20} from "@rari-capital/solmate/src/tokens/ERC20.sol";
import {SafeTransferLib} from "@rari-capital/solmate/src/utils/SafeTransferLib.sol";
contract ParaswapWrapperV2 {
address public immutable PARASWAP_V5;
address public immutable PARASWAP_TRANSFER_PROXY;
/// @notice Thrown when swap fails.
error swapFailed(bytes output);
constructor(address _paraswapV5, address _paraswapTransferProxy) {
PARASWAP_V5 = _paraswapV5;
PARASWAP_TRANSFER_PROXY = _paraswapTransferProxy;
}
function swapToTokens(
bytes calldata _txData,
address _receiver,
ERC20 _fromToken,
ERC20 _toToken,
uint256 _inputAmount
) external payable returns (bool success, bytes memory output) {
if (msg.value == 0) {
SafeTransferLib.safeTransferFrom(
_fromToken,
msg.sender,
address(this),
_inputAmount
);
SafeTransferLib.safeApprove(
_fromToken,
PARASWAP_TRANSFER_PROXY,
_inputAmount
);
}
(success, output) = PARASWAP_V5.call{value: msg.value}(_txData);
if (!success) revert swapFailed(output);
SafeTransferLib.safeTransfer(
_toToken,
_receiver,
_toToken.balanceOf(address(this))
);
if (address(_fromToken) != address(0)) checkTokenRefund(_fromToken);
}
function swapToEth(
bytes calldata _txData,
address _receiver,
ERC20 _fromToken,
uint256 _inputAmount
) external returns (bool success, bytes memory output) {
SafeTransferLib.safeTransferFrom(
_fromToken,
msg.sender,
address(this),
_inputAmount
);
SafeTransferLib.safeApprove(
_fromToken,
PARASWAP_TRANSFER_PROXY,
_inputAmount
);
(success, output) = PARASWAP_V5.call(_txData);
if (!success) revert swapFailed(output);
SafeTransferLib.safeTransferETH(_receiver, address(this).balance);
if (address(_fromToken) != address(0)) checkTokenRefund(_fromToken);
}
function checkTokenRefund(ERC20 _fromToken) internal {
if (_fromToken.balanceOf(address(this)) > 0) {
SafeTransferLib.safeTransfer(
_fromToken,
msg.sender,
_fromToken.balanceOf(address(this))
);
}
}
}
ERC20.sol 206 lines
// 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/Rari-Capital/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);
}
}
SafeTransferLib.sol 124 lines
// 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/Rari-Capital/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;
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;
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), from) // Append the "from" argument.
mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument.
mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument.
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;
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), to) // Append the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.
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;
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), to) // Append the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.
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");
}
}
Read Contract
PARASWAP_TRANSFER_PROXY 0x84796caf → address
PARASWAP_V5 0x45459408 → address
Write Contract 2 functions
These functions modify contract state and require a wallet transaction to execute.
swapToEth 0xc9fbfbfa
bytes _txData
address _receiver
address _fromToken
uint256 _inputAmount
returns: bool, bytes
swapToTokens 0x0c888d69
bytes _txData
address _receiver
address _fromToken
address _toToken
uint256 _inputAmount
returns: bool, bytes
Recent Transactions
This address has 1 on-chain transactions, but only 1.2% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →