Source Code
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
NftZapLib
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeTransferLib } from "solmate/utils/SafeTransferLib.sol";
import { INftZapLib } from "contracts/interfaces/libraries/INftZapLib.sol";
import { INftLiquidityConnector } from
"contracts/interfaces/INftLiquidityConnector.sol";
import { ISwapLib } from "contracts/interfaces/libraries/ISwapLib.sol";
import { ConnectorRegistry } from "contracts/ConnectorRegistry.sol";
import { DelegateModule } from "contracts/modules/DelegateModule.sol";
import { NftZapIn, NftZapOut } from "contracts/structs/NftZapStructs.sol";
import { NftAddLiquidity } from "contracts/structs/NftLiquidityStructs.sol";
contract NftZapLib is DelegateModule, INftZapLib {
error LiquidityAmountError(); // 0x4d0ab6b4
ISwapLib public immutable swapLib;
ConnectorRegistry public immutable connectorRegistry;
constructor(ConnectorRegistry connectorRegistry_, ISwapLib swapLib_) {
connectorRegistry = connectorRegistry_;
swapLib = swapLib_;
}
function zapIn(
NftZapIn memory zap
) external payable {
uint256 swapDataLength = zap.swaps.length;
for (uint256 i; i < swapDataLength;) {
_delegateTo(
address(swapLib), abi.encodeCall(ISwapLib.swap, (zap.swaps[i]))
);
unchecked {
i++;
}
}
bool atLeastOneNonZero = false;
NftAddLiquidity memory addLiquidityParams = zap.addLiquidityParams;
if (addLiquidityParams.amount0Desired == 0) {
addLiquidityParams.amount0Desired =
IERC20(addLiquidityParams.pool.token0).balanceOf(address(this));
}
if (addLiquidityParams.amount1Desired == 0) {
addLiquidityParams.amount1Desired =
IERC20(addLiquidityParams.pool.token1).balanceOf(address(this));
}
if (addLiquidityParams.amount0Desired > 0) {
atLeastOneNonZero = true;
SafeTransferLib.safeApprove(
addLiquidityParams.pool.token0,
address(addLiquidityParams.nft),
0
);
SafeTransferLib.safeApprove(
addLiquidityParams.pool.token0,
address(addLiquidityParams.nft),
addLiquidityParams.amount0Desired
);
}
if (addLiquidityParams.amount1Desired > 0) {
atLeastOneNonZero = true;
SafeTransferLib.safeApprove(
addLiquidityParams.pool.token1,
address(addLiquidityParams.nft),
0
);
SafeTransferLib.safeApprove(
addLiquidityParams.pool.token1,
address(addLiquidityParams.nft),
addLiquidityParams.amount1Desired
);
}
if (!atLeastOneNonZero) {
revert LiquidityAmountError();
}
address routerConnector =
connectorRegistry.connectorOf(address(addLiquidityParams.nft));
_delegateTo(
routerConnector,
abi.encodeCall(
INftLiquidityConnector.addLiquidity, (addLiquidityParams)
)
);
SafeTransferLib.safeApprove(
addLiquidityParams.pool.token0, address(addLiquidityParams.nft), 0
);
SafeTransferLib.safeApprove(
addLiquidityParams.pool.token1, address(addLiquidityParams.nft), 0
);
}
function zapOut(
NftZapOut memory zap
) external {
address routerConnector = connectorRegistry.connectorOf(
address(zap.removeLiquidityParams.nft)
);
_delegateTo(
routerConnector,
abi.encodeCall(
INftLiquidityConnector.removeLiquidity,
zap.removeLiquidityParams
)
);
uint256 swapDataLength = zap.swaps.length;
for (uint256 i; i < swapDataLength;) {
_delegateTo(
address(swapLib), abi.encodeCall(ISwapLib.swap, (zap.swaps[i]))
);
unchecked {
i++;
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.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: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
/*//////////////////////////////////////////////////////////////
ERRORS
//////////////////////////////////////////////////////////////*/
error ETHTransferFailed();
error TransferFromFailed();
error TransferFailed();
error ApproveFailed();
/*//////////////////////////////////////////////////////////////
ETH OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferETH(address to, uint256 amount) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Transfer the ETH and store if it succeeded or not.
success := call(gas(), to, amount, 0, 0, 0, 0)
}
if (!success) revert ETHTransferFailed();
}
/*//////////////////////////////////////////////////////////////
ERC20 OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferFrom(
address token,
address from,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), 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)
)
}
if (!success) revert TransferFromFailed();
}
function safeTransfer(
address token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), 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)
)
}
if (!success) revert TransferFailed();
}
function safeApprove(
address token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), 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)
)
}
if (!success) revert ApproveFailed();
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { NftZapIn, NftZapOut } from "contracts/structs/NftZapStructs.sol";
interface INftZapLib {
function zapIn(
NftZapIn memory zap
) external payable;
function zapOut(
NftZapOut memory zap
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { SwapParams } from "contracts/structs/LiquidityStructs.sol";
import {
NftAddLiquidity,
NftRemoveLiquidity
} from "contracts/structs/NftLiquidityStructs.sol";
interface INftLiquidityConnector {
function addLiquidity(
NftAddLiquidity memory addLiquidityParams
) external payable;
function removeLiquidity(
NftRemoveLiquidity memory removeLiquidityParams
) external;
function swapExactTokensForTokens(
SwapParams memory swap
) external payable;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { SwapParams } from "contracts/structs/LiquidityStructs.sol";
interface ISwapLib {
function swap(
SwapParams memory swap
) external payable;
function swapMultiple(
SwapParams[] memory swaps
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
import { Admin } from "contracts/base/Admin.sol";
import { TimelockAdmin } from "contracts/base/TimelockAdmin.sol";
error ConnectorNotRegistered(address target);
interface ICustomConnectorRegistry {
function connectorOf(address target) external view returns (address);
}
contract ConnectorRegistry is Admin, TimelockAdmin {
event ConnectorChanged(address target, address connector);
event CustomRegistryAdded(address registry);
event CustomRegistryRemoved(address registry);
error ConnectorAlreadySet(address target);
error ConnectorNotSet(address target);
ICustomConnectorRegistry[] public customRegistries;
mapping(ICustomConnectorRegistry => bool) public isCustomRegistry;
mapping(address target => address connector) private connectors_;
constructor(
address admin_,
address timelockAdmin_
) Admin(admin_) TimelockAdmin(timelockAdmin_) { }
/// @notice Update connector addresses for a batch of targets.
/// @dev Controls which connector contracts are used for the specified
/// targets.
/// @custom:access Restricted to protocol admin.
function setConnectors(
address[] calldata targets,
address[] calldata connectors
) external onlyAdmin {
for (uint256 i; i != targets.length;) {
if (connectors_[targets[i]] != address(0)) {
revert ConnectorAlreadySet(targets[i]);
}
connectors_[targets[i]] = connectors[i];
emit ConnectorChanged(targets[i], connectors[i]);
unchecked {
++i;
}
}
}
function updateConnectors(
address[] calldata targets,
address[] calldata connectors
) external onlyTimelockAdmin {
for (uint256 i; i != targets.length;) {
if (connectors_[targets[i]] == address(0)) {
revert ConnectorNotSet(targets[i]);
}
connectors_[targets[i]] = connectors[i];
emit ConnectorChanged(targets[i], connectors[i]);
unchecked {
++i;
}
}
}
/// @notice Append an address to the custom registries list.
/// @custom:access Restricted to protocol admin.
function addCustomRegistry(ICustomConnectorRegistry registry)
external
onlyAdmin
{
customRegistries.push(registry);
isCustomRegistry[registry] = true;
emit CustomRegistryAdded(address(registry));
}
/// @notice Replace an address in the custom registries list.
/// @custom:access Restricted to protocol admin.
function updateCustomRegistry(
uint256 index,
ICustomConnectorRegistry newRegistry
) external onlyTimelockAdmin {
address oldRegistry = address(customRegistries[index]);
isCustomRegistry[customRegistries[index]] = false;
emit CustomRegistryRemoved(oldRegistry);
customRegistries[index] = newRegistry;
isCustomRegistry[newRegistry] = true;
if (address(newRegistry) != address(0)) {
emit CustomRegistryAdded(address(newRegistry));
}
}
function connectorOf(address target) external view returns (address) {
address connector = connectors_[target];
if (connector != address(0)) {
return connector;
}
uint256 length = customRegistries.length;
for (uint256 i; i != length;) {
if (address(customRegistries[i]) != address(0)) {
try customRegistries[i].connectorOf(target) returns (
address _connector
) {
if (_connector != address(0)) {
return _connector;
}
} catch {
// Ignore
}
}
unchecked {
++i;
}
}
revert ConnectorNotRegistered(target);
}
function hasConnector(address target) external view returns (bool) {
if (connectors_[target] != address(0)) {
return true;
}
uint256 length = customRegistries.length;
for (uint256 i; i != length;) {
if (address(customRegistries[i]) != address(0)) {
try customRegistries[i].connectorOf(target) returns (
address _connector
) {
if (_connector != address(0)) {
return true;
}
} catch {
// Ignore
}
unchecked {
++i;
}
}
}
return false;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract DelegateModule {
function _delegateTo(
address to,
bytes memory data
) internal returns (bytes memory) {
(bool success, bytes memory result) = to.delegatecall(data);
if (!success) {
if (result.length == 0) revert();
assembly {
revert(add(32, result), mload(result))
}
}
return result;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
import { SwapParams } from "contracts/structs/LiquidityStructs.sol";
import {
NftAddLiquidity,
NftRemoveLiquidity
} from "contracts/structs/NftLiquidityStructs.sol";
struct NftZapIn {
SwapParams[] swaps;
NftAddLiquidity addLiquidityParams;
}
struct NftZapOut {
NftRemoveLiquidity removeLiquidityParams;
SwapParams[] swaps;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { INonfungiblePositionManager } from
"contracts/interfaces/external/uniswap/INonfungiblePositionManager.sol";
struct Pool {
address token0;
address token1;
uint24 fee;
}
struct NftAddLiquidity {
INonfungiblePositionManager nft;
uint256 tokenId;
Pool pool;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
bytes extraData;
}
struct NftRemoveLiquidity {
INonfungiblePositionManager nft;
uint256 tokenId;
uint128 liquidity;
uint256 amount0Min; // For decreasing
uint256 amount1Min;
uint128 amount0Max; // For collecting
uint128 amount1Max;
bytes extraData;
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
/*//////////////////////////////////////////////////////////////
METADATA STORAGE
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
uint8 public immutable decimals;
/*//////////////////////////////////////////////////////////////
ERC20 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
/*//////////////////////////////////////////////////////////////
EIP-2612 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
/*//////////////////////////////////////////////////////////////
ERC20 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
/*//////////////////////////////////////////////////////////////
EIP-2612 LOGIC
//////////////////////////////////////////////////////////////*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
// Unchecked because the only math done is incrementing
// the owner's nonce which cannot realistically overflow.
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
),
v,
r,
s
);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
/*//////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
// Cannot underflow because a user's balance
// will never be larger than the total supply.
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
struct AddLiquidityParams {
address router;
address lpToken;
address[] tokens;
uint256[] desiredAmounts;
uint256[] minAmounts;
bytes extraData;
}
struct RemoveLiquidityParams {
address router;
address lpToken;
address[] tokens;
uint256 lpAmountIn;
uint256[] minAmountsOut;
bytes extraData;
}
struct SwapParams {
address router;
uint256 amountIn;
uint256 minAmountOut;
address tokenIn;
bytes extraData;
}
struct GetAmountOutParams {
address router;
address lpToken;
address tokenIn;
address tokenOut;
uint256 amountIn;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
/// @title Admin contract
/// @author vfat.tools
/// @notice Provides an administration mechanism allowing restricted functions
abstract contract Admin {
/// ERRORS ///
/// @notice Thrown when the caller is not the admin
error NotAdminError(); //0xb5c42b3b
/// EVENTS ///
/// @notice Emitted when a new admin is set
/// @param oldAdmin Address of the old admin
/// @param newAdmin Address of the new admin
event AdminSet(address oldAdmin, address newAdmin);
/// STORAGE ///
/// @notice Address of the current admin
address public admin;
/// MODIFIERS ///
/// @dev Restricts a function to the admin
modifier onlyAdmin() {
if (msg.sender != admin) revert NotAdminError();
_;
}
/// WRITE FUNCTIONS ///
/// @param admin_ Address of the admin
constructor(address admin_) {
emit AdminSet(admin, admin_);
admin = admin_;
}
/// @notice Sets a new admin
/// @param newAdmin Address of the new admin
/// @custom:access Restricted to protocol admin.
function setAdmin(address newAdmin) external onlyAdmin {
emit AdminSet(admin, newAdmin);
admin = newAdmin;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
/// @title TimelockAdmin contract
/// @author vfat.tools
/// @notice Provides an timelockAdministration mechanism allowing restricted
/// functions
abstract contract TimelockAdmin {
/// ERRORS ///
/// @notice Thrown when the caller is not the timelockAdmin
error NotTimelockAdminError();
/// EVENTS ///
/// @notice Emitted when a new timelockAdmin is set
/// @param oldTimelockAdmin Address of the old timelockAdmin
/// @param newTimelockAdmin Address of the new timelockAdmin
event TimelockAdminSet(address oldTimelockAdmin, address newTimelockAdmin);
/// STORAGE ///
/// @notice Address of the current timelockAdmin
address public timelockAdmin;
/// MODIFIERS ///
/// @dev Restricts a function to the timelockAdmin
modifier onlyTimelockAdmin() {
if (msg.sender != timelockAdmin) revert NotTimelockAdminError();
_;
}
/// WRITE FUNCTIONS ///
/// @param timelockAdmin_ Address of the timelockAdmin
constructor(address timelockAdmin_) {
emit TimelockAdminSet(timelockAdmin, timelockAdmin_);
timelockAdmin = timelockAdmin_;
}
/// @notice Sets a new timelockAdmin
/// @dev Can only be called by the current timelockAdmin
/// @param newTimelockAdmin Address of the new timelockAdmin
function setTimelockAdmin(address newTimelockAdmin)
external
onlyTimelockAdmin
{
emit TimelockAdminSet(timelockAdmin, newTimelockAdmin);
timelockAdmin = newTimelockAdmin;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IERC721Enumerable } from
"openzeppelin-contracts/contracts/interfaces/IERC721Enumerable.sol";
interface INonfungiblePositionManager is IERC721Enumerable {
struct IncreaseLiquidityParams {
uint256 tokenId;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
}
struct MintParams {
address token0;
address token1;
uint24 fee;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
address recipient;
uint256 deadline;
}
struct DecreaseLiquidityParams {
uint256 tokenId;
uint128 liquidity;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
}
struct CollectParams {
uint256 tokenId;
address recipient;
uint128 amount0Max;
uint128 amount1Max;
}
function increaseLiquidity(IncreaseLiquidityParams memory params)
external
payable
returns (uint256 amount0, uint256 amount1, uint256 liquidity);
function decreaseLiquidity(DecreaseLiquidityParams calldata params)
external
payable
returns (uint256 amount0, uint256 amount1);
function mint(MintParams memory params)
external
payable
returns (uint256 tokenId, uint256 amount0, uint256 amount1);
function collect(CollectParams calldata params)
external
payable
returns (uint256 amount0, uint256 amount1);
function burn(uint256 tokenId) external payable;
function positions(uint256 tokenId)
external
view
returns (
uint96 nonce,
address operator,
address token0,
address token1,
uint24 fee,
int24 tickLower,
int24 tickUpper,
uint128 liquidity,
uint256 feeGrowthInside0LastX128,
uint256 feeGrowthInside1LastX128,
uint128 tokensOwed0,
uint128 tokensOwed1
);
}// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../token/ERC721/extensions/IERC721Enumerable.sol";
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)
pragma solidity ^0.8.0;
import "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Enumerable is IERC721 {
/**
* @dev Returns the total amount of tokens stored by the contract.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns a token ID owned by `owner` at a given `index` of its token list.
* Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
/**
* @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
* Use along with {totalSupply} to enumerate all tokens.
*/
function tokenByIndex(uint256 index) external view returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"solmate/=lib/solmate/src/",
"@openzeppelin/=lib/openzeppelin-contracts/",
"@uniswap/v3-periphery/=lib/v3-periphery/",
"@uniswap/v3-core/=lib/v3-core/",
"@morpho-blue/=lib/morpho-blue/src/",
"ds-test/=lib/solmate/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"morpho-blue/=lib/morpho-blue/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract ConnectorRegistry","name":"connectorRegistry_","type":"address"},{"internalType":"contract ISwapLib","name":"swapLib_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApproveFailed","type":"error"},{"inputs":[],"name":"LiquidityAmountError","type":"error"},{"inputs":[],"name":"connectorRegistry","outputs":[{"internalType":"contract ConnectorRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapLib","outputs":[{"internalType":"contract ISwapLib","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"router","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct SwapParams[]","name":"swaps","type":"tuple[]"},{"components":[{"internalType":"contract INonfungiblePositionManager","name":"nft","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"}],"internalType":"struct Pool","name":"pool","type":"tuple"},{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint256","name":"amount0Desired","type":"uint256"},{"internalType":"uint256","name":"amount1Desired","type":"uint256"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct NftAddLiquidity","name":"addLiquidityParams","type":"tuple"}],"internalType":"struct NftZapIn","name":"zap","type":"tuple"}],"name":"zapIn","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"contract INonfungiblePositionManager","name":"nft","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"uint128","name":"amount0Max","type":"uint128"},{"internalType":"uint128","name":"amount1Max","type":"uint128"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct NftRemoveLiquidity","name":"removeLiquidityParams","type":"tuple"},{"components":[{"internalType":"address","name":"router","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct SwapParams[]","name":"swaps","type":"tuple[]"}],"internalType":"struct NftZapOut","name":"zap","type":"tuple"}],"name":"zapOut","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60c060405234801561001057600080fd5b50604051610f5e380380610f5e83398101604081905261002f9161005e565b6001600160a01b0391821660a05216608052610098565b6001600160a01b038116811461005b57600080fd5b50565b6000806040838503121561007157600080fd5b825161007c81610046565b602084015190925061008d81610046565b809150509250929050565b60805160a051610e876100d76000396000818160c80152818161012201526104950152600081816078015281816101ee015261028c0152610e876000f3fe60806040526004361061003f5760003560e01c80630a0a5032146100445780633faa6e3014610066578063b53c86d2146100b6578063f5d0466c146100ea575b600080fd5b34801561005057600080fd5b5061006461005f3660046108f1565b6100fd565b005b34801561007257600080fd5b5061009a7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200160405180910390f35b3480156100c257600080fd5b5061009a7f000000000000000000000000000000000000000000000000000000000000000081565b6100646100f8366004610aa1565b610279565b8051516040516363cd755760e11b81526001600160a01b0391821660048201526000917f0000000000000000000000000000000000000000000000000000000000000000169063c79aeaae90602401602060405180830381865afa158015610169573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061018d9190610bde565b90506101d78183600001516040516024016101a89190610c52565b60408051601f198184030181529190526020810180516001600160e01b031663cce9480160e01b17905261057a565b5060208201515160005b818110156102735761026a7f00000000000000000000000000000000000000000000000000000000000000008560200151838151811061022357610223610ce2565b602002602001015160405160240161023b9190610cf8565b60408051601f198184030181529190526020810180516001600160e01b03166363471ff960e01b17905261057a565b506001016101e1565b50505050565b80515160005b818110156102ca576102c17f00000000000000000000000000000000000000000000000000000000000000008460000151838151811061022357610223610ce2565b5060010161027f565b50602082015160a0810151600091908203610354576040818101515190516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561032a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034e9190610d47565b60a08201525b8060c001516000036103d8576040808201516020015190516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156103ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d29190610d47565b60c08201525b60a081015115610412576040810151518151600193506103fa919060006105ff565b604081015151815160a08301516104129291906105ff565b60c0810151156104535760019150610438816040015160200151826000015160006105ff565b61045381604001516020015182600001518360c001516105ff565b8161047157604051631342adad60e21b815260040160405180910390fd5b80516040516363cd755760e11b81526001600160a01b0391821660048201526000917f0000000000000000000000000000000000000000000000000000000000000000169063c79aeaae90602401602060405180830381865afa1580156104dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105009190610bde565b905061054681836040516024016105179190610d60565b60408051601f198184030181529190526020810180516001600160e01b03166304caab4760e01b17905261057a565b50604082015151825161055b919060006105ff565b610573826040015160200151836000015160006105ff565b5050505050565b6060600080846001600160a01b0316846040516105979190610e35565b600060405180830381855af49150503d80600081146105d2576040519150601f19603f3d011682016040523d82523d6000602084013e6105d7565b606091505b5091509150816105f75780516000036105ef57600080fd5b805181602001fd5b949350505050565b600060405163095ea7b360e01b8152836004820152826024820152602060006044836000895af13d15601f3d116001600051141617169150508061027357604051633e3f8f7360e01b815260040160405180910390fd5b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561068f5761068f610656565b60405290565b6040805190810167ffffffffffffffff8111828210171561068f5761068f610656565b604051610100810167ffffffffffffffff8111828210171561068f5761068f610656565b604051610140810167ffffffffffffffff8111828210171561068f5761068f610656565b604051601f8201601f1916810167ffffffffffffffff8111828210171561072957610729610656565b604052919050565b6001600160a01b038116811461074657600080fd5b50565b803561075481610731565b919050565b80356001600160801b038116811461075457600080fd5b600082601f83011261078157600080fd5b813567ffffffffffffffff81111561079b5761079b610656565b6107ae601f8201601f1916602001610700565b8181528460208386010111156107c357600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f8301126107f157600080fd5b8135602067ffffffffffffffff8083111561080e5761080e610656565b8260051b61081d838201610700565b938452858101830193838101908886111561083757600080fd5b84880192505b858310156108e5578235848111156108555760008081fd5b880160a0818b03601f190181131561086d5760008081fd5b61087561066c565b8783013561088281610731565b80825250604080840135898301526060808501358284015260809150818501356108ab81610731565b908301529183013591878311156108c25760008081fd5b6108d08d8a85870101610770565b9082015284525050918401919084019061083d565b98975050505050505050565b60006020828403121561090357600080fd5b813567ffffffffffffffff8082111561091b57600080fd5b908301906040828603121561092f57600080fd5b610937610695565b82358281111561094657600080fd5b8301610100818803121561095957600080fd5b6109616106b8565b61096a82610749565b81526020820135602082015261098260408301610759565b604082015260608201356060820152608082013560808201526109a760a08301610759565b60a08201526109b860c08301610759565b60c082015260e0820135848111156109cf57600080fd5b6109db89828501610770565b60e0830152508252506020830135828111156109f657600080fd5b610a02878286016107e0565b60208301525095945050505050565b600060608284031215610a2357600080fd5b6040516060810181811067ffffffffffffffff82111715610a4657610a46610656565b6040529050808235610a5781610731565b81526020830135610a6781610731565b6020820152604083013562ffffff81168114610a8257600080fd5b6040919091015292915050565b8035600281900b811461075457600080fd5b600060208284031215610ab357600080fd5b813567ffffffffffffffff80821115610acb57600080fd5b9083019060408286031215610adf57600080fd5b610ae7610695565b823582811115610af657600080fd5b610b02878286016107e0565b825250602083013582811115610b1757600080fd5b92909201916101808387031215610b2d57600080fd5b610b356106dc565b610b3e84610749565b815260208401356020820152610b578760408601610a11565b6040820152610b6860a08501610a8f565b6060820152610b7960c08501610a8f565b608082015260e084013560a08201526101008085013560c08301526101208086013560e084015261014086013582840152610160860135915084821115610bbf57600080fd5b610bcb89838801610770565b9083015250602082015295945050505050565b600060208284031215610bf057600080fd5b8151610bfb81610731565b9392505050565b60005b83811015610c1d578181015183820152602001610c05565b50506000910152565b60008151808452610c3e816020860160208601610c02565b601f01601f19169290920160200192915050565b6020815260018060a01b038251166020820152602082015160408201526001600160801b03604083015116606082015260608201516080820152608082015160a0820152600060a0830151610cb260c08401826001600160801b03169052565b5060c08301516001600160801b03811660e08401525060e0830151610100838101526105f7610120840182610c26565b634e487b7160e01b600052603260045260246000fd5b60208152600060018060a01b03808451166020840152602084015160408401526040840151606084015280606085015116608084015250608083015160a0808401526105f760c0840182610c26565b600060208284031215610d5957600080fd5b5051919050565b60208152610d7a6020820183516001600160a01b03169052565b6020820151604082015260006040830151610dbf606084018280516001600160a01b0390811683526020808301519091169083015260409081015162ffffff16910152565b506060830151610dd460c084018260020b9052565b506080830151610de960e084018260020b9052565b5060a08301516101008381019190915260c08401516101208085019190915260e085015161014085015290840151610160840152830151610180808401526105f76101a0840182610c26565b60008251610e47818460208701610c02565b919091019291505056fea26469706673582212203d8378502508519c7da495f03149e10e4f50c32e6d6bb24288b47ad43a0d992e64736f6c634300081300330000000000000000000000003575aa02ae85d8cd2aae6dcaa5d8750cfc9622e6000000000000000000000000b01e431542bafbac3fc95057961c92ed8e06e08d
Deployed Bytecode
0x60806040526004361061003f5760003560e01c80630a0a5032146100445780633faa6e3014610066578063b53c86d2146100b6578063f5d0466c146100ea575b600080fd5b34801561005057600080fd5b5061006461005f3660046108f1565b6100fd565b005b34801561007257600080fd5b5061009a7f000000000000000000000000b01e431542bafbac3fc95057961c92ed8e06e08d81565b6040516001600160a01b03909116815260200160405180910390f35b3480156100c257600080fd5b5061009a7f0000000000000000000000003575aa02ae85d8cd2aae6dcaa5d8750cfc9622e681565b6100646100f8366004610aa1565b610279565b8051516040516363cd755760e11b81526001600160a01b0391821660048201526000917f0000000000000000000000003575aa02ae85d8cd2aae6dcaa5d8750cfc9622e6169063c79aeaae90602401602060405180830381865afa158015610169573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061018d9190610bde565b90506101d78183600001516040516024016101a89190610c52565b60408051601f198184030181529190526020810180516001600160e01b031663cce9480160e01b17905261057a565b5060208201515160005b818110156102735761026a7f000000000000000000000000b01e431542bafbac3fc95057961c92ed8e06e08d8560200151838151811061022357610223610ce2565b602002602001015160405160240161023b9190610cf8565b60408051601f198184030181529190526020810180516001600160e01b03166363471ff960e01b17905261057a565b506001016101e1565b50505050565b80515160005b818110156102ca576102c17f000000000000000000000000b01e431542bafbac3fc95057961c92ed8e06e08d8460000151838151811061022357610223610ce2565b5060010161027f565b50602082015160a0810151600091908203610354576040818101515190516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561032a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034e9190610d47565b60a08201525b8060c001516000036103d8576040808201516020015190516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156103ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d29190610d47565b60c08201525b60a081015115610412576040810151518151600193506103fa919060006105ff565b604081015151815160a08301516104129291906105ff565b60c0810151156104535760019150610438816040015160200151826000015160006105ff565b61045381604001516020015182600001518360c001516105ff565b8161047157604051631342adad60e21b815260040160405180910390fd5b80516040516363cd755760e11b81526001600160a01b0391821660048201526000917f0000000000000000000000003575aa02ae85d8cd2aae6dcaa5d8750cfc9622e6169063c79aeaae90602401602060405180830381865afa1580156104dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105009190610bde565b905061054681836040516024016105179190610d60565b60408051601f198184030181529190526020810180516001600160e01b03166304caab4760e01b17905261057a565b50604082015151825161055b919060006105ff565b610573826040015160200151836000015160006105ff565b5050505050565b6060600080846001600160a01b0316846040516105979190610e35565b600060405180830381855af49150503d80600081146105d2576040519150601f19603f3d011682016040523d82523d6000602084013e6105d7565b606091505b5091509150816105f75780516000036105ef57600080fd5b805181602001fd5b949350505050565b600060405163095ea7b360e01b8152836004820152826024820152602060006044836000895af13d15601f3d116001600051141617169150508061027357604051633e3f8f7360e01b815260040160405180910390fd5b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561068f5761068f610656565b60405290565b6040805190810167ffffffffffffffff8111828210171561068f5761068f610656565b604051610100810167ffffffffffffffff8111828210171561068f5761068f610656565b604051610140810167ffffffffffffffff8111828210171561068f5761068f610656565b604051601f8201601f1916810167ffffffffffffffff8111828210171561072957610729610656565b604052919050565b6001600160a01b038116811461074657600080fd5b50565b803561075481610731565b919050565b80356001600160801b038116811461075457600080fd5b600082601f83011261078157600080fd5b813567ffffffffffffffff81111561079b5761079b610656565b6107ae601f8201601f1916602001610700565b8181528460208386010111156107c357600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f8301126107f157600080fd5b8135602067ffffffffffffffff8083111561080e5761080e610656565b8260051b61081d838201610700565b938452858101830193838101908886111561083757600080fd5b84880192505b858310156108e5578235848111156108555760008081fd5b880160a0818b03601f190181131561086d5760008081fd5b61087561066c565b8783013561088281610731565b80825250604080840135898301526060808501358284015260809150818501356108ab81610731565b908301529183013591878311156108c25760008081fd5b6108d08d8a85870101610770565b9082015284525050918401919084019061083d565b98975050505050505050565b60006020828403121561090357600080fd5b813567ffffffffffffffff8082111561091b57600080fd5b908301906040828603121561092f57600080fd5b610937610695565b82358281111561094657600080fd5b8301610100818803121561095957600080fd5b6109616106b8565b61096a82610749565b81526020820135602082015261098260408301610759565b604082015260608201356060820152608082013560808201526109a760a08301610759565b60a08201526109b860c08301610759565b60c082015260e0820135848111156109cf57600080fd5b6109db89828501610770565b60e0830152508252506020830135828111156109f657600080fd5b610a02878286016107e0565b60208301525095945050505050565b600060608284031215610a2357600080fd5b6040516060810181811067ffffffffffffffff82111715610a4657610a46610656565b6040529050808235610a5781610731565b81526020830135610a6781610731565b6020820152604083013562ffffff81168114610a8257600080fd5b6040919091015292915050565b8035600281900b811461075457600080fd5b600060208284031215610ab357600080fd5b813567ffffffffffffffff80821115610acb57600080fd5b9083019060408286031215610adf57600080fd5b610ae7610695565b823582811115610af657600080fd5b610b02878286016107e0565b825250602083013582811115610b1757600080fd5b92909201916101808387031215610b2d57600080fd5b610b356106dc565b610b3e84610749565b815260208401356020820152610b578760408601610a11565b6040820152610b6860a08501610a8f565b6060820152610b7960c08501610a8f565b608082015260e084013560a08201526101008085013560c08301526101208086013560e084015261014086013582840152610160860135915084821115610bbf57600080fd5b610bcb89838801610770565b9083015250602082015295945050505050565b600060208284031215610bf057600080fd5b8151610bfb81610731565b9392505050565b60005b83811015610c1d578181015183820152602001610c05565b50506000910152565b60008151808452610c3e816020860160208601610c02565b601f01601f19169290920160200192915050565b6020815260018060a01b038251166020820152602082015160408201526001600160801b03604083015116606082015260608201516080820152608082015160a0820152600060a0830151610cb260c08401826001600160801b03169052565b5060c08301516001600160801b03811660e08401525060e0830151610100838101526105f7610120840182610c26565b634e487b7160e01b600052603260045260246000fd5b60208152600060018060a01b03808451166020840152602084015160408401526040840151606084015280606085015116608084015250608083015160a0808401526105f760c0840182610c26565b600060208284031215610d5957600080fd5b5051919050565b60208152610d7a6020820183516001600160a01b03169052565b6020820151604082015260006040830151610dbf606084018280516001600160a01b0390811683526020808301519091169083015260409081015162ffffff16910152565b506060830151610dd460c084018260020b9052565b506080830151610de960e084018260020b9052565b5060a08301516101008381019190915260c08401516101208085019190915260e085015161014085015290840151610160840152830151610180808401526105f76101a0840182610c26565b60008251610e47818460208701610c02565b919091019291505056fea26469706673582212203d8378502508519c7da495f03149e10e4f50c32e6d6bb24288b47ad43a0d992e64736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003575aa02ae85d8cd2aae6dcaa5d8750cfc9622e6000000000000000000000000b01e431542bafbac3fc95057961c92ed8e06e08d
-----Decoded View---------------
Arg [0] : connectorRegistry_ (address): 0x3575Aa02Ae85D8Cd2AaE6DCaA5D8750cFc9622e6
Arg [1] : swapLib_ (address): 0xb01e431542BAFBac3Fc95057961c92ED8E06E08d
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000003575aa02ae85d8cd2aae6dcaa5d8750cfc9622e6
Arg [1] : 000000000000000000000000b01e431542bafbac3fc95057961c92ed8e06e08d
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in FRAX
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.