Source Code
EVM
Overview
ETH Balance
0 ETH
ETH Value
$0.00Latest 8 from a total of 8 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Withdraw | 20447408 | 114 days ago | IN | 0 ETH | 0.00001485 | ||||
| Withdraw | 20234061 | 118 days ago | IN | 0 ETH | 0.00001484 | ||||
| Create Lock | 20225457 | 118 days ago | IN | 0 ETH | 0.0000362 | ||||
| Create Lock | 20224065 | 118 days ago | IN | 0 ETH | 0.00003618 | ||||
| Unpause New Lock... | 20220200 | 118 days ago | IN | 0 ETH | 0.00000614 | ||||
| Withdraw | 20209288 | 118 days ago | IN | 0 ETH | 0.00002248 | ||||
| Pause New Locks | 20207295 | 118 days ago | IN | 0 ETH | 0.00000627 | ||||
| Create Lock | 20206550 | 118 days ago | IN | 0 ETH | 0.00004696 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 20163423 | 119 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
IglooLockV2
Compiler Version
v0.8.24+commit.e11b9ed9
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.24;
/**
██████╗ ███████╗████████╗██████╗ ██████╗
██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔════╝
██████╔╝███████╗ ██║ ██████╔╝██║ ███╗
██╔═══╝ ╚════██║ ██║ ██╔══██╗██║ ██║
██║██╗ ███████║ ██║ ██║ ██║╚██████╔╝
╚═╝╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝
*/
/**
* ╔══════════════════════════════════════════════════════════════╗
* ║ IGLOOVAULT PROTOCOL Powered by PDGYSTR ║
* ║ Made by CaptainY ║
* ╠══════════════════════════════════════════════════════════════╣
* ║ Features: ║
* ║ • Bulletproof time-locked token custody ║
* ║ • Withdrawal guarantee; funds never get rekt ║
* ║ • Split/merge/extend functionality for max flexibility ║
* ║ • Zero trust; everything verifiable on blockchain ║
* ║ • PDGYSTR powered fee system for protocol sustainability ║
* ║ • AI-Audited multiple times but you know it's AI sers ║
* ║ ║
* ╚══════════════════════════════════════════════════════════════╝
*/
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";
/**
* @title IglooLockV2 - The ERC-20 Token Freezer
* @author CaptainY
* @notice Lock your precious ERC-20 tokens until you're ready to thaw them out
* @dev This beast handles any ERC-20 token with surgical precision - no rugs allowed
*/
contract IglooLockV2 is ReentrancyGuard, Ownable, Pausable {
using SafeERC20 for IERC20;
// What each frozen token stack looks like in our igloo
struct LockV2 {
address token; // Which ERC-20 token is frozen
address owner; // Who owns this frozen stack
uint128 amount; // How many tokens are chilling
uint64 unlockTime; // When the ice melts (unix timestamp)
bool withdrawn; // Has it been thawed out yet?
}
uint256 public nextId = 1; // Lock ID counter - starts at 1 like a chad
uint64 public constant MIN_DURATION = 1 hours; // Minimum freeze time - no quick dumps allowed
// Core infrastructure addresses - the holy trinity
IERC20 public constant PDGYSTR = IERC20(0xce2Fbf6EDfa8b759C4e0c80D73F1aFf2A93B054B); // The fee token
address public immutable feeVault; // Where PDGYSTR fees go to party
address public immutable registry; // The master ledger of all locks
// Economic parameters - these are the meme numbers ser
uint256 public lockFee = 42069 * 1e18; // 42069 PDGYSTR to freeze tokens (nice)
uint256 public splitFee = 4269 * 1e18; // 4269 PDGYSTR to split locks (also nice)
bool public feesEnabled = true; // Can turn off fees if feeling generous
// Storage mappings - where the magic happens
mapping(uint256 => LockV2) public locks; // lockId => lock details
mapping(address => uint256) public tokenTotalLocked; // token => total amount frozen
mapping(uint256 => uint256) private _regId; // lockId => registry position
// Events for the blockchain historians and degen trackers
event LockCreated(uint256 indexed id, address indexed token, address indexed owner, uint128 amount, uint64 unlockTime);
event LockExtended(uint256 indexed id, uint64 newUnlockTime);
event LockOwnerTransferred(uint256 indexed id, address indexed oldOwner, address indexed newOwner);
event LockWithdrawn(uint256 indexed id, address indexed to, uint128 amount);
event LockSplit(uint256 indexed originalId, uint256 indexed newId, uint128 splitAmount);
event LocksMerged(uint256 indexed keepId, uint256 indexed burnId, uint128 totalAmount);
event LockDeactivated(uint256 indexed id, string reason);
event FeesChanged(uint256 lockFee, uint256 splitFee);
event FeesToggled(bool enabled);
event TokensRescued(address indexed token, address indexed to, uint256 amount);
event RegistryCallFailed(uint256 indexed registryId, string reason); // When registry goes brrr
/**
* @notice Deploy this beast with proper infrastructure addresses
* @param _feeVault Where the PDGYSTR fees get collected and vibed
* @param _registry The master record keeper that tracks everything
* @param _safeOwner Who can admin this contract (choose wisely, no rugs)
*/
constructor(
address _feeVault,
address _registry,
address _safeOwner
) Ownable(_safeOwner) {
require(_feeVault != address(0), "invalid fee vault");
require(_registry != address(0), "invalid registry");
feeVault = _feeVault;
registry = _registry;
}
/**
* @notice Main entry point - freeze your tokens with standard approval
* @dev The classic way - approve first, then lock
*/
function createLock(
address token, // Which token you want to freeze
uint128 amount, // How much you want to lock up
uint64 unlockTime, // When you want it back
address beneficiary // Who gets to thaw it (can be yourself)
) external whenNotPaused nonReentrant returns (uint256 id) {
return _createLock(token, amount, unlockTime, beneficiary, msg.sender);
}
/**
* @notice Fancy entry point - freeze tokens with permit signature (gas efficient)
* @dev Uses EIP-2612 permit to avoid double transaction
*/
function createLockWithPermit(
address token,
uint128 amount,
uint64 unlockTime,
address beneficiary,
uint256 deadline, // Permit expiration
uint8 v, // Signature components
bytes32 r,
bytes32 s
) external whenNotPaused nonReentrant returns (uint256 id) {
// Use the permit to approve in the same transaction - big brain move
IERC20Permit(token).permit(msg.sender, address(this), amount, deadline, v, r, s);
require(IERC20(token).allowance(msg.sender, address(this)) >= amount, "permit/allowance too low");
return _createLock(token, amount, unlockTime, beneficiary, msg.sender);
}
/**
* @notice Internal freezing logic - this is where the magic happens
* @dev Protected against fee-on-transfer tokens and other degenerate stuff
*/
function _createLock(
address token,
uint128 amount,
uint64 unlockTime,
address beneficiary,
address payer
) internal returns (uint256 id) {
require(beneficiary != address(0), "bad beneficiary");
require(amount > 0, "zero amount");
require(unlockTime >= uint64(block.timestamp) + MIN_DURATION, "unlock too soon");
require(token.code.length > 0, "invalid token contract");
// Collect the PDGYSTR tribute before doing anything else
if (feesEnabled && lockFee > 0) {
IFeeVault(feeVault).collectFee(payer, lockFee, keccak256(bytes("V2_LOCK")), "V2_LOCK");
}
// Defensive check against fee-on-transfer tokens (we don't play that game)
uint256 balBefore = IERC20(token).balanceOf(address(this));
IERC20(token).safeTransferFrom(payer, address(this), amount);
uint256 balAfter = IERC20(token).balanceOf(address(this));
require(balAfter - balBefore == amount, "deflationary token not supported");
// Create the lock record - these tokens are now frozen solid
id = nextId++;
locks[id] = LockV2({
token: token,
owner: beneficiary,
amount: amount,
unlockTime: unlockTime,
withdrawn: false
});
tokenTotalLocked[token] += amount; // Track total locked for safety
// Try to register with our master ledger (best effort - won't break if registry is down)
(bool success, bytes memory returnData) = registry.call(
abi.encodeWithSelector(ILockRegistry.registerLock.selector, address(this), id, beneficiary, unlockTime, 0)
);
if (success) {
_regId[id] = abi.decode(returnData, (uint256));
} else {
emit RegistryCallFailed(0, "registration failed");
}
emit LockCreated(id, token, beneficiary, amount, unlockTime);
}
/**
* @notice Extend the freeze time - make those tokens colder for longer
* @dev Works even when contract is paused because extending is always safe
*/
function extendLock(uint256 id, uint64 newUnlockTime) external {
LockV2 storage L = locks[id];
require(msg.sender == L.owner, "not owner");
require(!L.withdrawn, "already withdrawn");
require(newUnlockTime > L.unlockTime, "must extend");
L.unlockTime = newUnlockTime;
// Tell the registry about the new timeline (best effort)
(bool success,) = registry.call(
abi.encodeWithSelector(ILockRegistry.updateUnlockTime.selector, _regId[id], newUnlockTime)
);
if (!success) {
emit RegistryCallFailed(_regId[id], "unlock time update failed");
}
emit LockExtended(id, newUnlockTime);
}
/**
* @notice Transfer lock ownership - gift your frozen tokens to someone else
* @dev Locked with reentrancy guard and post-withdrawal protection
*/
function transferLockOwner(uint256 id, address newOwner) external nonReentrant {
LockV2 storage L = locks[id];
require(msg.sender == L.owner, "not owner");
require(!L.withdrawn, "withdrawn"); // Can't transfer what's already thawed
require(newOwner != address(0), "zero address");
address oldOwner = L.owner;
L.owner = newOwner;
// Update the master ledger (best effort)
(bool success,) = registry.call(
abi.encodeWithSelector(ILockRegistry.updateLockOwner.selector, _regId[id], newOwner)
);
if (!success) {
emit RegistryCallFailed(_regId[id], "owner transfer failed");
}
emit LockOwnerTransferred(id, oldOwner, newOwner);
}
/**
* @notice THE HOLY GRAIL - withdraw your tokens after the ice melts
* @dev CRITICAL: This can NEVER be blocked - even if everything else breaks
*/
function withdraw(uint256 id) external nonReentrant {
LockV2 storage L = locks[id];
require(msg.sender == L.owner, "not owner");
require(!L.withdrawn, "withdrawn");
require(block.timestamp >= L.unlockTime, "locked");
// Mark as withdrawn and update accounting
L.withdrawn = true;
tokenTotalLocked[L.token] -= L.amount;
// Send the tokens home - this ALWAYS works regardless of registry status
IERC20(L.token).safeTransfer(L.owner, L.amount);
// Try to update registry but don't let it break withdrawals
(bool success,) = registry.call(
abi.encodeWithSelector(ILockRegistry.setInactive.selector, _regId[id], "withdrawn")
);
if (!success) {
emit RegistryCallFailed(_regId[id], "deactivation failed");
}
emit LockWithdrawn(id, L.owner, L.amount);
}
/**
* @notice Split one big lock into two smaller locks - for the flexible degens
* @dev Requires split fee payment in PDGYSTR
*/
function splitLock(uint256 id, uint128 splitAmount) external whenNotPaused nonReentrant returns (uint256 newId) {
LockV2 storage L = locks[id];
require(msg.sender == L.owner, "not owner");
require(!L.withdrawn, "withdrawn");
require(splitAmount > 0 && splitAmount < L.amount, "invalid split");
// Pay the split fee to keep the protocol sustainable
if (feesEnabled && splitFee > 0) {
IFeeVault(feeVault).collectFee(msg.sender, splitFee, keccak256(bytes("V2_SPLIT")), "V2_SPLIT");
}
// Create the new lock with the split amount
newId = nextId++;
locks[newId] = LockV2({
token: L.token,
owner: L.owner,
amount: splitAmount,
unlockTime: L.unlockTime,
withdrawn: false
});
// Reduce the original lock
L.amount -= splitAmount;
// Try to register the new lock with registry (best effort)
(bool success, bytes memory returnData) = registry.call(
abi.encodeWithSelector(ILockRegistry.registerLock.selector, address(this), newId, L.owner, L.unlockTime, 0)
);
if (success) {
_regId[newId] = abi.decode(returnData, (uint256));
} else {
emit RegistryCallFailed(0, "split registration failed");
}
emit LockSplit(id, newId, splitAmount);
}
/**
* @notice Merge two identical locks into one bigger lock - for the gas-efficient degens
* @dev Both locks must have same token, owner, and unlock time
*/
function mergeLocks(uint256 keepId, uint256 burnId) external nonReentrant {
require(keepId != burnId, "same id");
LockV2 storage keep = locks[keepId];
LockV2 storage burn = locks[burnId];
// Validate both locks belong to sender and are compatible
require(msg.sender == keep.owner && msg.sender == burn.owner, "not owner");
require(!keep.withdrawn && !burn.withdrawn, "withdrawn");
require(keep.token == burn.token, "different tokens");
require(keep.unlockTime == burn.unlockTime, "different unlock times");
// Merge the amounts and burn the second lock
uint128 totalAmount = keep.amount + burn.amount;
keep.amount = totalAmount;
burn.withdrawn = true; // Mark as withdrawn to deactivate
emit LocksMerged(keepId, burnId, totalAmount);
emit LockDeactivated(burnId, "merged");
// Try to deactivate the burned lock in registry (best effort)
(bool success,) = registry.call(
abi.encodeWithSelector(ILockRegistry.setInactive.selector, _regId[burnId], "merged")
);
if (!success) {
emit RegistryCallFailed(_regId[burnId], "merge deactivation failed");
}
}
/**
* @notice Emergency token rescue - only for tokens that aren't locked
* @dev Owner can rescue tokens that somehow ended up here but aren't part of any lock
*/
function rescueTokens(address token, address to, uint256 amount) external onlyOwner {
require(to != address(0), "invalid recipient");
uint256 contractBalance = IERC20(token).balanceOf(address(this));
uint256 lockedAmount = tokenTotalLocked[token];
require(amount <= contractBalance - lockedAmount, "cannot touch locked tokens");
IERC20(token).safeTransfer(to, amount);
emit TokensRescued(token, to, amount);
}
// ═══════════════════════════════════════════════════════════
// ADMIN FUNCTIONS
// ═══════════════════════════════════════════════════════════
/**
* @notice Update the meme fee numbers - owner only
*/
function setFees(uint256 _lockFee, uint256 _splitFee) external onlyOwner {
lockFee = _lockFee;
splitFee = _splitFee;
emit FeesChanged(_lockFee, _splitFee);
}
/**
* @notice Turn fees on/off - for when we're feeling generous
*/
function toggleFees(bool enabled) external onlyOwner {
feesEnabled = enabled;
emit FeesToggled(enabled);
}
/**
* @notice Emergency pause for new locks - withdrawals always work though
*/
function pauseNewLocks() external onlyOwner {
_pause();
}
function unpauseNewLocks() external onlyOwner {
_unpause();
}
// ═══════════════════════════════════════════════════════════
// VIEW FUNCTIONS
// ═══════════════════════════════════════════════════════════
function getLockInfo(uint256 id) external view returns (LockV2 memory) {
return locks[id];
}
function ownerOfLock(uint256 id) external view returns (address) {
return locks[id].owner;
}
function totalLocked(address token) external view returns (uint256) {
return tokenTotalLocked[token];
}
function isActive(uint256 id) external view returns (bool) {
return !locks[id].withdrawn;
}
function isWithdrawn(uint256 id) external view returns (bool) {
return locks[id].withdrawn;
}
/**
* @notice Generate a hash of the lock config - for sharing and verification
*/
function hashLockConfig(uint256 id) external view returns (bytes32) {
LockV2 memory lock = locks[id];
return keccak256(abi.encode(
lock.token,
lock.amount,
lock.unlockTime,
id
));
}
/**
* @notice System health check - is everything working properly?
*/
function getSystemHealth() external view returns (
bool feeVaultAuthorized,
bool registryAuthorized,
bool feesEnabled_,
uint256 lockFee_,
uint256 splitFee_,
bool isPaused
) {
return (
IFeeVault(feeVault).isLocker(address(this)),
ILockRegistry(registry).isLocker(address(this)),
feesEnabled,
lockFee,
splitFee,
paused()
);
}
}
// ═══════════════════════════════════════════════════════════
// INTERFACE DEFINITIONS
// ═══════════════════════════════════════════════════════════
interface IFeeVault {
function collectFee(address from, uint256 amount, bytes32 serviceId, string calldata serviceLabel) external;
function isLocker(address locker) external view returns (bool);
}
interface ILockRegistry {
function registerLock(address locker, uint256 lockId, address owner, uint64 unlockTime, uint8 lockType) external returns (uint256);
function updateLockOwner(uint256 registryId, address newOwner) external;
function updateUnlockTime(uint256 registryId, uint64 newUnlockTime) external;
function setInactive(uint256 registryId, string calldata reason) external;
function isLocker(address locker) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[ERC-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC-20 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.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
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].
*
* CAUTION: See Security Considerations above.
*/
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 v5.3.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
bool private _paused;
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
/**
* @dev The operation failed because the contract is paused.
*/
error EnforcedPause();
/**
* @dev The operation failed because the contract is not paused.
*/
error ExpectedPause();
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../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.
*
* The initial owner is set to the address provided by the deployer. 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;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @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 {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @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 {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_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 v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
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 value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` 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 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* 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[ERC 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);
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_feeVault","type":"address"},{"internalType":"address","name":"_registry","type":"address"},{"internalType":"address","name":"_safeOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lockFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"splitFee","type":"uint256"}],"name":"FeesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"FeesToggled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"},{"indexed":false,"internalType":"uint64","name":"unlockTime","type":"uint64"}],"name":"LockCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"LockDeactivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"newUnlockTime","type":"uint64"}],"name":"LockExtended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"LockOwnerTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"originalId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"splitAmount","type":"uint128"}],"name":"LockSplit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"}],"name":"LockWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"keepId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"burnId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"totalAmount","type":"uint128"}],"name":"LocksMerged","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":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"registryId","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"RegistryCallFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensRescued","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"MIN_DURATION","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PDGYSTR","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint64","name":"unlockTime","type":"uint64"},{"internalType":"address","name":"beneficiary","type":"address"}],"name":"createLock","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint64","name":"unlockTime","type":"uint64"},{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"createLockWithPermit","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint64","name":"newUnlockTime","type":"uint64"}],"name":"extendLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feesEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getLockInfo","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint64","name":"unlockTime","type":"uint64"},{"internalType":"bool","name":"withdrawn","type":"bool"}],"internalType":"struct IglooLockV2.LockV2","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSystemHealth","outputs":[{"internalType":"bool","name":"feeVaultAuthorized","type":"bool"},{"internalType":"bool","name":"registryAuthorized","type":"bool"},{"internalType":"bool","name":"feesEnabled_","type":"bool"},{"internalType":"uint256","name":"lockFee_","type":"uint256"},{"internalType":"uint256","name":"splitFee_","type":"uint256"},{"internalType":"bool","name":"isPaused","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"hashLockConfig","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"isWithdrawn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"locks","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint64","name":"unlockTime","type":"uint64"},{"internalType":"bool","name":"withdrawn","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"keepId","type":"uint256"},{"internalType":"uint256","name":"burnId","type":"uint256"}],"name":"mergeLocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nextId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOfLock","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseNewLocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rescueTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockFee","type":"uint256"},{"internalType":"uint256","name":"_splitFee","type":"uint256"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"splitFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint128","name":"splitAmount","type":"uint128"}],"name":"splitLock","outputs":[{"internalType":"uint256","name":"newId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"toggleFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenTotalLocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"totalLocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferLockOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpauseNewLocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60c0604052600160028190556908e890a7c0e2a434000060035568e76c46b1de5e9400006004556005805460ff191690911790553480156200003f575f80fd5b5060405162002db438038062002db48339810160408190526200006291620001bf565b60015f55806001600160a01b0381166200009657604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b620000a18162000152565b506001600160a01b038316620000ee5760405162461bcd60e51b81526020600482015260116024820152701a5b9d985b1a5908199959481d985d5b1d607a1b60448201526064016200008d565b6001600160a01b038216620001395760405162461bcd60e51b815260206004820152601060248201526f696e76616c696420726567697374727960801b60448201526064016200008d565b506001600160a01b039182166080521660a05262000206565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b80516001600160a01b0381168114620001ba575f80fd5b919050565b5f805f60608486031215620001d2575f80fd5b620001dd84620001a3565b9250620001ed60208501620001a3565b9150620001fd60408501620001a3565b90509250925092565b60805160a051612b466200026e5f395f81816104080152818161091101528181610b4401528181610ea60152818161110001528181611351015281816117c001526123c001525f818161027701528181610ac60152818161163701526120880152612b465ff3fe608060405234801561000f575f80fd5b50600436106101f2575f3560e01c80637b10399911610114578063b6a6d177116100a9578063d135bacd11610079578063d135bacd14610641578063d4bef64814610654578063d8fb93371461067f578063f2fde38b146106a7578063f4dadc61146106ba575f80fd5b8063b6a6d177146104d5578063c30184b7146104f6578063c9102afd14610522578063cea9d26f1461062e575f80fd5b80638da5cb5b116100e45780638da5cb5b14610491578063a0c9b39c146104a2578063a64e4f8a146104b5578063a69ea776146104c2575f80fd5b80637b1039991461040357806382afd23b1461042a578063858cb1d2146104575780638c15b53a14610476575f80fd5b8063546bae0d1161018a5780635c975abb1161015a5780635c975abb146103c157806361b8ce8c146103df578063715018a6146103e85780637ab6489d146103f0575f80fd5b8063546bae0d1461037f57806355b8391f14610392578063563cdb73146103a557806356a06235146103b8575f80fd5b80633297e094116101c55780633297e0941461026a578063478222c21461027257806347f4f81b146102b15780634980555514610376575f80fd5b80630b78f9c0146101f65780632e1a7d4d1461020b5780632e21059a1461021e57806331a6be8c14610226575b5f80fd5b610209610204366004612692565b610767565b005b6102096102193660046126b2565b6107b6565b610209610a8b565b61022e610a9d565b60408051961515875294151560208701529215159385019390935260608401526080830191909152151560a082015260c0015b60405180910390f35b610209610be3565b6102997f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610261565b6103686102bf3660046126b2565b5f81815260066020908152604091829020825160a0808201855282546001600160a01b039081168084526001850154909116838601526002909301546001600160801b038116838701819052600160801b82046001600160401b03166060808601829052600160c01b90930460ff161515608095860152875180880196909652858801919091529084015282820195909552835180830390910181529301909152815191012090565b604051908152602001610261565b61036860045481565b61036861038d366004612710565b610bf3565b6102096103a0366004612692565b610c24565b6102096103b3366004612761565b610fd8565b61036860035481565b600154600160a01b900460ff165b6040519015158152602001610261565b61036860025481565b61020961121e565b6102096103fe36600461278b565b61122f565b6102997f000000000000000000000000000000000000000000000000000000000000000081565b6103cf6104383660046126b2565b5f90815260066020526040902060020154600160c01b900460ff161590565b6103686104653660046127ac565b60076020525f908152604090205481565b61029973ce2fbf6edfa8b759c4e0c80d73f1aff2a93b054b81565b6001546001600160a01b0316610299565b6103686104b03660046127cc565b6114ca565b6005546103cf9060ff1681565b6102096104d03660046127fa565b61198c565b6104de610e1081565b6040516001600160401b039091168152602001610261565b6103cf6105043660046126b2565b5f90815260066020526040902060020154600160c01b900460ff1690565b6105cf6105303660046126b2565b6040805160a0810182525f80825260208201819052918101829052606081018290526080810191909152505f90815260066020908152604091829020825160a08101845281546001600160a01b03908116825260018301541692810192909252600201546001600160801b03811692820192909252600160801b82046001600160401b03166060820152600160c01b90910460ff161515608082015290565b604051610261919081516001600160a01b039081168252602080840151909116908201526040808301516001600160801b0316908201526060808301516001600160401b03169082015260809182015115159181019190915260a00190565b61020961063c366004612815565b6119db565b61036861064f36600461284e565b611b71565b6102996106623660046126b2565b5f908152600660205260409020600101546001600160a01b031690565b61036861068d3660046127ac565b6001600160a01b03165f9081526007602052604090205490565b6102096106b53660046127ac565b611cf2565b61071c6106c83660046126b2565b60066020525f90815260409020805460018201546002909201546001600160a01b0391821692909116906001600160801b038116906001600160401b03600160801b8204169060ff600160c01b9091041685565b604080516001600160a01b0396871681529590941660208601526001600160801b03909216928401929092526001600160401b0390911660608301521515608082015260a001610261565b61076f611d2c565b6003829055600481905560408051838152602081018390527f64f84976d9c917a44796104a59950fdbd9b3c16a5dd348b546d738301f6bd068910160405180910390a15050565b6107be611d59565b5f81815260066020526040902060018101546001600160a01b031633146108005760405162461bcd60e51b81526004016107f7906128d2565b60405180910390fd5b6002810154600160c01b900460ff161561082c5760405162461bcd60e51b81526004016107f7906128f5565b6002810154600160801b90046001600160401b03164210156108795760405162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b60448201526064016107f7565b60028101805460ff60c01b198116600160c01b1790915581546001600160a01b03165f90815260076020526040812080546001600160801b03909316929091906108c4908490612931565b90915550506001810154600282015482546108f6926001600160a01b03918216929116906001600160801b0316611d81565b5f828152600860205260408082205490516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163e3c2678f60e01b916109489190602401612944565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516109869190612972565b5f604051808303815f865af19150503d805f81146109bf576040519150601f19603f3d011682016040523d82523d5f602084013e6109c4565b606091505b5050905080610a28575f83815260086020526040908190205490515f80516020612af183398151915290610a1f9060208082526013908201527219195858dd1a5d985d1a5bdb8819985a5b1959606a1b604082015260600190565b60405180910390a25b600182015460028301546040516001600160801b0390911681526001600160a01b039091169084907f8d5feba0638fa3789c58cd3222c17a418c425e6e52d8fdb5928973405ff25e739060200160405180910390a35050610a8860015f55565b50565b610a93611d2c565b610a9b611de5565b565b604051630bb18f5f60e21b81523060048201525f90819081908190819081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632ec63d7c90602401602060405180830381865afa158015610b0b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b2f919061299e565b604051630bb18f5f60e21b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632ec63d7c90602401602060405180830381865afa158015610b91573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bb5919061299e565b60055460035460045460015460ff93841693600160a01b90910416949b939a50919850965094509092509050565b610beb611d2c565b610a9b611e45565b5f610bfc611e81565b610c04611d59565b610c118585858533611eac565b9050610c1c60015f55565b949350505050565b610c2c611d59565b808203610c655760405162461bcd60e51b81526020600482015260076024820152661cd85b59481a5960ca1b60448201526064016107f7565b5f82815260066020526040808220838352912060018201546001600160a01b031633148015610ca0575060018101546001600160a01b031633145b610cbc5760405162461bcd60e51b81526004016107f7906128d2565b6002820154600160c01b900460ff16158015610ce457506002810154600160c01b900460ff16155b610d005760405162461bcd60e51b81526004016107f7906128f5565b805482546001600160a01b03908116911614610d515760405162461bcd60e51b815260206004820152601060248201526f646966666572656e7420746f6b656e7360801b60448201526064016107f7565b60028181015490830154600160801b918290046001600160401b03908116929091041614610dba5760405162461bcd60e51b8152602060048201526016602482015275646966666572656e7420756e6c6f636b2074696d657360501b60448201526064016107f7565b600280820154908301545f91610ddc916001600160801b0391821691166129b9565b600284810180546001600160801b0384166fffffffffffffffffffffffffffffffff199091168117909155908401805460ff60c01b1916600160c01b179055604051908152909150849086907f4ba3761912528c2f207124bd3439dbd5a9d56ec5b3e07f45ebdd889f479d11759060200160405180910390a3837ff05fa922e88271b95c949209f9863461e09f81d5e92b69b2ec853c4ed24271c1604051610e83906129e0565b60405180910390a25f848152600860205260408082205490516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163e3c2678f60e01b91610edd9190602401612a05565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610f1b9190612972565b5f604051808303815f865af19150503d805f8114610f54576040519150601f19603f3d011682016040523d82523d5f602084013e610f59565b606091505b5050905080610fc7575f85815260086020526040908190205490515f80516020612af183398151915290610fbe9060208082526019908201527f6d6572676520646561637469766174696f6e206661696c656400000000000000604082015260600190565b60405180910390a25b50505050610fd460015f55565b5050565b610fe0611d59565b5f82815260066020526040902060018101546001600160a01b031633146110195760405162461bcd60e51b81526004016107f7906128d2565b6002810154600160c01b900460ff16156110455760405162461bcd60e51b81526004016107f7906128f5565b6001600160a01b03821661108a5760405162461bcd60e51b815260206004820152600c60248201526b7a65726f206164647265737360a01b60448201526064016107f7565b6001810180546001600160a01b038481166001600160a01b0319831681179093555f868152600860209081526040808320548151602481019190915260448082019790975281518082039097018752606401815290850180516001600160e01b03166306035b4360e11b179052519282169390927f00000000000000000000000000000000000000000000000000000000000000009092169161112d9190612972565b5f604051808303815f865af19150503d805f8114611166576040519150601f19603f3d011682016040523d82523d5f602084013e61116b565b606091505b50509050806111d1575f85815260086020526040908190205490515f80516020612af1833981519152906111c8906020808252601590820152741bdddb995c881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b60405180910390a25b836001600160a01b0316826001600160a01b0316867fc38d2bc2ef74cd5e37303032cf09280951bfedf031eb48f7de7a7405cf2ce2f060405160405180910390a4505050610fd460015f55565b611226611d2c565b610a9b5f61256c565b5f82815260066020526040902060018101546001600160a01b031633146112685760405162461bcd60e51b81526004016107f7906128d2565b6002810154600160c01b900460ff16156112b85760405162461bcd60e51b815260206004820152601160248201527030b63932b0b23c903bb4ba34323930bbb760791b60448201526064016107f7565b60028101546001600160401b03600160801b90910481169083161161130d5760405162461bcd60e51b815260206004820152600b60248201526a1b5d5cdd08195e1d195b9960aa1b60448201526064016107f7565b6002810180546001600160401b038416600160801b0267ffffffffffffffff60801b199091161790555f838152600860205260408082205490516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163f278d4a760e01b9161139c919087906024019182526001600160401b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516113da9190612972565b5f604051808303815f865af19150503d805f8114611413576040519150601f19603f3d011682016040523d82523d5f602084013e611418565b606091505b5050905080611486575f84815260086020526040908190205490515f80516020612af18339815191529061147d9060208082526019908201527f756e6c6f636b2074696d6520757064617465206661696c656400000000000000604082015260600190565b60405180910390a25b6040516001600160401b038416815284907f7189acbbb826f9a514e1d187ea8f1e3eff0c63b70f069ddd1a717124845ca7849060200160405180910390a250505050565b5f6114d3611e81565b6114db611d59565b5f83815260066020526040902060018101546001600160a01b031633146115145760405162461bcd60e51b81526004016107f7906128d2565b6002810154600160c01b900460ff16156115405760405162461bcd60e51b81526004016107f7906128f5565b5f836001600160801b0316118015611568575060028101546001600160801b03908116908416105b6115a45760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081cdc1b1a5d609a1b60448201526064016107f7565b60055460ff1680156115b757505f600454115b156116975760048054604080518082018252600880825267158c97d4d413125560c21b6020909201829052915163a2be599b60e01b8152339481019490945260248401929092527f9786e5d2c466407cbe6b189d49ea4f02a8dd50a8335f107aa44b3dfce75391cc604484015260806064840152608483015260a48201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a2be599b9060c4015f604051808303815f87803b158015611680575f80fd5b505af1158015611692573d5f803e3d5ffd5b505050505b60028054905f6116a683612a30565b909155506040805160a08101825283546001600160a01b039081168252600180860154821660208085019182526001600160801b03808b168688019081526002808b0180546001600160401b03600160801b91829004811660608c019081525f60808d018181528f825260069099529c8d209b518c54908c166001600160a01b0319918216178d559851998c0180549a909b169990981698909817909855915197018054945193511515600160c01b0260ff60c01b19949096169096026001600160c01b0319909416968216969096179290921716919091179091558154939550869391929161179891859116612a48565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d3601bc160e01b3086866001015f9054906101000a90046001600160a01b03168760020160109054906101000a90046001600160401b03165f604051602401611836959493929190612a68565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516118749190612972565b5f604051808303815f865af19150503d805f81146118ad576040519150601f19603f3d011682016040523d82523d5f602084013e6118b2565b606091505b509150915081156118e457808060200190518101906118d19190612aa6565b5f8581526008602052604090205561193a565b5f5f80516020612af18339815191526040516119319060208082526019908201527f73706c697420726567697374726174696f6e206661696c656400000000000000604082015260600190565b60405180910390a25b6040516001600160801b0386168152849087907f074e5eea98d6d562ad96f14001b46ce564debdd394094acb75f344dade6f36459060200160405180910390a350505061198660015f55565b92915050565b611994611d2c565b6005805460ff19168215159081179091556040519081527fc97260ffb3df6b903cdfd59e3b5b21a896404903a8e8a83bf60ba3fca365fbe59060200160405180910390a150565b6119e3611d2c565b6001600160a01b038216611a2d5760405162461bcd60e51b81526020600482015260116024820152701a5b9d985b1a59081c9958da5c1a595b9d607a1b60448201526064016107f7565b6040516370a0823160e01b81523060048201525f906001600160a01b038516906370a0823190602401602060405180830381865afa158015611a71573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a959190612aa6565b6001600160a01b0385165f90815260076020526040902054909150611aba8183612931565b831115611b095760405162461bcd60e51b815260206004820152601a60248201527f63616e6e6f7420746f756368206c6f636b656420746f6b656e7300000000000060448201526064016107f7565b611b1d6001600160a01b0386168585611d81565b836001600160a01b0316856001600160a01b03167f77023e19c7343ad491fd706c36335ca0e738340a91f29b1fd81e2673d44896c485604051611b6291815260200190565b60405180910390a35050505050565b5f611b7a611e81565b611b82611d59565b60405163d505accf60e01b81523360048201523060248201526001600160801b03891660448201526064810186905260ff8516608482015260a4810184905260c481018390526001600160a01b038a169063d505accf9060e4015f604051808303815f87803b158015611bf3575f80fd5b505af1158015611c05573d5f803e3d5ffd5b5050604051636eb1769f60e11b81523360048201523060248201526001600160801b038b1692506001600160a01b038c16915063dd62ed3e90604401602060405180830381865afa158015611c5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c809190612aa6565b1015611cce5760405162461bcd60e51b815260206004820152601860248201527f7065726d69742f616c6c6f77616e636520746f6f206c6f77000000000000000060448201526064016107f7565b611cdb8989898933611eac565b9050611ce660015f55565b98975050505050505050565b611cfa611d2c565b6001600160a01b038116611d2357604051631e4fbdf760e01b81525f60048201526024016107f7565b610a888161256c565b6001546001600160a01b03163314610a9b5760405163118cdaa760e01b81523360048201526024016107f7565b60025f5403611d7b57604051633ee5aeb560e01b815260040160405180910390fd5b60025f55565b6040516001600160a01b03838116602483015260448201839052611de091859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506125bd565b505050565b611ded611e81565b6001805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611e283390565b6040516001600160a01b03909116815260200160405180910390a1565b611e4d61262f565b6001805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33611e28565b600154600160a01b900460ff1615610a9b5760405163d93c066560e01b815260040160405180910390fd5b5f6001600160a01b038316611ef55760405162461bcd60e51b815260206004820152600f60248201526e6261642062656e656669636961727960881b60448201526064016107f7565b5f856001600160801b031611611f3b5760405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc8185b5bdd5b9d60aa1b60448201526064016107f7565b611f47610e1042612abd565b6001600160401b0316846001600160401b03161015611f9a5760405162461bcd60e51b815260206004820152600f60248201526e3ab73637b1b5903a37b79039b7b7b760891b60448201526064016107f7565b5f866001600160a01b03163b11611fec5760405162461bcd60e51b81526020600482015260166024820152751a5b9d985b1a59081d1bdad95b8818dbdb9d1c9858dd60521b60448201526064016107f7565b60055460ff168015611fff57505f600354115b156120e25760035460408051808201825260078082526656325f4c4f434b60c81b6020909201829052915163a2be599b60e01b81526001600160a01b03868116600483015260248201949094527fad836d6fe1e4dc6814ab434e8fe36c3eaaa2e6ab849a91a2e4a37a9ba01e5c91604482015260806064820152608481019290925260a48201527f00000000000000000000000000000000000000000000000000000000000000009091169063a2be599b9060c4015f604051808303815f87803b1580156120cb575f80fd5b505af11580156120dd573d5f803e3d5ffd5b505050505b6040516370a0823160e01b81523060048201525f906001600160a01b038816906370a0823190602401602060405180830381865afa158015612126573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061214a9190612aa6565b905061216a6001600160a01b03881684306001600160801b038a16612659565b6040516370a0823160e01b81523060048201525f906001600160a01b038916906370a0823190602401602060405180830381865afa1580156121ae573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d29190612aa6565b90506001600160801b0387166121e88383612931565b146122355760405162461bcd60e51b815260206004820181905260248201527f6465666c6174696f6e61727920746f6b656e206e6f7420737570706f7274656460448201526064016107f7565b60028054905f61224483612a30565b9190505592506040518060a00160405280896001600160a01b03168152602001866001600160a01b03168152602001886001600160801b03168152602001876001600160401b031681526020015f151581525060065f8581526020019081526020015f205f820151815f015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506040820151816002015f6101000a8154816001600160801b0302191690836001600160801b0316021790555060608201518160020160106101000a8154816001600160401b0302191690836001600160401b0316021790555060808201518160020160186101000a81548160ff021916908315150217905550905050866001600160801b031660075f8a6001600160a01b03166001600160a01b031681526020019081526020015f205f8282546123b59190612add565b925050819055505f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d3601bc160e01b30878a8c5f604051602401612409959493929190612a68565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516124479190612972565b5f604051808303815f865af19150503d805f8114612480576040519150601f19603f3d011682016040523d82523d5f602084013e612485565b606091505b509150915081156124b757808060200190518101906124a49190612aa6565b5f86815260086020526040902055612503565b5f5f80516020612af18339815191526040516124fa906020808252601390820152721c9959da5cdd1c985d1a5bdb8819985a5b1959606a1b604082015260600190565b60405180910390a25b604080516001600160801b038b1681526001600160401b038a1660208201526001600160a01b03808a1692908d169188917fe7bcbc5c65377f8c5d003ac45d142bc8f1150f8482724c5bea6e452d958d569e910160405180910390a45050505095945050505050565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f8060205f8451602086015f885af1806125dc576040513d5f823e3d81fd5b50505f513d915081156125f3578060011415612600565b6001600160a01b0384163b155b1561262957604051635274afe760e01b81526001600160a01b03851660048201526024016107f7565b50505050565b600154600160a01b900460ff16610a9b57604051638dfc202b60e01b815260040160405180910390fd5b6040516001600160a01b0384811660248301528381166044830152606482018390526126299186918216906323b872dd90608401611dae565b5f80604083850312156126a3575f80fd5b50508035926020909101359150565b5f602082840312156126c2575f80fd5b5035919050565b80356001600160a01b03811681146126df575f80fd5b919050565b80356001600160801b03811681146126df575f80fd5b80356001600160401b03811681146126df575f80fd5b5f805f8060808587031215612723575f80fd5b61272c856126c9565b935061273a602086016126e4565b9250612748604086016126fa565b9150612756606086016126c9565b905092959194509250565b5f8060408385031215612772575f80fd5b82359150612782602084016126c9565b90509250929050565b5f806040838503121561279c575f80fd5b82359150612782602084016126fa565b5f602082840312156127bc575f80fd5b6127c5826126c9565b9392505050565b5f80604083850312156127dd575f80fd5b82359150612782602084016126e4565b8015158114610a88575f80fd5b5f6020828403121561280a575f80fd5b81356127c5816127ed565b5f805f60608486031215612827575f80fd5b612830846126c9565b925061283e602085016126c9565b9150604084013590509250925092565b5f805f805f805f80610100898b031215612866575f80fd5b61286f896126c9565b975061287d60208a016126e4565b965061288b60408a016126fa565b955061289960608a016126c9565b94506080890135935060a089013560ff811681146128b5575f80fd5b979a969950949793969295929450505060c08201359160e0013590565b6020808252600990820152683737ba1037bbb732b960b91b604082015260600190565b602081525f6119866020830160098152683bb4ba34323930bbb760b91b602082015260400190565b634e487b7160e01b5f52601160045260245ffd5b818103818111156119865761198661291d565b818152604060208201525f6127c56040830160098152683bb4ba34323930bbb760b91b602082015260400190565b5f82515f5b818110156129915760208186018101518583015201612977565b505f920191825250919050565b5f602082840312156129ae575f80fd5b81516127c5816127ed565b6001600160801b038181168382160190808211156129d9576129d961291d565b5092915050565b602081525f6119866020830160068152651b595c99d95960d21b602082015260400190565b818152604060208201525f6127c56040830160068152651b595c99d95960d21b602082015260400190565b5f60018201612a4157612a4161291d565b5060010190565b6001600160801b038281168282160390808211156129d9576129d961291d565b6001600160a01b03958616815260208101949094529190931660408301526001600160401b03909216606082015260ff909116608082015260a00190565b5f60208284031215612ab6575f80fd5b5051919050565b6001600160401b038181168382160190808211156129d9576129d961291d565b808201808211156119865761198661291d56fe35cb73aa7fbe8337a0662c3921ca7b2c60e9184a073a772efb5d8f4b6183fa0ca264697066735822122045ff0bda496ea83f74d23ea8f8cf4573eb45cb3bb775a943437c234ec4d2156164736f6c6343000818003300000000000000000000000095c88c7e13016de4a78ce63c3e601b58ddc0f3d9000000000000000000000000bc635e846825ad70af0585bdaf36a52a659333010000000000000000000000009ef87811e160fb95735ca3325ee29d2330e3d69e
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106101f2575f3560e01c80637b10399911610114578063b6a6d177116100a9578063d135bacd11610079578063d135bacd14610641578063d4bef64814610654578063d8fb93371461067f578063f2fde38b146106a7578063f4dadc61146106ba575f80fd5b8063b6a6d177146104d5578063c30184b7146104f6578063c9102afd14610522578063cea9d26f1461062e575f80fd5b80638da5cb5b116100e45780638da5cb5b14610491578063a0c9b39c146104a2578063a64e4f8a146104b5578063a69ea776146104c2575f80fd5b80637b1039991461040357806382afd23b1461042a578063858cb1d2146104575780638c15b53a14610476575f80fd5b8063546bae0d1161018a5780635c975abb1161015a5780635c975abb146103c157806361b8ce8c146103df578063715018a6146103e85780637ab6489d146103f0575f80fd5b8063546bae0d1461037f57806355b8391f14610392578063563cdb73146103a557806356a06235146103b8575f80fd5b80633297e094116101c55780633297e0941461026a578063478222c21461027257806347f4f81b146102b15780634980555514610376575f80fd5b80630b78f9c0146101f65780632e1a7d4d1461020b5780632e21059a1461021e57806331a6be8c14610226575b5f80fd5b610209610204366004612692565b610767565b005b6102096102193660046126b2565b6107b6565b610209610a8b565b61022e610a9d565b60408051961515875294151560208701529215159385019390935260608401526080830191909152151560a082015260c0015b60405180910390f35b610209610be3565b6102997f00000000000000000000000095c88c7e13016de4a78ce63c3e601b58ddc0f3d981565b6040516001600160a01b039091168152602001610261565b6103686102bf3660046126b2565b5f81815260066020908152604091829020825160a0808201855282546001600160a01b039081168084526001850154909116838601526002909301546001600160801b038116838701819052600160801b82046001600160401b03166060808601829052600160c01b90930460ff161515608095860152875180880196909652858801919091529084015282820195909552835180830390910181529301909152815191012090565b604051908152602001610261565b61036860045481565b61036861038d366004612710565b610bf3565b6102096103a0366004612692565b610c24565b6102096103b3366004612761565b610fd8565b61036860035481565b600154600160a01b900460ff165b6040519015158152602001610261565b61036860025481565b61020961121e565b6102096103fe36600461278b565b61122f565b6102997f000000000000000000000000bc635e846825ad70af0585bdaf36a52a6593330181565b6103cf6104383660046126b2565b5f90815260066020526040902060020154600160c01b900460ff161590565b6103686104653660046127ac565b60076020525f908152604090205481565b61029973ce2fbf6edfa8b759c4e0c80d73f1aff2a93b054b81565b6001546001600160a01b0316610299565b6103686104b03660046127cc565b6114ca565b6005546103cf9060ff1681565b6102096104d03660046127fa565b61198c565b6104de610e1081565b6040516001600160401b039091168152602001610261565b6103cf6105043660046126b2565b5f90815260066020526040902060020154600160c01b900460ff1690565b6105cf6105303660046126b2565b6040805160a0810182525f80825260208201819052918101829052606081018290526080810191909152505f90815260066020908152604091829020825160a08101845281546001600160a01b03908116825260018301541692810192909252600201546001600160801b03811692820192909252600160801b82046001600160401b03166060820152600160c01b90910460ff161515608082015290565b604051610261919081516001600160a01b039081168252602080840151909116908201526040808301516001600160801b0316908201526060808301516001600160401b03169082015260809182015115159181019190915260a00190565b61020961063c366004612815565b6119db565b61036861064f36600461284e565b611b71565b6102996106623660046126b2565b5f908152600660205260409020600101546001600160a01b031690565b61036861068d3660046127ac565b6001600160a01b03165f9081526007602052604090205490565b6102096106b53660046127ac565b611cf2565b61071c6106c83660046126b2565b60066020525f90815260409020805460018201546002909201546001600160a01b0391821692909116906001600160801b038116906001600160401b03600160801b8204169060ff600160c01b9091041685565b604080516001600160a01b0396871681529590941660208601526001600160801b03909216928401929092526001600160401b0390911660608301521515608082015260a001610261565b61076f611d2c565b6003829055600481905560408051838152602081018390527f64f84976d9c917a44796104a59950fdbd9b3c16a5dd348b546d738301f6bd068910160405180910390a15050565b6107be611d59565b5f81815260066020526040902060018101546001600160a01b031633146108005760405162461bcd60e51b81526004016107f7906128d2565b60405180910390fd5b6002810154600160c01b900460ff161561082c5760405162461bcd60e51b81526004016107f7906128f5565b6002810154600160801b90046001600160401b03164210156108795760405162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b60448201526064016107f7565b60028101805460ff60c01b198116600160c01b1790915581546001600160a01b03165f90815260076020526040812080546001600160801b03909316929091906108c4908490612931565b90915550506001810154600282015482546108f6926001600160a01b03918216929116906001600160801b0316611d81565b5f828152600860205260408082205490516001600160a01b037f000000000000000000000000bc635e846825ad70af0585bdaf36a52a65933301169163e3c2678f60e01b916109489190602401612944565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516109869190612972565b5f604051808303815f865af19150503d805f81146109bf576040519150601f19603f3d011682016040523d82523d5f602084013e6109c4565b606091505b5050905080610a28575f83815260086020526040908190205490515f80516020612af183398151915290610a1f9060208082526013908201527219195858dd1a5d985d1a5bdb8819985a5b1959606a1b604082015260600190565b60405180910390a25b600182015460028301546040516001600160801b0390911681526001600160a01b039091169084907f8d5feba0638fa3789c58cd3222c17a418c425e6e52d8fdb5928973405ff25e739060200160405180910390a35050610a8860015f55565b50565b610a93611d2c565b610a9b611de5565b565b604051630bb18f5f60e21b81523060048201525f90819081908190819081906001600160a01b037f00000000000000000000000095c88c7e13016de4a78ce63c3e601b58ddc0f3d91690632ec63d7c90602401602060405180830381865afa158015610b0b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b2f919061299e565b604051630bb18f5f60e21b81523060048201527f000000000000000000000000bc635e846825ad70af0585bdaf36a52a659333016001600160a01b031690632ec63d7c90602401602060405180830381865afa158015610b91573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bb5919061299e565b60055460035460045460015460ff93841693600160a01b90910416949b939a50919850965094509092509050565b610beb611d2c565b610a9b611e45565b5f610bfc611e81565b610c04611d59565b610c118585858533611eac565b9050610c1c60015f55565b949350505050565b610c2c611d59565b808203610c655760405162461bcd60e51b81526020600482015260076024820152661cd85b59481a5960ca1b60448201526064016107f7565b5f82815260066020526040808220838352912060018201546001600160a01b031633148015610ca0575060018101546001600160a01b031633145b610cbc5760405162461bcd60e51b81526004016107f7906128d2565b6002820154600160c01b900460ff16158015610ce457506002810154600160c01b900460ff16155b610d005760405162461bcd60e51b81526004016107f7906128f5565b805482546001600160a01b03908116911614610d515760405162461bcd60e51b815260206004820152601060248201526f646966666572656e7420746f6b656e7360801b60448201526064016107f7565b60028181015490830154600160801b918290046001600160401b03908116929091041614610dba5760405162461bcd60e51b8152602060048201526016602482015275646966666572656e7420756e6c6f636b2074696d657360501b60448201526064016107f7565b600280820154908301545f91610ddc916001600160801b0391821691166129b9565b600284810180546001600160801b0384166fffffffffffffffffffffffffffffffff199091168117909155908401805460ff60c01b1916600160c01b179055604051908152909150849086907f4ba3761912528c2f207124bd3439dbd5a9d56ec5b3e07f45ebdd889f479d11759060200160405180910390a3837ff05fa922e88271b95c949209f9863461e09f81d5e92b69b2ec853c4ed24271c1604051610e83906129e0565b60405180910390a25f848152600860205260408082205490516001600160a01b037f000000000000000000000000bc635e846825ad70af0585bdaf36a52a65933301169163e3c2678f60e01b91610edd9190602401612a05565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610f1b9190612972565b5f604051808303815f865af19150503d805f8114610f54576040519150601f19603f3d011682016040523d82523d5f602084013e610f59565b606091505b5050905080610fc7575f85815260086020526040908190205490515f80516020612af183398151915290610fbe9060208082526019908201527f6d6572676520646561637469766174696f6e206661696c656400000000000000604082015260600190565b60405180910390a25b50505050610fd460015f55565b5050565b610fe0611d59565b5f82815260066020526040902060018101546001600160a01b031633146110195760405162461bcd60e51b81526004016107f7906128d2565b6002810154600160c01b900460ff16156110455760405162461bcd60e51b81526004016107f7906128f5565b6001600160a01b03821661108a5760405162461bcd60e51b815260206004820152600c60248201526b7a65726f206164647265737360a01b60448201526064016107f7565b6001810180546001600160a01b038481166001600160a01b0319831681179093555f868152600860209081526040808320548151602481019190915260448082019790975281518082039097018752606401815290850180516001600160e01b03166306035b4360e11b179052519282169390927f000000000000000000000000bc635e846825ad70af0585bdaf36a52a659333019092169161112d9190612972565b5f604051808303815f865af19150503d805f8114611166576040519150601f19603f3d011682016040523d82523d5f602084013e61116b565b606091505b50509050806111d1575f85815260086020526040908190205490515f80516020612af1833981519152906111c8906020808252601590820152741bdddb995c881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b60405180910390a25b836001600160a01b0316826001600160a01b0316867fc38d2bc2ef74cd5e37303032cf09280951bfedf031eb48f7de7a7405cf2ce2f060405160405180910390a4505050610fd460015f55565b611226611d2c565b610a9b5f61256c565b5f82815260066020526040902060018101546001600160a01b031633146112685760405162461bcd60e51b81526004016107f7906128d2565b6002810154600160c01b900460ff16156112b85760405162461bcd60e51b815260206004820152601160248201527030b63932b0b23c903bb4ba34323930bbb760791b60448201526064016107f7565b60028101546001600160401b03600160801b90910481169083161161130d5760405162461bcd60e51b815260206004820152600b60248201526a1b5d5cdd08195e1d195b9960aa1b60448201526064016107f7565b6002810180546001600160401b038416600160801b0267ffffffffffffffff60801b199091161790555f838152600860205260408082205490516001600160a01b037f000000000000000000000000bc635e846825ad70af0585bdaf36a52a65933301169163f278d4a760e01b9161139c919087906024019182526001600160401b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516113da9190612972565b5f604051808303815f865af19150503d805f8114611413576040519150601f19603f3d011682016040523d82523d5f602084013e611418565b606091505b5050905080611486575f84815260086020526040908190205490515f80516020612af18339815191529061147d9060208082526019908201527f756e6c6f636b2074696d6520757064617465206661696c656400000000000000604082015260600190565b60405180910390a25b6040516001600160401b038416815284907f7189acbbb826f9a514e1d187ea8f1e3eff0c63b70f069ddd1a717124845ca7849060200160405180910390a250505050565b5f6114d3611e81565b6114db611d59565b5f83815260066020526040902060018101546001600160a01b031633146115145760405162461bcd60e51b81526004016107f7906128d2565b6002810154600160c01b900460ff16156115405760405162461bcd60e51b81526004016107f7906128f5565b5f836001600160801b0316118015611568575060028101546001600160801b03908116908416105b6115a45760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081cdc1b1a5d609a1b60448201526064016107f7565b60055460ff1680156115b757505f600454115b156116975760048054604080518082018252600880825267158c97d4d413125560c21b6020909201829052915163a2be599b60e01b8152339481019490945260248401929092527f9786e5d2c466407cbe6b189d49ea4f02a8dd50a8335f107aa44b3dfce75391cc604484015260806064840152608483015260a48201527f00000000000000000000000095c88c7e13016de4a78ce63c3e601b58ddc0f3d96001600160a01b03169063a2be599b9060c4015f604051808303815f87803b158015611680575f80fd5b505af1158015611692573d5f803e3d5ffd5b505050505b60028054905f6116a683612a30565b909155506040805160a08101825283546001600160a01b039081168252600180860154821660208085019182526001600160801b03808b168688019081526002808b0180546001600160401b03600160801b91829004811660608c019081525f60808d018181528f825260069099529c8d209b518c54908c166001600160a01b0319918216178d559851998c0180549a909b169990981698909817909855915197018054945193511515600160c01b0260ff60c01b19949096169096026001600160c01b0319909416968216969096179290921716919091179091558154939550869391929161179891859116612a48565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505f807f000000000000000000000000bc635e846825ad70af0585bdaf36a52a659333016001600160a01b031663d3601bc160e01b3086866001015f9054906101000a90046001600160a01b03168760020160109054906101000a90046001600160401b03165f604051602401611836959493929190612a68565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516118749190612972565b5f604051808303815f865af19150503d805f81146118ad576040519150601f19603f3d011682016040523d82523d5f602084013e6118b2565b606091505b509150915081156118e457808060200190518101906118d19190612aa6565b5f8581526008602052604090205561193a565b5f5f80516020612af18339815191526040516119319060208082526019908201527f73706c697420726567697374726174696f6e206661696c656400000000000000604082015260600190565b60405180910390a25b6040516001600160801b0386168152849087907f074e5eea98d6d562ad96f14001b46ce564debdd394094acb75f344dade6f36459060200160405180910390a350505061198660015f55565b92915050565b611994611d2c565b6005805460ff19168215159081179091556040519081527fc97260ffb3df6b903cdfd59e3b5b21a896404903a8e8a83bf60ba3fca365fbe59060200160405180910390a150565b6119e3611d2c565b6001600160a01b038216611a2d5760405162461bcd60e51b81526020600482015260116024820152701a5b9d985b1a59081c9958da5c1a595b9d607a1b60448201526064016107f7565b6040516370a0823160e01b81523060048201525f906001600160a01b038516906370a0823190602401602060405180830381865afa158015611a71573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a959190612aa6565b6001600160a01b0385165f90815260076020526040902054909150611aba8183612931565b831115611b095760405162461bcd60e51b815260206004820152601a60248201527f63616e6e6f7420746f756368206c6f636b656420746f6b656e7300000000000060448201526064016107f7565b611b1d6001600160a01b0386168585611d81565b836001600160a01b0316856001600160a01b03167f77023e19c7343ad491fd706c36335ca0e738340a91f29b1fd81e2673d44896c485604051611b6291815260200190565b60405180910390a35050505050565b5f611b7a611e81565b611b82611d59565b60405163d505accf60e01b81523360048201523060248201526001600160801b03891660448201526064810186905260ff8516608482015260a4810184905260c481018390526001600160a01b038a169063d505accf9060e4015f604051808303815f87803b158015611bf3575f80fd5b505af1158015611c05573d5f803e3d5ffd5b5050604051636eb1769f60e11b81523360048201523060248201526001600160801b038b1692506001600160a01b038c16915063dd62ed3e90604401602060405180830381865afa158015611c5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c809190612aa6565b1015611cce5760405162461bcd60e51b815260206004820152601860248201527f7065726d69742f616c6c6f77616e636520746f6f206c6f77000000000000000060448201526064016107f7565b611cdb8989898933611eac565b9050611ce660015f55565b98975050505050505050565b611cfa611d2c565b6001600160a01b038116611d2357604051631e4fbdf760e01b81525f60048201526024016107f7565b610a888161256c565b6001546001600160a01b03163314610a9b5760405163118cdaa760e01b81523360048201526024016107f7565b60025f5403611d7b57604051633ee5aeb560e01b815260040160405180910390fd5b60025f55565b6040516001600160a01b03838116602483015260448201839052611de091859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506125bd565b505050565b611ded611e81565b6001805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611e283390565b6040516001600160a01b03909116815260200160405180910390a1565b611e4d61262f565b6001805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33611e28565b600154600160a01b900460ff1615610a9b5760405163d93c066560e01b815260040160405180910390fd5b5f6001600160a01b038316611ef55760405162461bcd60e51b815260206004820152600f60248201526e6261642062656e656669636961727960881b60448201526064016107f7565b5f856001600160801b031611611f3b5760405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc8185b5bdd5b9d60aa1b60448201526064016107f7565b611f47610e1042612abd565b6001600160401b0316846001600160401b03161015611f9a5760405162461bcd60e51b815260206004820152600f60248201526e3ab73637b1b5903a37b79039b7b7b760891b60448201526064016107f7565b5f866001600160a01b03163b11611fec5760405162461bcd60e51b81526020600482015260166024820152751a5b9d985b1a59081d1bdad95b8818dbdb9d1c9858dd60521b60448201526064016107f7565b60055460ff168015611fff57505f600354115b156120e25760035460408051808201825260078082526656325f4c4f434b60c81b6020909201829052915163a2be599b60e01b81526001600160a01b03868116600483015260248201949094527fad836d6fe1e4dc6814ab434e8fe36c3eaaa2e6ab849a91a2e4a37a9ba01e5c91604482015260806064820152608481019290925260a48201527f00000000000000000000000095c88c7e13016de4a78ce63c3e601b58ddc0f3d99091169063a2be599b9060c4015f604051808303815f87803b1580156120cb575f80fd5b505af11580156120dd573d5f803e3d5ffd5b505050505b6040516370a0823160e01b81523060048201525f906001600160a01b038816906370a0823190602401602060405180830381865afa158015612126573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061214a9190612aa6565b905061216a6001600160a01b03881684306001600160801b038a16612659565b6040516370a0823160e01b81523060048201525f906001600160a01b038916906370a0823190602401602060405180830381865afa1580156121ae573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d29190612aa6565b90506001600160801b0387166121e88383612931565b146122355760405162461bcd60e51b815260206004820181905260248201527f6465666c6174696f6e61727920746f6b656e206e6f7420737570706f7274656460448201526064016107f7565b60028054905f61224483612a30565b9190505592506040518060a00160405280896001600160a01b03168152602001866001600160a01b03168152602001886001600160801b03168152602001876001600160401b031681526020015f151581525060065f8581526020019081526020015f205f820151815f015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506040820151816002015f6101000a8154816001600160801b0302191690836001600160801b0316021790555060608201518160020160106101000a8154816001600160401b0302191690836001600160401b0316021790555060808201518160020160186101000a81548160ff021916908315150217905550905050866001600160801b031660075f8a6001600160a01b03166001600160a01b031681526020019081526020015f205f8282546123b59190612add565b925050819055505f807f000000000000000000000000bc635e846825ad70af0585bdaf36a52a659333016001600160a01b031663d3601bc160e01b30878a8c5f604051602401612409959493929190612a68565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516124479190612972565b5f604051808303815f865af19150503d805f8114612480576040519150601f19603f3d011682016040523d82523d5f602084013e612485565b606091505b509150915081156124b757808060200190518101906124a49190612aa6565b5f86815260086020526040902055612503565b5f5f80516020612af18339815191526040516124fa906020808252601390820152721c9959da5cdd1c985d1a5bdb8819985a5b1959606a1b604082015260600190565b60405180910390a25b604080516001600160801b038b1681526001600160401b038a1660208201526001600160a01b03808a1692908d169188917fe7bcbc5c65377f8c5d003ac45d142bc8f1150f8482724c5bea6e452d958d569e910160405180910390a45050505095945050505050565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f8060205f8451602086015f885af1806125dc576040513d5f823e3d81fd5b50505f513d915081156125f3578060011415612600565b6001600160a01b0384163b155b1561262957604051635274afe760e01b81526001600160a01b03851660048201526024016107f7565b50505050565b600154600160a01b900460ff16610a9b57604051638dfc202b60e01b815260040160405180910390fd5b6040516001600160a01b0384811660248301528381166044830152606482018390526126299186918216906323b872dd90608401611dae565b5f80604083850312156126a3575f80fd5b50508035926020909101359150565b5f602082840312156126c2575f80fd5b5035919050565b80356001600160a01b03811681146126df575f80fd5b919050565b80356001600160801b03811681146126df575f80fd5b80356001600160401b03811681146126df575f80fd5b5f805f8060808587031215612723575f80fd5b61272c856126c9565b935061273a602086016126e4565b9250612748604086016126fa565b9150612756606086016126c9565b905092959194509250565b5f8060408385031215612772575f80fd5b82359150612782602084016126c9565b90509250929050565b5f806040838503121561279c575f80fd5b82359150612782602084016126fa565b5f602082840312156127bc575f80fd5b6127c5826126c9565b9392505050565b5f80604083850312156127dd575f80fd5b82359150612782602084016126e4565b8015158114610a88575f80fd5b5f6020828403121561280a575f80fd5b81356127c5816127ed565b5f805f60608486031215612827575f80fd5b612830846126c9565b925061283e602085016126c9565b9150604084013590509250925092565b5f805f805f805f80610100898b031215612866575f80fd5b61286f896126c9565b975061287d60208a016126e4565b965061288b60408a016126fa565b955061289960608a016126c9565b94506080890135935060a089013560ff811681146128b5575f80fd5b979a969950949793969295929450505060c08201359160e0013590565b6020808252600990820152683737ba1037bbb732b960b91b604082015260600190565b602081525f6119866020830160098152683bb4ba34323930bbb760b91b602082015260400190565b634e487b7160e01b5f52601160045260245ffd5b818103818111156119865761198661291d565b818152604060208201525f6127c56040830160098152683bb4ba34323930bbb760b91b602082015260400190565b5f82515f5b818110156129915760208186018101518583015201612977565b505f920191825250919050565b5f602082840312156129ae575f80fd5b81516127c5816127ed565b6001600160801b038181168382160190808211156129d9576129d961291d565b5092915050565b602081525f6119866020830160068152651b595c99d95960d21b602082015260400190565b818152604060208201525f6127c56040830160068152651b595c99d95960d21b602082015260400190565b5f60018201612a4157612a4161291d565b5060010190565b6001600160801b038281168282160390808211156129d9576129d961291d565b6001600160a01b03958616815260208101949094529190931660408301526001600160401b03909216606082015260ff909116608082015260a00190565b5f60208284031215612ab6575f80fd5b5051919050565b6001600160401b038181168382160190808211156129d9576129d961291d565b808201808211156119865761198661291d56fe35cb73aa7fbe8337a0662c3921ca7b2c60e9184a073a772efb5d8f4b6183fa0ca264697066735822122045ff0bda496ea83f74d23ea8f8cf4573eb45cb3bb775a943437c234ec4d2156164736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000095c88c7e13016de4a78ce63c3e601b58ddc0f3d9000000000000000000000000bc635e846825ad70af0585bdaf36a52a659333010000000000000000000000009ef87811e160fb95735ca3325ee29d2330e3d69e
-----Decoded View---------------
Arg [0] : _feeVault (address): 0x95C88C7E13016DE4A78ce63C3e601b58DdC0F3d9
Arg [1] : _registry (address): 0xBC635e846825ad70Af0585bdaF36a52A65933301
Arg [2] : _safeOwner (address): 0x9EF87811e160Fb95735cA3325EE29d2330E3d69e
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000095c88c7e13016de4a78ce63c3e601b58ddc0f3d9
Arg [1] : 000000000000000000000000bc635e846825ad70af0585bdaf36a52a65933301
Arg [2] : 0000000000000000000000009ef87811e160fb95735ca3325ee29d2330e3d69e
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.