Source Code
Latest 25 from a total of 22,372 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Swap | 362830534 | 180 days ago | IN | 0 ETH | 0.00000342 | ||||
| Swap | 362690940 | 180 days ago | IN | 0 ETH | 0.00000292 | ||||
| Swap | 362446192 | 181 days ago | IN | 0 ETH | 0.00000241 | ||||
| Swap | 362442602 | 181 days ago | IN | 0 ETH | 0.00000241 | ||||
| Swap | 362434086 | 181 days ago | IN | 0 ETH | 0.00000246 | ||||
| Swap | 362416943 | 181 days ago | IN | 0 ETH | 0.00000246 | ||||
| Swap | 361071553 | 185 days ago | IN | 0 ETH | 0.0000048 | ||||
| Swap | 360787538 | 186 days ago | IN | 0 ETH | 0.00001837 | ||||
| Swap | 359998287 | 188 days ago | IN | 0 ETH | 0.00000233 | ||||
| Swap | 357848023 | 194 days ago | IN | 0 ETH | 0.00000213 | ||||
| Swap | 357053925 | 197 days ago | IN | 0 ETH | 0.00000221 | ||||
| Swap | 356191338 | 199 days ago | IN | 0 ETH | 0.00000229 | ||||
| Swap | 355776009 | 200 days ago | IN | 0 ETH | 0.00000202 | ||||
| Swap | 355432619 | 201 days ago | IN | 0 ETH | 0.00000213 | ||||
| Swap | 353328412 | 208 days ago | IN | 0 ETH | 0.00012938 | ||||
| Swap | 351022091 | 214 days ago | IN | 0 ETH | 0.00000279 | ||||
| Swap | 348861546 | 220 days ago | IN | 0 ETH | 0.00000331 | ||||
| Swap | 344926448 | 232 days ago | IN | 0 ETH | 0.00000368 | ||||
| Swap | 344926367 | 232 days ago | IN | 0 ETH | 0.00000368 | ||||
| Swap | 343468017 | 236 days ago | IN | 0 ETH | 0.00000235 | ||||
| Swap | 343467911 | 236 days ago | IN | 0 ETH | 0.00000242 | ||||
| Swap | 340692171 | 244 days ago | IN | 0 ETH | 0.00000318 | ||||
| Swap | 337964709 | 252 days ago | IN | 0 ETH | 0.00000303 | ||||
| Swap | 333851248 | 264 days ago | IN | 0 ETH | 0.00013149 | ||||
| Swap | 333850989 | 264 days ago | IN | 0 ETH | 0.00013149 |
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 325921667 | 287 days ago | 0.001 ETH | ||||
| 309847976 | 334 days ago | 0.000019 ETH | ||||
| 304664679 | 349 days ago | 0.0004 ETH | ||||
| 298897452 | 366 days ago | 0.00033 ETH | ||||
| 298896902 | 366 days ago | 0.0003 ETH | ||||
| 298895905 | 366 days ago | 0.00031 ETH | ||||
| 298894766 | 366 days ago | 0.00031 ETH | ||||
| 296733484 | 372 days ago | 0.00001 ETH | ||||
| 295354224 | 376 days ago | 0.00189 ETH | ||||
| 295206891 | 376 days ago | 0.002 ETH | ||||
| 293966627 | 380 days ago | 0.0004 ETH | ||||
| 293574463 | 381 days ago | 0.0004 ETH | ||||
| 293571208 | 381 days ago | 0.0004 ETH | ||||
| 293565756 | 381 days ago | 0.0004 ETH | ||||
| 293560957 | 381 days ago | 0.0004 ETH | ||||
| 293558254 | 381 days ago | 0.0004 ETH | ||||
| 292574106 | 384 days ago | 0.0014 ETH | ||||
| 292188299 | 385 days ago | 0.0015 ETH | ||||
| 291126675 | 388 days ago | 0.0004 ETH | ||||
| 289858380 | 392 days ago | 0.0004 ETH | ||||
| 289855551 | 392 days ago | 0.0004 ETH | ||||
| 289851219 | 392 days ago | 0.0004 ETH | ||||
| 289835589 | 392 days ago | 0.0004 ETH | ||||
| 289778199 | 392 days ago | 0.0004 ETH | ||||
| 289771971 | 392 days ago | 0.0004 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SwapFacade
Compiler Version
v0.8.18+commit.87f61d96
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
import '@1inch/solidity-utils/contracts/libraries/SafeERC20.sol';
import './features/ContractOnlyEthRecipient.sol';
import './interfaces/ISwapFacade.sol';
import './libs/TokenLibrary.sol';
import './Errors.sol';
import '@openzeppelin/contracts/access/Ownable2Step.sol';
/**
* @title SwapFacade
* @notice This facade performs minReturn safety checks and holds all approves to ensure safety of all arbitrary calls
*/
contract SwapFacade is ISwapFacade, Ownable2Step {
using SafeERC20 for IERC20;
using TokenLibrary for IERC20;
address public feeCollector;
constructor(address feeCollector_) {
if (feeCollector_ == address(0)) {
revert AddressCannotBeZero();
}
feeCollector = feeCollector_;
}
/// @notice Performs tokens swap
/// @param executor Address of low level executor used to make actual swaps
/// @param amount Amount of source tokens user is willing to swap
/// @param minReturns Minimal amount of targetToken that user is willing to receive. If not reached transaction reverts
/// @param targetTokenTransferInfos instructions on how to transfer tokens to target addresses
/// @param deadline Safety parameter against stalled transactions. If deadline reached swap reverts unconditionally
/// @param swapDescriptions Descriptions that describe how exactly swaps should be performed
/// @param permit Signed permit for spending `amount` of tokens. Optional. May be used instead of manually approving tokens before calling `swap`
function swap(
ISwapExecutor executor,
uint256 amount,
MinReturnInfo[] calldata minReturns,
ISwapExecutor.TokenTransferInfo[] calldata targetTokenTransferInfos,
uint256 deadline,
ISwapExecutor.SwapDescription[] calldata swapDescriptions,
bytes calldata permit
) external payable override returns (uint256[] memory swappedAmounts) {
{
// solhint-disable-next-line not-rely-on-time
if (deadline < block.timestamp) {
// solhint-disable-next-line not-rely-on-time
revert TransactionExpired(deadline, block.timestamp);
}
}
if (amount == 0) {
revert ZeroInput();
}
for (uint256 i = 0; i < targetTokenTransferInfos.length; i++) {
if (targetTokenTransferInfos[i].recipient == address(0)) {
revert ZeroRecipient();
}
}
if (swapDescriptions.length == 0) {
revert EmptySwap();
}
uint256 collectedFees;
if (msg.value > 0) {
if (msg.value != amount) {
revert EthValueAmountMismatch();
} else if (permit.length > 0) {
revert PermitNotAllowedForEthSwap();
} else if (!TokenLibrary.isEth(swapDescriptions[0].sourceToken)) {
revert EthValueSourceTokenMismatch();
}
collectedFees = address(feeCollector).balance;
} else {
if (
swapDescriptions[0].sourceToken.balanceOf(address(executor)) <
amount
) {
if (permit.length > 0) {
SafeERC20.tryPermit(
swapDescriptions[0].sourceToken,
permit
);
}
swapDescriptions[0].sourceToken.safeTransferFrom(
msg.sender,
address(executor),
amount
);
}
collectedFees = swapDescriptions[0].sourceToken.balanceOf(
feeCollector
);
}
swappedAmounts = _swap(
executor,
minReturns,
targetTokenTransferInfos,
swapDescriptions
);
if (msg.value > 0) {
collectedFees = address(feeCollector).balance - collectedFees;
} else {
collectedFees =
swapDescriptions[0].sourceToken.balanceOf(feeCollector) -
collectedFees;
}
if (swappedAmounts.length != 1) {
revert MultiSwapNotAllowed();
}
emit Trade(
msg.sender,
address(swapDescriptions[0].sourceToken),
address(minReturns[0].token),
amount,
swappedAmounts[0],
collectedFees
);
return swappedAmounts;
}
/// @notice Performs tokens swap and validates swap success against minReturn value
function _swap(
ISwapExecutor executor,
MinReturnInfo[] calldata minReturns,
ISwapExecutor.TokenTransferInfo[] calldata targetTokenTransferInfos,
ISwapExecutor.SwapDescription[] calldata swapDescriptions
) private returns (uint256[] memory) {
uint256[] memory balancesBeforeSwap = new uint256[](minReturns.length);
for (uint256 i = 0; i < minReturns.length; i++) {
balancesBeforeSwap[i] = minReturns[i].token.universalBalanceOf(
minReturns[i].recipient
);
}
executor.executeSwap{value: msg.value}(
targetTokenTransferInfos,
swapDescriptions
);
uint256[] memory swappedAmounts = new uint256[](minReturns.length);
for (uint256 i = 0; i < minReturns.length; i++) {
uint256 balanceBeforeSwap = balancesBeforeSwap[i];
uint256 balanceAfterSwap = minReturns[i].token.universalBalanceOf(
minReturns[i].recipient
);
uint256 totalSwappedAmount = balanceAfterSwap - balanceBeforeSwap;
if (totalSwappedAmount < minReturns[i].amount) {
revert MinReturnError(totalSwappedAmount, minReturns[i].amount);
}
swappedAmounts[i] = totalSwappedAmount;
}
return swappedAmounts;
}
function sweep(IERC20 token, address destination) external onlyOwner {
token.safeTransfer(destination, IERC20(token).balanceOf(address(this)));
}
function updateFeeCollector(address newFeeCollector) external onlyOwner {
if (newFeeCollector == address(0)) {
revert AddressCannotBeZero();
}
feeCollector = newFeeCollector;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IDaiLikePermit {
function permit(
address holder,
address spender,
uint256 nonce,
uint256 expiry,
bool allowed,
uint8 v,
bytes32 r,
bytes32 s
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IPermit2 {
struct PermitDetails {
// ERC20 token address
address token;
// the maximum amount allowed to spend
uint160 amount;
// timestamp at which a spender's token allowances become invalid
uint48 expiration;
// an incrementing value indexed per owner,token,and spender for each signature
uint48 nonce;
}
/// @notice The permit message signed for a single token allownce
struct PermitSingle {
// the permit data for a single token alownce
PermitDetails details;
// address permissioned on the allowed tokens
address spender;
// deadline on the permit signature
uint256 sigDeadline;
}
/// @notice Packed allowance
struct PackedAllowance {
// amount allowed
uint160 amount;
// permission expiry
uint48 expiration;
// an incrementing value indexed per owner,token,and spender for each signature
uint48 nonce;
}
function transferFrom(address user, address spender, uint160 amount, address token) external;
function permit(address owner, PermitSingle memory permitSingle, bytes calldata signature) external;
function allowance(address user, address token, address spender) external view returns (PackedAllowance memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IWETH is IERC20 {
event Deposit(address indexed dst, uint256 wad);
event Withdrawal(address indexed src, uint256 wad);
function deposit() external payable;
function withdraw(uint256 amount) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title Revert reason forwarder.
library RevertReasonForwarder {
/// @dev Forwards latest externall call revert.
function reRevert() internal pure {
// bubble up revert reason from latest external call
assembly ("memory-safe") { // solhint-disable-line no-inline-assembly
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
}
/// @dev Returns latest external call revert reason.
function reReason() internal pure returns (bytes memory reason) {
assembly ("memory-safe") { // solhint-disable-line no-inline-assembly
reason := mload(0x40)
let length := returndatasize()
mstore(reason, length)
returndatacopy(add(reason, 0x20), 0, length)
mstore(0x40, add(reason, add(0x20, length)))
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";
import "../interfaces/IDaiLikePermit.sol";
import "../interfaces/IPermit2.sol";
import "../interfaces/IWETH.sol";
import "../libraries/RevertReasonForwarder.sol";
/**
* @title Implements efficient safe methods for ERC20 interface.
* @notice Compared to the standard ERC20, this implementation offers several enhancements:
* 1. more gas-efficient, providing significant savings in transaction costs.
* 2. support for different permit implementations
* 3. forceApprove functionality
* 4. support for WETH deposit and withdraw
*/
library SafeERC20 {
error SafeTransferFailed();
error SafeTransferFromFailed();
error ForceApproveFailed();
error SafeIncreaseAllowanceFailed();
error SafeDecreaseAllowanceFailed();
error SafePermitBadLength();
error Permit2TransferAmountTooHigh();
// Uniswap Permit2 address
address private constant _PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
bytes4 private constant _PERMIT_LENGTH_ERROR = 0x68275857; // SafePermitBadLength.selector
uint256 private constant _RAW_CALL_GAS_LIMIT = 5000;
/**
* @notice Fetches the balance of a specific ERC20 token held by an account.
* Consumes less gas then regular `ERC20.balanceOf`.
* @param token The IERC20 token contract for which the balance will be fetched.
* @param account The address of the account whose token balance will be fetched.
* @return tokenBalance The balance of the specified ERC20 token held by the account.
*/
function safeBalanceOf(
IERC20 token,
address account
) internal view returns(uint256 tokenBalance) {
bytes4 selector = IERC20.balanceOf.selector;
assembly ("memory-safe") { // solhint-disable-line no-inline-assembly
mstore(0x00, selector)
mstore(0x04, account)
let success := staticcall(gas(), token, 0x00, 0x24, 0x00, 0x20)
tokenBalance := mload(0)
if or(iszero(success), lt(returndatasize(), 0x20)) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
}
}
/**
* @notice Attempts to safely transfer tokens from one address to another.
* @dev If permit2 is true, uses the Permit2 standard; otherwise uses the standard ERC20 transferFrom.
* Either requires `true` in return data, or requires target to be smart-contract and empty return data.
* @param token The IERC20 token contract from which the tokens will be transferred.
* @param from The address from which the tokens will be transferred.
* @param to The address to which the tokens will be transferred.
* @param amount The amount of tokens to transfer.
* @param permit2 If true, uses the Permit2 standard for the transfer; otherwise uses the standard ERC20 transferFrom.
*/
function safeTransferFromUniversal(
IERC20 token,
address from,
address to,
uint256 amount,
bool permit2
) internal {
if (permit2) {
safeTransferFromPermit2(token, from, to, amount);
} else {
safeTransferFrom(token, from, to, amount);
}
}
/**
* @notice Attempts to safely transfer tokens from one address to another using the ERC20 standard.
* @dev Either requires `true` in return data, or requires target to be smart-contract and empty return data.
* @param token The IERC20 token contract from which the tokens will be transferred.
* @param from The address from which the tokens will be transferred.
* @param to The address to which the tokens will be transferred.
* @param amount The amount of tokens to transfer.
*/
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 amount
) internal {
bytes4 selector = token.transferFrom.selector;
bool success;
assembly ("memory-safe") { // solhint-disable-line no-inline-assembly
let data := mload(0x40)
mstore(data, selector)
mstore(add(data, 0x04), from)
mstore(add(data, 0x24), to)
mstore(add(data, 0x44), amount)
success := call(gas(), token, 0, data, 100, 0x0, 0x20)
if success {
switch returndatasize()
case 0 {
success := gt(extcodesize(token), 0)
}
default {
success := and(gt(returndatasize(), 31), eq(mload(0), 1))
}
}
}
if (!success) revert SafeTransferFromFailed();
}
/**
* @notice Attempts to safely transfer tokens from one address to another using the Permit2 standard.
* @dev Either requires `true` in return data, or requires target to be smart-contract and empty return data.
* @param token The IERC20 token contract from which the tokens will be transferred.
* @param from The address from which the tokens will be transferred.
* @param to The address to which the tokens will be transferred.
* @param amount The amount of tokens to transfer.
*/
function safeTransferFromPermit2(
IERC20 token,
address from,
address to,
uint256 amount
) internal {
if (amount > type(uint160).max) revert Permit2TransferAmountTooHigh();
bytes4 selector = IPermit2.transferFrom.selector;
bool success;
assembly ("memory-safe") { // solhint-disable-line no-inline-assembly
let data := mload(0x40)
mstore(data, selector)
mstore(add(data, 0x04), from)
mstore(add(data, 0x24), to)
mstore(add(data, 0x44), amount)
mstore(add(data, 0x64), token)
success := call(gas(), _PERMIT2, 0, data, 0x84, 0x0, 0x0)
if success {
success := gt(extcodesize(_PERMIT2), 0)
}
}
if (!success) revert SafeTransferFromFailed();
}
/**
* @notice Attempts to safely transfer tokens to another address.
* @dev Either requires `true` in return data, or requires target to be smart-contract and empty return data.
* @param token The IERC20 token contract from which the tokens will be transferred.
* @param to The address to which the tokens will be transferred.
* @param value The amount of tokens to transfer.
*/
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
if (!_makeCall(token, token.transfer.selector, to, value)) {
revert SafeTransferFailed();
}
}
/**
* @notice Attempts to approve a spender to spend a certain amount of tokens.
* @dev If `approve(from, to, amount)` fails, it tries to set the allowance to zero, and retries the `approve` call.
* @param token The IERC20 token contract on which the call will be made.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
*/
function forceApprove(
IERC20 token,
address spender,
uint256 value
) internal {
if (!_makeCall(token, token.approve.selector, spender, value)) {
if (
!_makeCall(token, token.approve.selector, spender, 0) ||
!_makeCall(token, token.approve.selector, spender, value)
) {
revert ForceApproveFailed();
}
}
}
/**
* @notice Safely increases the allowance of a spender.
* @dev Increases with safe math check. Checks if the increased allowance will overflow, if yes, then it reverts the transaction.
* Then uses `forceApprove` to increase the allowance.
* @param token The IERC20 token contract on which the call will be made.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to increase the allowance by.
*/
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 allowance = token.allowance(address(this), spender);
if (value > type(uint256).max - allowance) revert SafeIncreaseAllowanceFailed();
forceApprove(token, spender, allowance + value);
}
/**
* @notice Safely decreases the allowance of a spender.
* @dev Decreases with safe math check. Checks if the decreased allowance will underflow, if yes, then it reverts the transaction.
* Then uses `forceApprove` to increase the allowance.
* @param token The IERC20 token contract on which the call will be made.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to decrease the allowance by.
*/
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 allowance = token.allowance(address(this), spender);
if (value > allowance) revert SafeDecreaseAllowanceFailed();
forceApprove(token, spender, allowance - value);
}
/**
* @notice Attempts to execute the `permit` function on the provided token with the sender and contract as parameters.
* Permit type is determined automatically based on permit calldata (IERC20Permit, IDaiLikePermit, and IPermit2).
* @dev Wraps `tryPermit` function and forwards revert reason if permit fails.
* @param token The IERC20 token to execute the permit function on.
* @param permit The permit data to be used in the function call.
*/
function safePermit(IERC20 token, bytes calldata permit) internal {
if (!tryPermit(token, msg.sender, address(this), permit)) RevertReasonForwarder.reRevert();
}
/**
* @notice Attempts to execute the `permit` function on the provided token with custom owner and spender parameters.
* Permit type is determined automatically based on permit calldata (IERC20Permit, IDaiLikePermit, and IPermit2).
* @dev Wraps `tryPermit` function and forwards revert reason if permit fails.
* @param token The IERC20 token to execute the permit function on.
* @param owner The owner of the tokens for which the permit is made.
* @param spender The spender allowed to spend the tokens by the permit.
* @param permit The permit data to be used in the function call.
*/
function safePermit(IERC20 token, address owner, address spender, bytes calldata permit) internal {
if (!tryPermit(token, owner, spender, permit)) RevertReasonForwarder.reRevert();
}
/**
* @notice Attempts to execute the `permit` function on the provided token with the sender and contract as parameters.
* @dev Invokes `tryPermit` with sender as owner and contract as spender.
* @param token The IERC20 token to execute the permit function on.
* @param permit The permit data to be used in the function call.
* @return success Returns true if the permit function was successfully executed, false otherwise.
*/
function tryPermit(IERC20 token, bytes calldata permit) internal returns(bool success) {
return tryPermit(token, msg.sender, address(this), permit);
}
/**
* @notice The function attempts to call the permit function on a given ERC20 token.
* @dev The function is designed to support a variety of permit functions, namely: IERC20Permit, IDaiLikePermit, and IPermit2.
* It accommodates both Compact and Full formats of these permit types.
* Please note, it is expected that the `expiration` parameter for the compact Permit2 and the `deadline` parameter
* for the compact Permit are to be incremented by one before invoking this function. This approach is motivated by
* gas efficiency considerations; as the unlimited expiration period is likely to be the most common scenario, and
* zeros are cheaper to pass in terms of gas cost. Thus, callers should increment the expiration or deadline by one
* before invocation for optimized performance.
* @param token The address of the ERC20 token on which to call the permit function.
* @param owner The owner of the tokens. This address should have signed the off-chain permit.
* @param spender The address which will be approved for transfer of tokens.
* @param permit The off-chain permit data, containing different fields depending on the type of permit function.
* @return success A boolean indicating whether the permit call was successful.
*/
function tryPermit(IERC20 token, address owner, address spender, bytes calldata permit) internal returns(bool success) {
// load function selectors for different permit standards
bytes4 permitSelector = IERC20Permit.permit.selector;
bytes4 daiPermitSelector = IDaiLikePermit.permit.selector;
bytes4 permit2Selector = IPermit2.permit.selector;
assembly ("memory-safe") { // solhint-disable-line no-inline-assembly
let ptr := mload(0x40)
// Switch case for different permit lengths, indicating different permit standards
switch permit.length
// Compact IERC20Permit
case 100 {
mstore(ptr, permitSelector) // store selector
mstore(add(ptr, 0x04), owner) // store owner
mstore(add(ptr, 0x24), spender) // store spender
// Compact IERC20Permit.permit(uint256 value, uint32 deadline, uint256 r, uint256 vs)
{ // stack too deep
let deadline := shr(224, calldataload(add(permit.offset, 0x20))) // loads permit.offset 0x20..0x23
let vs := calldataload(add(permit.offset, 0x44)) // loads permit.offset 0x44..0x63
calldatacopy(add(ptr, 0x44), permit.offset, 0x20) // store value = copy permit.offset 0x00..0x19
mstore(add(ptr, 0x64), sub(deadline, 1)) // store deadline = deadline - 1
mstore(add(ptr, 0x84), add(27, shr(255, vs))) // store v = most significant bit of vs + 27 (27 or 28)
calldatacopy(add(ptr, 0xa4), add(permit.offset, 0x24), 0x20) // store r = copy permit.offset 0x24..0x43
mstore(add(ptr, 0xc4), shr(1, shl(1, vs))) // store s = vs without most significant bit
}
// IERC20Permit.permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
success := call(gas(), token, 0, ptr, 0xe4, 0, 0)
}
// Compact IDaiLikePermit
case 72 {
mstore(ptr, daiPermitSelector) // store selector
mstore(add(ptr, 0x04), owner) // store owner
mstore(add(ptr, 0x24), spender) // store spender
// Compact IDaiLikePermit.permit(uint32 nonce, uint32 expiry, uint256 r, uint256 vs)
{ // stack too deep
let expiry := shr(224, calldataload(add(permit.offset, 0x04))) // loads permit.offset 0x04..0x07
let vs := calldataload(add(permit.offset, 0x28)) // loads permit.offset 0x28..0x47
mstore(add(ptr, 0x44), shr(224, calldataload(permit.offset))) // store nonce = copy permit.offset 0x00..0x03
mstore(add(ptr, 0x64), sub(expiry, 1)) // store expiry = expiry - 1
mstore(add(ptr, 0x84), true) // store allowed = true
mstore(add(ptr, 0xa4), add(27, shr(255, vs))) // store v = most significant bit of vs + 27 (27 or 28)
calldatacopy(add(ptr, 0xc4), add(permit.offset, 0x08), 0x20) // store r = copy permit.offset 0x08..0x27
mstore(add(ptr, 0xe4), shr(1, shl(1, vs))) // store s = vs without most significant bit
}
// IDaiLikePermit.permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s)
success := call(gas(), token, 0, ptr, 0x104, 0, 0)
}
// IERC20Permit
case 224 {
mstore(ptr, permitSelector)
calldatacopy(add(ptr, 0x04), permit.offset, permit.length) // copy permit calldata
// IERC20Permit.permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
success := call(gas(), token, 0, ptr, 0xe4, 0, 0)
}
// IDaiLikePermit
case 256 {
mstore(ptr, daiPermitSelector)
calldatacopy(add(ptr, 0x04), permit.offset, permit.length) // copy permit calldata
// IDaiLikePermit.permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s)
success := call(gas(), token, 0, ptr, 0x104, 0, 0)
}
// Compact IPermit2
case 96 {
// Compact IPermit2.permit(uint160 amount, uint32 expiration, uint32 nonce, uint32 sigDeadline, uint256 r, uint256 vs)
mstore(ptr, permit2Selector) // store selector
mstore(add(ptr, 0x04), owner) // store owner
mstore(add(ptr, 0x24), token) // store token
calldatacopy(add(ptr, 0x50), permit.offset, 0x14) // store amount = copy permit.offset 0x00..0x13
// and(0xffffffffffff, ...) - conversion to uint48
mstore(add(ptr, 0x64), and(0xffffffffffff, sub(shr(224, calldataload(add(permit.offset, 0x14))), 1))) // store expiration = ((permit.offset 0x14..0x17 - 1) & 0xffffffffffff)
mstore(add(ptr, 0x84), shr(224, calldataload(add(permit.offset, 0x18)))) // store nonce = copy permit.offset 0x18..0x1b
mstore(add(ptr, 0xa4), spender) // store spender
// and(0xffffffffffff, ...) - conversion to uint48
mstore(add(ptr, 0xc4), and(0xffffffffffff, sub(shr(224, calldataload(add(permit.offset, 0x1c))), 1))) // store sigDeadline = ((permit.offset 0x1c..0x1f - 1) & 0xffffffffffff)
mstore(add(ptr, 0xe4), 0x100) // store offset = 256
mstore(add(ptr, 0x104), 0x40) // store length = 64
calldatacopy(add(ptr, 0x124), add(permit.offset, 0x20), 0x20) // store r = copy permit.offset 0x20..0x3f
calldatacopy(add(ptr, 0x144), add(permit.offset, 0x40), 0x20) // store vs = copy permit.offset 0x40..0x5f
// IPermit2.permit(address owner, PermitSingle calldata permitSingle, bytes calldata signature)
success := call(gas(), _PERMIT2, 0, ptr, 0x164, 0, 0)
}
// IPermit2
case 352 {
mstore(ptr, permit2Selector)
calldatacopy(add(ptr, 0x04), permit.offset, permit.length) // copy permit calldata
// IPermit2.permit(address owner, PermitSingle calldata permitSingle, bytes calldata signature)
success := call(gas(), _PERMIT2, 0, ptr, 0x164, 0, 0)
}
// Unknown
default {
mstore(ptr, _PERMIT_LENGTH_ERROR)
revert(ptr, 4)
}
}
}
/**
* @dev Executes a low level call to a token contract, making it resistant to reversion and erroneous boolean returns.
* @param token The IERC20 token contract on which the call will be made.
* @param selector The function signature that is to be called on the token contract.
* @param to The address to which the token amount will be transferred.
* @param amount The token amount to be transferred.
* @return success A boolean indicating if the call was successful. Returns 'true' on success and 'false' on failure.
* In case of success but no returned data, validates that the contract code exists.
* In case of returned data, ensures that it's a boolean `true`.
*/
function _makeCall(
IERC20 token,
bytes4 selector,
address to,
uint256 amount
) private returns (bool success) {
assembly ("memory-safe") { // solhint-disable-line no-inline-assembly
let data := mload(0x40)
mstore(data, selector)
mstore(add(data, 0x04), to)
mstore(add(data, 0x24), amount)
success := call(gas(), token, 0, data, 0x44, 0x0, 0x20)
if success {
switch returndatasize()
case 0 {
success := gt(extcodesize(token), 0)
}
default {
success := and(gt(returndatasize(), 31), eq(mload(0), 1))
}
}
}
}
/**
* @notice Safely deposits a specified amount of Ether into the IWETH contract. Consumes less gas then regular `IWETH.deposit`.
* @param weth The IWETH token contract.
* @param amount The amount of Ether to deposit into the IWETH contract.
*/
function safeDeposit(IWETH weth, uint256 amount) internal {
if (amount > 0) {
bytes4 selector = IWETH.deposit.selector;
assembly ("memory-safe") { // solhint-disable-line no-inline-assembly
mstore(0, selector)
if iszero(call(gas(), weth, amount, 0, 4, 0, 0)) {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
}
}
/**
* @notice Safely withdraws a specified amount of wrapped Ether from the IWETH contract. Consumes less gas then regular `IWETH.withdraw`.
* @dev Uses inline assembly to interact with the IWETH contract.
* @param weth The IWETH token contract.
* @param amount The amount of wrapped Ether to withdraw from the IWETH contract.
*/
function safeWithdraw(IWETH weth, uint256 amount) internal {
bytes4 selector = IWETH.withdraw.selector;
assembly ("memory-safe") { // solhint-disable-line no-inline-assembly
mstore(0, selector)
mstore(4, amount)
if iszero(call(gas(), weth, 0, 0, 0x24, 0, 0)) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
}
}
/**
* @notice Safely withdraws a specified amount of wrapped Ether from the IWETH contract to a specified recipient.
* Consumes less gas then regular `IWETH.withdraw`.
* @param weth The IWETH token contract.
* @param amount The amount of wrapped Ether to withdraw from the IWETH contract.
* @param to The recipient of the withdrawn Ether.
*/
function safeWithdrawTo(IWETH weth, uint256 amount, address to) internal {
safeWithdraw(weth, amount);
if (to != address(this)) {
assembly ("memory-safe") { // solhint-disable-line no-inline-assembly
if iszero(call(_RAW_CALL_GAS_LIMIT, to, amount, 0, 0, 0, 0)) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)
pragma solidity ^0.8.0;
import "./Ownable.sol";
/**
* @dev Contract module which provides access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership} and {acceptOwnership}.
*
* This module is used through inheritance. It will make available all functions
* from parent (Ownable).
*/
abstract contract Ownable2Step is Ownable {
address private _pendingOwner;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
/**
* @dev Returns the address of the pending owner.
*/
function pendingOwner() public view virtual returns (address) {
return _pendingOwner;
}
/**
* @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual override onlyOwner {
_pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual override {
delete _pendingOwner;
super._transferOwnership(newOwner);
}
/**
* @dev The new owner accepts the ownership transfer.
*/
function acceptOwnership() public virtual {
address sender = _msgSender();
require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner");
_transferOwnership(sender);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
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 amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` 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 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
pragma abicoder v1;
enum EnumType {
SourceTokenInteraction,
TargetTokenInteraction,
CallType
}
enum UniswapV3LikeProtocol {
Uniswap,
Kyber,
Maverick,
Pancake
}
error EthValueAmountMismatch();
error EthValueSourceTokenMismatch();
error MinReturnError(uint256, uint256);
error EmptySwapOnExecutor();
error EmptySwap();
error ZeroInput();
error ZeroRecipient();
error MultiSwapNotAllowed();
error TransactionExpired(uint256, uint256);
error PermitNotAllowedForEthSwap();
error SwapTotalAmountCannotBeZero();
error SwapAmountCannotBeZero();
error DirectEthDepositIsForbidden();
error MStableInvalidSwapType(uint256);
error AddressCannotBeZero();
error TransferFromNotAllowed();
error EnumOutOfRangeValue(EnumType, uint256);
error BadUniswapV3LikePool(UniswapV3LikeProtocol);
error ERC1820InterfactionForbidden();// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
pragma abicoder v1;
import '../Errors.sol';
/**
* @title ContractOnlyEthRecipient
* @notice Base contract that rejects any direct ethereum deposits. This is a failsafe against users who can accidentaly send ether
*/
abstract contract ContractOnlyEthRecipient {
receive() external payable {
// solhint-disable-next-line avoid-tx-origin
if (msg.sender == tx.origin) {
revert DirectEthDepositIsForbidden();
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
/**
* @title ISwapExecutor
* @notice Interface for executing low level swaps, including all relevant structs and enums
*/
interface ISwapExecutor {
struct TokenTransferInfo {
IERC20 token;
uint256 exactAmount;
address payable recipient;
}
struct TargetSwapDescription {
uint256 tokenRatio;
address target;
bytes data;
// uint8 callType; first 8 bits
// uint8 sourceInteraction; next 8 bits
// uint32 amountOffset; next 32 bits
// address sourceTokenInteractionTarget; last 160 bits
uint256 params;
}
struct SwapDescription {
IERC20 sourceToken;
TargetSwapDescription[] swaps;
}
function executeSwap(
TokenTransferInfo[] calldata targetTokenTransferInfos,
SwapDescription[] calldata swapDescriptions
) external payable;
}
uint8 constant CALL_TYPE_DIRECT = 0;
uint8 constant CALL_TYPE_CALCULATED = 1;
uint8 constant SOURCE_TOKEN_INTERACTION_NONE = 0;
uint8 constant SOURCE_TOKEN_INTERACTION_TRANSFER = 1;
uint8 constant SOURCE_TOKEN_INTERACTION_APPROVE = 2;// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
import './ISwapExecutor.sol';
/**
* @title ISwapFacade
* @notice Interface for the Facade contract of the aggregator.
*/
interface ISwapFacade {
struct MinReturnInfo {
IERC20 token;
uint256 amount;
address recipient;
}
event Trade(
address trader,
address srcToken,
address dstToken,
uint256 srcTokenAmount,
uint256 dstTokenAmount,
uint256 fees
);
function swap(
ISwapExecutor executor,
uint256 amount,
MinReturnInfo[] calldata minReturns,
ISwapExecutor.TokenTransferInfo[] calldata targetTokenTransferInfos,
uint256 deadline,
ISwapExecutor.SwapDescription[] calldata swapDescriptions,
bytes calldata permit
) external payable returns (uint256[] memory);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
pragma abicoder v1;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@1inch/solidity-utils/contracts/libraries/SafeERC20.sol';
/**
* @title TokenLibrary
* @notice Library for basic interactions with tokens (such as deposits, withdrawals, transfers)
*/
library TokenLibrary {
using SafeERC20 for IERC20;
function isEth(IERC20 token) internal pure returns (bool) {
return
address(token) == address(0) ||
address(token) ==
address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
}
function universalBalanceOf(
IERC20 token,
address account
) internal view returns (uint256) {
if (isEth(token)) {
return account.balance;
} else {
return token.balanceOf(account);
}
}
function universalTransfer(
IERC20 token,
address payable to,
uint256 amount
) internal {
if (amount == 0) {
return;
}
if (isEth(token)) {
to.transfer(amount);
} else {
token.safeTransfer(to, amount);
}
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"feeCollector_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressCannotBeZero","type":"error"},{"inputs":[],"name":"EmptySwap","type":"error"},{"inputs":[],"name":"EthValueAmountMismatch","type":"error"},{"inputs":[],"name":"EthValueSourceTokenMismatch","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"MinReturnError","type":"error"},{"inputs":[],"name":"MultiSwapNotAllowed","type":"error"},{"inputs":[],"name":"PermitNotAllowedForEthSwap","type":"error"},{"inputs":[],"name":"SafeTransferFailed","type":"error"},{"inputs":[],"name":"SafeTransferFromFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"TransactionExpired","type":"error"},{"inputs":[],"name":"ZeroInput","type":"error"},{"inputs":[],"name":"ZeroRecipient","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"trader","type":"address"},{"indexed":false,"internalType":"address","name":"srcToken","type":"address"},{"indexed":false,"internalType":"address","name":"dstToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"srcTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dstTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fees","type":"uint256"}],"name":"Trade","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISwapExecutor","name":"executor","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"internalType":"struct ISwapFacade.MinReturnInfo[]","name":"minReturns","type":"tuple[]"},{"components":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"exactAmount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ISwapExecutor.TokenTransferInfo[]","name":"targetTokenTransferInfos","type":"tuple[]"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"components":[{"internalType":"contract IERC20","name":"sourceToken","type":"address"},{"components":[{"internalType":"uint256","name":"tokenRatio","type":"uint256"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"params","type":"uint256"}],"internalType":"struct ISwapExecutor.TargetSwapDescription[]","name":"swaps","type":"tuple[]"}],"internalType":"struct ISwapExecutor.SwapDescription[]","name":"swapDescriptions","type":"tuple[]"},{"internalType":"bytes","name":"permit","type":"bytes"}],"name":"swap","outputs":[{"internalType":"uint256[]","name":"swappedAmounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"destination","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newFeeCollector","type":"address"}],"name":"updateFeeCollector","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b50604051620017bf380380620017bf833981016040819052620000349162000107565b6200003f336200008d565b6001600160a01b03811662000067576040516303988b8160e61b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b039290921691909117905562000139565b600180546001600160a01b0319169055620000b481620000b7602090811b6200090417901c565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156200011a57600080fd5b81516001600160a01b03811681146200013257600080fd5b9392505050565b61167680620001496000396000f3fe6080604052600436106100865760003560e01c8063c415b95c11610059578063c415b95c1461010e578063d2c35ce81461012e578063e30c39781461014e578063f0d7bb941461016c578063f2fde38b1461018c57600080fd5b8063715018a61461008b57806379ba5097146100a25780638da5cb5b146100b7578063b8dc491b146100ee575b600080fd5b34801561009757600080fd5b506100a06101ac565b005b3480156100ae57600080fd5b506100a06101c0565b3480156100c357600080fd5b506000546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100fa57600080fd5b506100a06101093660046110ca565b61023f565b34801561011a57600080fd5b506002546100d1906001600160a01b031681565b34801561013a57600080fd5b506100a0610149366004611103565b6102ca565b34801561015a57600080fd5b506001546001600160a01b03166100d1565b61017f61017a36600461120a565b61031b565b6040516100e591906112f9565b34801561019857600080fd5b506100a06101a7366004611103565b610893565b6101b4610954565b6101be60006109ae565b565b60015433906001600160a01b031681146102335760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b61023c816109ae565b50565b610247610954565b6040516370a0823160e01b81523060048201526102c69082906001600160a01b038516906370a0823190602401602060405180830381865afa158015610291573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b5919061133d565b6001600160a01b03851691906109c7565b5050565b6102d2610954565b6001600160a01b0381166102f9576040516303988b8160e61b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6060428610156103475760405163300249d760e01b81526004810187905242602482015260440161022a565b8a6000036103685760405163af458c0760e01b815260040160405180910390fd5b60005b878110156103d857600089898381811061038757610387611356565b905060600201604001602081019061039f9190611103565b6001600160a01b0316036103c65760405163d27b444360e01b815260040160405180910390fd5b806103d081611382565b91505061036b565b5060008490036103fb5760405163b494d17560e01b815260040160405180910390fd5b600034156104ad578b34146104235760405163178ee1ed60e21b815260040160405180910390fd5b82156104425760405163283e650d60e01b815260040160405180910390fd5b61047d8686600081811061045857610458611356565b905060200281019061046a919061139b565b610478906020810190611103565b6109fc565b61049a57604051632b27b8bb60e01b815260040160405180910390fd5b506002546001600160a01b031631610694565b8b868660008181106104c1576104c1611356565b90506020028101906104d3919061139b565b6104e1906020810190611103565b6001600160a01b03166370a082318f6040518263ffffffff1660e01b815260040161051b91906001600160a01b0391909116815260200190565b602060405180830381865afa158015610538573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061055c919061133d565b10156105f15782156105a7576105a58686600081811061057e5761057e611356565b9050602002810190610590919061139b565b61059e906020810190611103565b8585610a36565b505b6105f1338e8e898960008181106105c0576105c0611356565b90506020028101906105d2919061139b565b6105e0906020810190611103565b6001600160a01b0316929190610a4d565b8585600081811061060457610604611356565b9050602002810190610616919061139b565b610624906020810190611103565b6002546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa15801561066d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610691919061133d565b90505b6106a38d8c8c8c8c8b8b610ad1565b915034156106ca576002546106c39082906001600160a01b0316316113bb565b9050610778565b80868660008181106106de576106de611356565b90506020028101906106f0919061139b565b6106fe906020810190611103565b6002546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015610747573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076b919061133d565b61077591906113bb565b90505b815160011461079a57604051636676835160e01b815260040160405180910390fd5b7f4a2af5744adbfadba82ab831aea212bad92f5a70fef2079562044f423e99985133878760008181106107cf576107cf611356565b90506020028101906107e1919061139b565b6107ef906020810190611103565b8d8d600081811061080257610802611356565b6108189260206060909202019081019150611103565b8f8660008151811061082c5761082c611356565b60200260200101518660405161087b969594939291906001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925260a081019190915260c00190565b60405180910390a1509b9a5050505050505050505050565b61089b610954565b600180546001600160a01b0383166001600160a01b031990911681179091556108cc6000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b031633146101be5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161022a565b600180546001600160a01b031916905561023c81610904565b6109da8363a9059cbb60e01b8484610d89565b6109f75760405163fb7f507960e01b815260040160405180910390fd5b505050565b60006001600160a01b0382161580610a3057506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b92915050565b6000610a458433308686610ddc565b949350505050565b60006323b872dd60e01b905060006040518281528560048201528460248201528360448201526020600060648360008b5af19150508015610aab573d8015610aa157600160005114601f3d11169150610aa9565b6000873b1191505b505b80610ac95760405163f405907160e01b815260040160405180910390fd5b505050505050565b606060008667ffffffffffffffff811115610aee57610aee6113ce565b604051908082528060200260200182016040528015610b17578160200160208202803683370190505b50905060005b87811015610bb857610b89898983818110610b3a57610b3a611356565b9050606002016040016020810190610b529190611103565b8a8a84818110610b6457610b64611356565b610b7a9260206060909202019081019150611103565b6001600160a01b031690611023565b828281518110610b9b57610b9b611356565b602090810291909101015280610bb081611382565b915050610b1d565b506040516392b1274560e01b81526001600160a01b038a16906392b12745903490610bed908a908a908a908a9060040161140d565b6000604051808303818588803b158015610c0657600080fd5b505af1158015610c1a573d6000803e3d6000fd5b50600093508a9250505067ffffffffffffffff811115610c3c57610c3c6113ce565b604051908082528060200260200182016040528015610c65578160200160208202803683370190505b50905060005b88811015610d7b576000838281518110610c8757610c87611356565b602002602001015190506000610cd28c8c85818110610ca857610ca8611356565b9050606002016040016020810190610cc09190611103565b8d8d86818110610b6457610b64611356565b90506000610ce083836113bb565b90508c8c85818110610cf457610cf4611356565b90506060020160200135811015610d4657808d8d86818110610d1857610d18611356565b9050606002016020013560405163321f864360e11b815260040161022a929190918252602082015260400190565b80858581518110610d5957610d59611356565b6020026020010181815250505050508080610d7390611382565b915050610c6b565b509998505050505050505050565b60006040518481528360048201528260248201526020600060448360008a5af19150508015610a45573d8015610dcb57600160005114601f3d11169150610dd3565b6000863b1191505b50949350505050565b60405160009063d505accf60e01b906323f2ebc360e21b906302b67b5760e41b908560648114610e3f5760488114610ea35760e08114610f11576101008114610f2d5760608114610f4a576101608114610fed57636827585760e01b8252600482fd5b848252896004830152886024830152602088013560e01c604489013560208a60448601376001820360648501528060ff1c601b016084850152602060248b0160a48601376001600160ff1b031660c48401525060008060e484828f5af19550611015565b838252896004830152886024830152600488013560e01c6028890135893560e01c6044850152600182036064850152600160848501528060ff1c601b0160a4850152602060088b0160c48601376001600160ff1b031660e48401525060008061010484828f5af19550611015565b8482528688600484013760008060e48460008f5af19550611015565b838252868860048401376000806101048460008f5af19550611015565b8282528960048301528a602483015260148860508401376001601489013560e01c0365ffffffffffff166064830152601888013560e01c60848301528860a48301526001601c89013560e01c0365ffffffffffff1660c483015261010060e4830152604061010483015260208089016101248401376020604089016101448401376000806101648460006e22d473030f116ddee9f6b43ac78ba35af19550611015565b828252868860048401376000806101648460006e22d473030f116ddee9f6b43ac78ba35af195505b505050505095945050505050565b600061102e836109fc565b1561104457506001600160a01b03811631610a30565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381865afa158015611096573d6000803e3d6000fd5b505050506040513d60208110156110ac57600080fd5b50519392505050565b6001600160a01b038116811461023c57600080fd5b600080604083850312156110dd57600080fd5b82356110e8816110b5565b915060208301356110f8816110b5565b809150509250929050565b60006020828403121561111557600080fd5b8135611120816110b5565b9392505050565b8035611132816110b5565b919050565b60008083601f84011261114957600080fd5b50813567ffffffffffffffff81111561116157600080fd5b60208301915083602060608302850101111561117c57600080fd5b9250929050565b60008083601f84011261119557600080fd5b50813567ffffffffffffffff8111156111ad57600080fd5b6020830191508360208260051b850101111561117c57600080fd5b60008083601f8401126111da57600080fd5b50813567ffffffffffffffff8111156111f257600080fd5b60208301915083602082850101111561117c57600080fd5b600080600080600080600080600080600060e08c8e03121561122b57600080fd5b6112348c611127565b9a5060208c0135995067ffffffffffffffff8060408e0135111561125757600080fd5b6112678e60408f01358f01611137565b909a50985060608d013581101561127d57600080fd5b61128d8e60608f01358f01611137565b909850965060808d0135955060a08d01358110156112aa57600080fd5b6112ba8e60a08f01358f01611183565b909550935060c08d01358110156112d057600080fd5b506112e18d60c08e01358e016111c8565b81935080925050509295989b509295989b9093969950565b6020808252825182820181905260009190848201906040850190845b8181101561133157835183529284019291840191600101611315565b50909695505050505050565b60006020828403121561134f57600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016113945761139461136c565b5060010190565b60008235603e198336030181126113b157600080fd5b9190910192915050565b81810381811115610a3057610a3061136c565b634e487b7160e01b600052604160045260246000fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6040808252810184905260006060820186825b878110156114765761143282356110b5565b6001600160a01b038235811684526020808401359085015261145760408401356110b5565b6040838101359091169084015260609283019290910190600101611420565b505082810360208401528084825260208201905060208560051b8301018660005b8781101561163157848303601f19018452603e19368a900381018335126114bd57600080fd5b898335016114cb81356110b5565b6001600160a01b03813581168652601e1936839003016020830135126114f057600080fd5b816020830135019150813567ffffffffffffffff8082111561151157600080fd5b8160051b360360208501131561152657600080fd5b604060208901526040880182815260608901905060608360051b8a0101602086016000609e19883603015b8682101561160d57605f198d85030185528083351261156f57600080fd5b888335016020810135855261158760408201356110b5565b88604082013516602086015260608101358b8236030181126115a857600080fd5b8101604081019060200135888111156115c057600080fd5b8036038213156115cf57600080fd5b608060408801526115e46080880182846113e4565b915050608082013560608701528095505050602083019250602085019450600182019150611551565b50505080995050505050505050602082019150602084019350600181019050611497565b5090999850505050505050505056fea26469706673582212203eb045697eb7920001ef411587efa4c3a72293336d02227a14586d08f25ec6b164736f6c634300081200330000000000000000000000009cd4f98c93f94ff13af96d2f3550418cce8418c0
Deployed Bytecode
0x6080604052600436106100865760003560e01c8063c415b95c11610059578063c415b95c1461010e578063d2c35ce81461012e578063e30c39781461014e578063f0d7bb941461016c578063f2fde38b1461018c57600080fd5b8063715018a61461008b57806379ba5097146100a25780638da5cb5b146100b7578063b8dc491b146100ee575b600080fd5b34801561009757600080fd5b506100a06101ac565b005b3480156100ae57600080fd5b506100a06101c0565b3480156100c357600080fd5b506000546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100fa57600080fd5b506100a06101093660046110ca565b61023f565b34801561011a57600080fd5b506002546100d1906001600160a01b031681565b34801561013a57600080fd5b506100a0610149366004611103565b6102ca565b34801561015a57600080fd5b506001546001600160a01b03166100d1565b61017f61017a36600461120a565b61031b565b6040516100e591906112f9565b34801561019857600080fd5b506100a06101a7366004611103565b610893565b6101b4610954565b6101be60006109ae565b565b60015433906001600160a01b031681146102335760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b61023c816109ae565b50565b610247610954565b6040516370a0823160e01b81523060048201526102c69082906001600160a01b038516906370a0823190602401602060405180830381865afa158015610291573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b5919061133d565b6001600160a01b03851691906109c7565b5050565b6102d2610954565b6001600160a01b0381166102f9576040516303988b8160e61b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6060428610156103475760405163300249d760e01b81526004810187905242602482015260440161022a565b8a6000036103685760405163af458c0760e01b815260040160405180910390fd5b60005b878110156103d857600089898381811061038757610387611356565b905060600201604001602081019061039f9190611103565b6001600160a01b0316036103c65760405163d27b444360e01b815260040160405180910390fd5b806103d081611382565b91505061036b565b5060008490036103fb5760405163b494d17560e01b815260040160405180910390fd5b600034156104ad578b34146104235760405163178ee1ed60e21b815260040160405180910390fd5b82156104425760405163283e650d60e01b815260040160405180910390fd5b61047d8686600081811061045857610458611356565b905060200281019061046a919061139b565b610478906020810190611103565b6109fc565b61049a57604051632b27b8bb60e01b815260040160405180910390fd5b506002546001600160a01b031631610694565b8b868660008181106104c1576104c1611356565b90506020028101906104d3919061139b565b6104e1906020810190611103565b6001600160a01b03166370a082318f6040518263ffffffff1660e01b815260040161051b91906001600160a01b0391909116815260200190565b602060405180830381865afa158015610538573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061055c919061133d565b10156105f15782156105a7576105a58686600081811061057e5761057e611356565b9050602002810190610590919061139b565b61059e906020810190611103565b8585610a36565b505b6105f1338e8e898960008181106105c0576105c0611356565b90506020028101906105d2919061139b565b6105e0906020810190611103565b6001600160a01b0316929190610a4d565b8585600081811061060457610604611356565b9050602002810190610616919061139b565b610624906020810190611103565b6002546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa15801561066d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610691919061133d565b90505b6106a38d8c8c8c8c8b8b610ad1565b915034156106ca576002546106c39082906001600160a01b0316316113bb565b9050610778565b80868660008181106106de576106de611356565b90506020028101906106f0919061139b565b6106fe906020810190611103565b6002546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015610747573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076b919061133d565b61077591906113bb565b90505b815160011461079a57604051636676835160e01b815260040160405180910390fd5b7f4a2af5744adbfadba82ab831aea212bad92f5a70fef2079562044f423e99985133878760008181106107cf576107cf611356565b90506020028101906107e1919061139b565b6107ef906020810190611103565b8d8d600081811061080257610802611356565b6108189260206060909202019081019150611103565b8f8660008151811061082c5761082c611356565b60200260200101518660405161087b969594939291906001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925260a081019190915260c00190565b60405180910390a1509b9a5050505050505050505050565b61089b610954565b600180546001600160a01b0383166001600160a01b031990911681179091556108cc6000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b031633146101be5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161022a565b600180546001600160a01b031916905561023c81610904565b6109da8363a9059cbb60e01b8484610d89565b6109f75760405163fb7f507960e01b815260040160405180910390fd5b505050565b60006001600160a01b0382161580610a3057506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b92915050565b6000610a458433308686610ddc565b949350505050565b60006323b872dd60e01b905060006040518281528560048201528460248201528360448201526020600060648360008b5af19150508015610aab573d8015610aa157600160005114601f3d11169150610aa9565b6000873b1191505b505b80610ac95760405163f405907160e01b815260040160405180910390fd5b505050505050565b606060008667ffffffffffffffff811115610aee57610aee6113ce565b604051908082528060200260200182016040528015610b17578160200160208202803683370190505b50905060005b87811015610bb857610b89898983818110610b3a57610b3a611356565b9050606002016040016020810190610b529190611103565b8a8a84818110610b6457610b64611356565b610b7a9260206060909202019081019150611103565b6001600160a01b031690611023565b828281518110610b9b57610b9b611356565b602090810291909101015280610bb081611382565b915050610b1d565b506040516392b1274560e01b81526001600160a01b038a16906392b12745903490610bed908a908a908a908a9060040161140d565b6000604051808303818588803b158015610c0657600080fd5b505af1158015610c1a573d6000803e3d6000fd5b50600093508a9250505067ffffffffffffffff811115610c3c57610c3c6113ce565b604051908082528060200260200182016040528015610c65578160200160208202803683370190505b50905060005b88811015610d7b576000838281518110610c8757610c87611356565b602002602001015190506000610cd28c8c85818110610ca857610ca8611356565b9050606002016040016020810190610cc09190611103565b8d8d86818110610b6457610b64611356565b90506000610ce083836113bb565b90508c8c85818110610cf457610cf4611356565b90506060020160200135811015610d4657808d8d86818110610d1857610d18611356565b9050606002016020013560405163321f864360e11b815260040161022a929190918252602082015260400190565b80858581518110610d5957610d59611356565b6020026020010181815250505050508080610d7390611382565b915050610c6b565b509998505050505050505050565b60006040518481528360048201528260248201526020600060448360008a5af19150508015610a45573d8015610dcb57600160005114601f3d11169150610dd3565b6000863b1191505b50949350505050565b60405160009063d505accf60e01b906323f2ebc360e21b906302b67b5760e41b908560648114610e3f5760488114610ea35760e08114610f11576101008114610f2d5760608114610f4a576101608114610fed57636827585760e01b8252600482fd5b848252896004830152886024830152602088013560e01c604489013560208a60448601376001820360648501528060ff1c601b016084850152602060248b0160a48601376001600160ff1b031660c48401525060008060e484828f5af19550611015565b838252896004830152886024830152600488013560e01c6028890135893560e01c6044850152600182036064850152600160848501528060ff1c601b0160a4850152602060088b0160c48601376001600160ff1b031660e48401525060008061010484828f5af19550611015565b8482528688600484013760008060e48460008f5af19550611015565b838252868860048401376000806101048460008f5af19550611015565b8282528960048301528a602483015260148860508401376001601489013560e01c0365ffffffffffff166064830152601888013560e01c60848301528860a48301526001601c89013560e01c0365ffffffffffff1660c483015261010060e4830152604061010483015260208089016101248401376020604089016101448401376000806101648460006e22d473030f116ddee9f6b43ac78ba35af19550611015565b828252868860048401376000806101648460006e22d473030f116ddee9f6b43ac78ba35af195505b505050505095945050505050565b600061102e836109fc565b1561104457506001600160a01b03811631610a30565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381865afa158015611096573d6000803e3d6000fd5b505050506040513d60208110156110ac57600080fd5b50519392505050565b6001600160a01b038116811461023c57600080fd5b600080604083850312156110dd57600080fd5b82356110e8816110b5565b915060208301356110f8816110b5565b809150509250929050565b60006020828403121561111557600080fd5b8135611120816110b5565b9392505050565b8035611132816110b5565b919050565b60008083601f84011261114957600080fd5b50813567ffffffffffffffff81111561116157600080fd5b60208301915083602060608302850101111561117c57600080fd5b9250929050565b60008083601f84011261119557600080fd5b50813567ffffffffffffffff8111156111ad57600080fd5b6020830191508360208260051b850101111561117c57600080fd5b60008083601f8401126111da57600080fd5b50813567ffffffffffffffff8111156111f257600080fd5b60208301915083602082850101111561117c57600080fd5b600080600080600080600080600080600060e08c8e03121561122b57600080fd5b6112348c611127565b9a5060208c0135995067ffffffffffffffff8060408e0135111561125757600080fd5b6112678e60408f01358f01611137565b909a50985060608d013581101561127d57600080fd5b61128d8e60608f01358f01611137565b909850965060808d0135955060a08d01358110156112aa57600080fd5b6112ba8e60a08f01358f01611183565b909550935060c08d01358110156112d057600080fd5b506112e18d60c08e01358e016111c8565b81935080925050509295989b509295989b9093969950565b6020808252825182820181905260009190848201906040850190845b8181101561133157835183529284019291840191600101611315565b50909695505050505050565b60006020828403121561134f57600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016113945761139461136c565b5060010190565b60008235603e198336030181126113b157600080fd5b9190910192915050565b81810381811115610a3057610a3061136c565b634e487b7160e01b600052604160045260246000fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6040808252810184905260006060820186825b878110156114765761143282356110b5565b6001600160a01b038235811684526020808401359085015261145760408401356110b5565b6040838101359091169084015260609283019290910190600101611420565b505082810360208401528084825260208201905060208560051b8301018660005b8781101561163157848303601f19018452603e19368a900381018335126114bd57600080fd5b898335016114cb81356110b5565b6001600160a01b03813581168652601e1936839003016020830135126114f057600080fd5b816020830135019150813567ffffffffffffffff8082111561151157600080fd5b8160051b360360208501131561152657600080fd5b604060208901526040880182815260608901905060608360051b8a0101602086016000609e19883603015b8682101561160d57605f198d85030185528083351261156f57600080fd5b888335016020810135855261158760408201356110b5565b88604082013516602086015260608101358b8236030181126115a857600080fd5b8101604081019060200135888111156115c057600080fd5b8036038213156115cf57600080fd5b608060408801526115e46080880182846113e4565b915050608082013560608701528095505050602083019250602085019450600182019150611551565b50505080995050505050505050602082019150602084019350600181019050611497565b5090999850505050505050505056fea26469706673582212203eb045697eb7920001ef411587efa4c3a72293336d02227a14586d08f25ec6b164736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000009cd4f98c93f94ff13af96d2f3550418cce8418c0
-----Decoded View---------------
Arg [0] : feeCollector_ (address): 0x9Cd4f98c93f94fF13AF96d2F3550418cCE8418c0
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000009cd4f98c93f94ff13af96d2f3550418cce8418c0
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$7.13
Net Worth in ETH
0.002484
Token Allocations
ETH
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| SCROLL | 100.00% | $2,861.2 | 0.002491 | $7.13 |
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.