ERC-20
Source Code
Overview
Max Total Supply
1,530.090922 ERC20 ***
Holders
398
Market
Price
$0.00 @ 0.000000 ETH
Onchain Market Cap
-
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 6 Decimals)
Balance
0.105275 ERC20 ***Value
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
TimelockBoost
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 888 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;
import { ERC4626 } from "solmate/mixins/ERC4626.sol";
import { ERC20 } from "solmate/tokens/ERC20.sol";
import { SafeTransferLib } from "solmate/utils/SafeTransferLib.sol";
import { ShareMath } from "../libraries/ShareMath.sol";
import { Pausable } from "@openzeppelin/contracts/security/Pausable.sol";
import { IAggregateVault } from "../interfaces/IAggregateVault.sol";
import { GlobalACL, Auth } from "../Auth.sol";
/// @title TimelockBoost
/// @author Umami DAO
/// @notice ERC4626 implementation for boosted vault tokens
contract TimelockBoost is ERC4626, Pausable, GlobalACL {
using SafeTransferLib for ERC20;
// STORAGE
// ------------------------------------------------------------------------------------------
/// @dev maximum number of queued withdrawals at once
uint256 constant LOCK_QUEUE_LIMIT = 5;
/// @dev the zap contract to allow users to deposit in one action
address public ZAP;
struct QueuedWithdrawal {
uint256 queuedTimestamp;
uint256 underlyingAmount;
}
struct TokenLockState {
uint256 withdrawDuration;
uint256 activeWithdrawBalance;
}
/// @dev state of the locking contract
TokenLockState public lockState;
/// @dev account => uint
mapping(address => uint8) public activeWithdrawals;
/// @dev account => QueuedWithdrawal[]
mapping(address => QueuedWithdrawal[LOCK_QUEUE_LIMIT]) public withdrawalQueue;
// EVENTS
// ------------------------------------------------------------------------------------------
event Deposit(address indexed _asset, address _account, uint256 _amount);
event WithdrawInitiated(address indexed _asset, address _account, uint256 _amount, uint256 _duration);
event WithdrawComplete(address indexed _asset, address _account, uint256 _amount);
constructor(ERC20 _asset, string memory _name, string memory _symbol, uint256 _withdrawDuration, Auth _auth)
ERC4626(_asset, _name, _symbol)
GlobalACL(_auth)
{
lockState.withdrawDuration = _withdrawDuration;
}
// DEPOSIT & WITHDRAW
// ------------------------------------------------------------------------------------------
/**
* @notice Deposit assets and mint corresponding shares for the receiver.
* @param assets The amount of assets to be deposited.
* @param receiver The address that will receive the shares.
* @return shares The number of shares minted for the deposited assets.
*/
function deposit(uint256 assets, address receiver) public override whenNotPaused returns (uint256 shares) {
// Check for rounding error since we round down in previewDeposit.
require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES");
// Need to transfer before minting or ERC777s could reenter.
asset.safeTransferFrom(msg.sender, address(this), assets);
_mint(receiver, shares);
emit Deposit(msg.sender, receiver, assets, shares);
}
/**
* @notice Mint a specified amount of shares and deposit the corresponding amount of assets to the receiver
* @param shares The amount of shares to mint
* @param receiver The address to receive the deposited assets
* @return assets The amount of assets deposited for the minted shares
*/
function mint(uint256 shares, address receiver) public override whenNotPaused returns (uint256 assets) {
assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up.
// Need to transfer before minting or ERC777s could reenter.
asset.safeTransferFrom(msg.sender, address(this), assets);
_mint(receiver, shares);
emit Deposit(msg.sender, receiver, assets, shares);
}
/**
* @notice Initiate a withdrawal of the specified amount of assets.
* @param _assets The amount of assets to withdraw.
* @return shares The number of shares burned for the withdrawn assets.
*/
function initiateWithdraw(uint256 _assets) external whenNotPaused returns (uint256 shares) {
shares = convertToShares(_assets);
_initiateWithdrawShares(shares, _assets);
}
/**
* @notice Initiate a withdrawal of the specified amount of shares.
* @param _shares The amount of shares to withdraw.
* @return _assets The number of assets withdrawn for given shares.
*/
function initiateRedeem(uint256 _shares) external whenNotPaused returns (uint256 _assets) {
_assets = convertToAssets(_shares);
_initiateWithdrawShares(_shares, _assets);
}
/**
* @notice Claim all available withdrawals for the sender.
* @param _receiver The address that will receive the withdrawn assets.
* @return _totalWithdraw The total amount of assets withdrawn.
*/
function claimWithdrawals(address _receiver) external whenNotPaused returns (uint256 _totalWithdraw) {
require(activeWithdrawals[msg.sender] > 0, "TimelockBoost: !activeWithdrawals");
QueuedWithdrawal[LOCK_QUEUE_LIMIT] storage accountWithdrawals = withdrawalQueue[msg.sender];
uint256 withdrawAmount;
for (uint256 i = 0; i < LOCK_QUEUE_LIMIT; i++) {
if (
accountWithdrawals[i].queuedTimestamp + lockState.withdrawDuration < block.timestamp
&& accountWithdrawals[i].queuedTimestamp != 0
) {
withdrawAmount = _removeWithdrawForAccount(msg.sender, i);
_decrementActiveWithdraws(msg.sender, withdrawAmount);
_totalWithdraw += withdrawAmount;
}
}
if (_totalWithdraw > 0) {
asset.safeTransfer(_receiver, _totalWithdraw);
}
emit WithdrawComplete(address(asset), msg.sender, _totalWithdraw);
}
/**
* @notice Claim all available withdrawals for the sender. Only used for Zap
* @param _receiver The address that will receive the withdrawn assets.
* @return _totalWithdraw The total amount of assets withdrawn.
*/
function claimWithdrawalsFor(address _account, address _receiver)
external
whenNotPaused
onlyZap
returns (uint256 _totalWithdraw)
{
require(activeWithdrawals[_account] > 0, "TimelockBoost: !activeWithdrawals");
QueuedWithdrawal[LOCK_QUEUE_LIMIT] storage accountWithdrawals = withdrawalQueue[_account];
uint256 withdrawAmount;
for (uint256 i = 0; i < LOCK_QUEUE_LIMIT; i++) {
if (
accountWithdrawals[i].queuedTimestamp + lockState.withdrawDuration < block.timestamp
&& accountWithdrawals[i].queuedTimestamp != 0
) {
withdrawAmount = _removeWithdrawForAccount(_account, i);
_decrementActiveWithdraws(_account, withdrawAmount);
_totalWithdraw += withdrawAmount;
}
}
if (_totalWithdraw > 0) {
asset.safeTransfer(_receiver, _totalWithdraw);
}
emit WithdrawComplete(address(asset), _account, _totalWithdraw);
}
// MATH
// ------------------------------------------------------------------------------------------
/**
* @notice Get the total assets
*/
function totalAssets() public view override returns (uint256) {
return asset.balanceOf(address(this)) - lockState.activeWithdrawBalance;
}
/**
* @notice Calculate the current price per share (PPS) of the token.
* @return pricePerShare The current price per share.
*/
function pps() public view returns (uint256 pricePerShare) {
uint256 supply = totalSupply;
return supply == 0 ? 10 ** decimals : (totalAssets() * 10 ** decimals) / supply;
}
/**
* @notice Convert a specified amount of assets to shares
* @param _assets The amount of assets to convert
* @return - The amount of shares corresponding to the given assets
*/
function convertToShares(uint256 _assets) public view override returns (uint256) {
uint256 supply = totalSupply;
return supply == 0 ? _assets : ShareMath.assetToShares(_assets, pps(), decimals);
}
/**
* @notice Convert a specified amount of shares to assets
* @param _shares The amount of shares to convert
* @return - The amount of assets corresponding to the given shares
*/
function convertToAssets(uint256 _shares) public view override returns (uint256) {
uint256 supply = totalSupply;
return supply == 0 ? _shares : ShareMath.sharesToAsset(_shares, pps(), decimals);
}
/**
* @notice Preview the amount of shares for a given deposit amount
* @param _assets The amount of assets to deposit
* @return - The amount of shares for the given deposit amount
*/
function previewDeposit(uint256 _assets) public view override returns (uint256) {
return convertToShares(_assets);
}
/**
* @notice Preview the amount of assets for a given mint amount
* @param _shares The amount of shares to mint
* @return _mintAmount The amount of assets for the given mint amount
*/
function previewMint(uint256 _shares) public view override returns (uint256 _mintAmount) {
uint256 supply = totalSupply;
_mintAmount = supply == 0 ? _shares : ShareMath.sharesToAsset(_shares, pps(), decimals);
}
/**
* @notice Preview the amount of shares for a given withdrawal amount
* @param _assets The amount of assets to withdraw
* @return _withdrawAmount The amount of shares for the given withdrawal amount
*/
function previewWithdraw(uint256 _assets) public view override returns (uint256 _withdrawAmount) {
uint256 supply = totalSupply;
_withdrawAmount = supply == 0 ? _assets : ShareMath.assetToShares(_assets, pps(), decimals);
}
/**
* @notice Returns an array of withdrawal requests for an account
* @param _account The account
* @return _array An array of withdrawal requests
*/
function withdrawRequests(address _account) public view returns (QueuedWithdrawal[LOCK_QUEUE_LIMIT] memory) {
QueuedWithdrawal[LOCK_QUEUE_LIMIT] memory accountWithdrawals = withdrawalQueue[_account];
return accountWithdrawals;
}
/**
* @notice Returns a struct for the locked state. To be used by contracts.
* @return state Locked state struct
*/
function getLockState() external view returns (TokenLockState memory state) {
return lockState;
}
/**
* @notice Returns a underlying token balance for a user
* @return _underlyingBalance The users underlying balance
*/
function underlyingBalance(address _account) external view returns (uint256 _underlyingBalance) {
return convertToAssets(balanceOf[_account]);
}
// DEPOSIT & WITHDRAW LIMIT
// ------------------------------------------------------------------------------------------
/**
* @notice Get the maximum deposit amount for an address
* @dev _address The address to check the maximum deposit amount for
* @dev returns the maximum deposit amount for the given address
*/
function maxDeposit(address) public view override returns (uint256) {
return asset.totalSupply();
}
/**
* @notice Get the maximum mint amount for an address
*/
function maxMint(address) public view override returns (uint256) {
return convertToShares(asset.totalSupply());
}
/**
* @notice Get the maximum withdrawal amount for an address
* @param owner The address to check the maximum withdrawal amount for
* @return The maximum withdrawal amount for the given address
*/
function maxWithdraw(address owner) public view override returns (uint256) {
return convertToAssets(balanceOf[owner]);
}
// INTERNAL
// ------------------------------------------------------------------------------------------
function _initiateWithdrawShares(uint256 _shares, uint256 _assets) internal {
require(activeWithdrawals[msg.sender] < LOCK_QUEUE_LIMIT, "TimelockBoost: > LOCK_QUEUE_LIMIT");
_incrementActiveWithdraws(msg.sender, _assets);
_addWithdrawForAccount(msg.sender, _assets);
_burn(msg.sender, _shares);
emit WithdrawInitiated(address(asset), msg.sender, _assets, lockState.withdrawDuration);
}
/**
* @notice Increment the active withdrawal count and balance for the specified account.
* @param _account The address of the account.
* @param _assets The amount of assets to increment the active withdrawal balance.
*/
function _incrementActiveWithdraws(address _account, uint256 _assets) internal {
lockState.activeWithdrawBalance += _assets;
activeWithdrawals[_account] += 1;
require(activeWithdrawals[_account] <= LOCK_QUEUE_LIMIT, "TimelockBoost: !activeWithdrawalsLength");
}
/**
* @notice Decrement the active withdrawal count and balance for the specified account.
* @param _account The address of the account.
* @param _assets The amount of assets to decrement the active withdrawal balance.
*/
function _decrementActiveWithdraws(address _account, uint256 _assets) internal {
lockState.activeWithdrawBalance -= _assets;
activeWithdrawals[_account] -= 1;
}
/**
* @notice Add a new withdrawal for the specified account.
* @param _account The address of the account.
* @param _assets The amount of assets to be added to the withdrawal queue.
*/
function _addWithdrawForAccount(address _account, uint256 _assets) internal {
QueuedWithdrawal[LOCK_QUEUE_LIMIT] storage accountWithdrawals = withdrawalQueue[_account];
for (uint256 i = 0; i < LOCK_QUEUE_LIMIT; i++) {
if (accountWithdrawals[i].queuedTimestamp == 0) {
accountWithdrawals[i].queuedTimestamp = block.timestamp;
accountWithdrawals[i].underlyingAmount = _assets;
return;
}
}
}
/**
* @notice Remove a withdrawal from the queue for the specified account.
* @param _account The address of the account.
* @param _index The index of the withdrawal to be removed.
* @return underlyingAmount The amount of assets that were associated with the removed withdrawal.
*/
function _removeWithdrawForAccount(address _account, uint256 _index) internal returns (uint256 underlyingAmount) {
QueuedWithdrawal[LOCK_QUEUE_LIMIT] storage accountWithdrawals = withdrawalQueue[_account];
require(
accountWithdrawals[_index].queuedTimestamp + lockState.withdrawDuration < block.timestamp,
"TimelockBoost: !withdrawalDuration"
);
underlyingAmount = accountWithdrawals[_index].underlyingAmount;
delete accountWithdrawals[_index];
}
// CONFIG
// ------------------------------------------------------------------------------------------
/**
* @notice Set the Zap contract address.
* @dev Can only be called by configurator.
* @param _zap The address of the Zap contract.
*/
function setZap(address _zap) external onlyConfigurator {
require(_zap != address(0), "TimelockBoost: ZAP set");
ZAP = _zap;
}
/**
* @notice Set the withdrawal duration for the contract.
* @param _withdrawalDuration The new withdrawal duration in seconds.
*/
function setWithdrawalDuration(uint256 _withdrawalDuration) external onlyConfigurator {
lockState.withdrawDuration = _withdrawalDuration;
}
/**
* @notice Pause deposit and withdrawal functionalities of the contract.
*/
function pauseDepositWithdraw() external onlyConfigurator {
_pause();
}
/**
* @notice Pause deposit and withdrawal functionalities of the contract.
*/
function unpauseDepositWithdraw() external onlyConfigurator {
_unpause();
}
// MODIFIERS
// ------------------------------------------------------------------------------------------
/**
* @dev Modifier to ensure that the caller is the Zap contract.
*/
modifier onlyZap() {
require(msg.sender == ZAP, "TimelockBoost: !ZAP");
_;
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
import {SafeTransferLib} from "../utils/SafeTransferLib.sol";
import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol";
/// @notice Minimal ERC4626 tokenized Vault implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/mixins/ERC4626.sol)
abstract contract ERC4626 is ERC20 {
using SafeTransferLib for ERC20;
using FixedPointMathLib for uint256;
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares);
event Withdraw(
address indexed caller,
address indexed receiver,
address indexed owner,
uint256 assets,
uint256 shares
);
/*//////////////////////////////////////////////////////////////
IMMUTABLES
//////////////////////////////////////////////////////////////*/
ERC20 public immutable asset;
constructor(
ERC20 _asset,
string memory _name,
string memory _symbol
) ERC20(_name, _symbol, _asset.decimals()) {
asset = _asset;
}
/*//////////////////////////////////////////////////////////////
DEPOSIT/WITHDRAWAL LOGIC
//////////////////////////////////////////////////////////////*/
function deposit(uint256 assets, address receiver) public virtual returns (uint256 shares) {
// Check for rounding error since we round down in previewDeposit.
require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES");
// Need to transfer before minting or ERC777s could reenter.
asset.safeTransferFrom(msg.sender, address(this), assets);
_mint(receiver, shares);
emit Deposit(msg.sender, receiver, assets, shares);
afterDeposit(assets, shares);
}
function mint(uint256 shares, address receiver) public virtual returns (uint256 assets) {
assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up.
// Need to transfer before minting or ERC777s could reenter.
asset.safeTransferFrom(msg.sender, address(this), assets);
_mint(receiver, shares);
emit Deposit(msg.sender, receiver, assets, shares);
afterDeposit(assets, shares);
}
function withdraw(
uint256 assets,
address receiver,
address owner
) public virtual returns (uint256 shares) {
shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up.
if (msg.sender != owner) {
uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
}
beforeWithdraw(assets, shares);
_burn(owner, shares);
emit Withdraw(msg.sender, receiver, owner, assets, shares);
asset.safeTransfer(receiver, assets);
}
function redeem(
uint256 shares,
address receiver,
address owner
) public virtual returns (uint256 assets) {
if (msg.sender != owner) {
uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
}
// Check for rounding error since we round down in previewRedeem.
require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS");
beforeWithdraw(assets, shares);
_burn(owner, shares);
emit Withdraw(msg.sender, receiver, owner, assets, shares);
asset.safeTransfer(receiver, assets);
}
/*//////////////////////////////////////////////////////////////
ACCOUNTING LOGIC
//////////////////////////////////////////////////////////////*/
function totalAssets() public view virtual returns (uint256);
function convertToShares(uint256 assets) public view virtual returns (uint256) {
uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.
return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets());
}
function convertToAssets(uint256 shares) public view virtual returns (uint256) {
uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.
return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply);
}
function previewDeposit(uint256 assets) public view virtual returns (uint256) {
return convertToShares(assets);
}
function previewMint(uint256 shares) public view virtual returns (uint256) {
uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.
return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply);
}
function previewWithdraw(uint256 assets) public view virtual returns (uint256) {
uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.
return supply == 0 ? assets : assets.mulDivUp(supply, totalAssets());
}
function previewRedeem(uint256 shares) public view virtual returns (uint256) {
return convertToAssets(shares);
}
/*//////////////////////////////////////////////////////////////
DEPOSIT/WITHDRAWAL LIMIT LOGIC
//////////////////////////////////////////////////////////////*/
function maxDeposit(address) public view virtual returns (uint256) {
return type(uint256).max;
}
function maxMint(address) public view virtual returns (uint256) {
return type(uint256).max;
}
function maxWithdraw(address owner) public view virtual returns (uint256) {
return convertToAssets(balanceOf[owner]);
}
function maxRedeem(address owner) public view virtual returns (uint256) {
return balanceOf[owner];
}
/*//////////////////////////////////////////////////////////////
INTERNAL HOOKS LOGIC
//////////////////////////////////////////////////////////////*/
function beforeWithdraw(uint256 assets, uint256 shares) internal virtual {}
function afterDeposit(uint256 assets, uint256 shares) internal virtual {}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
/*//////////////////////////////////////////////////////////////
METADATA STORAGE
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
uint8 public immutable decimals;
/*//////////////////////////////////////////////////////////////
ERC20 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
/*//////////////////////////////////////////////////////////////
EIP-2612 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
/*//////////////////////////////////////////////////////////////
ERC20 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
/*//////////////////////////////////////////////////////////////
EIP-2612 LOGIC
//////////////////////////////////////////////////////////////*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
// Unchecked because the only math done is incrementing
// the owner's nonce which cannot realistically overflow.
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
),
v,
r,
s
);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
/*//////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
// Cannot underflow because a user's balance
// will never be larger than the total supply.
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
/*//////////////////////////////////////////////////////////////
ETH OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferETH(address to, uint256 amount) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Transfer the ETH and store if it succeeded or not.
success := call(gas(), to, amount, 0, 0, 0, 0)
}
require(success, "ETH_TRANSFER_FAILED");
}
/*//////////////////////////////////////////////////////////////
ERC20 OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument.
mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument.
mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
)
}
require(success, "TRANSFER_FROM_FAILED");
}
function safeTransfer(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "TRANSFER_FAILED");
}
function safeApprove(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "APPROVE_FAILED");
}
}// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;
library ShareMath {
uint256 internal constant PLACEHOLDER_UINT = 1;
function assetToShares(uint256 assetAmount, uint256 assetPerShare, uint256 decimals)
internal
pure
returns (uint256)
{
// If this throws, it means that vault's roundPricePerShare[currentRound] has not been set yet
// which should never happen.
// Has to be larger than 1 because `1` is used in `initRoundPricePerShares` to prevent cold writes.
require(assetPerShare > PLACEHOLDER_UINT, "Invalid assetPerShare");
return (assetAmount * 10 ** decimals) / assetPerShare;
}
function sharesToAsset(uint256 shares, uint256 assetPerShare, uint256 decimals) internal pure returns (uint256) {
// If this throws, it means that vault's roundPricePerShare[currentRound] has not been set yet
// which should never happen.
// Has to be larger than 1 because `1` is used in `initRoundPricePerShares` to prevent cold writes.
require(assetPerShare > PLACEHOLDER_UINT, "Invalid assetPerShare");
return (shares * assetPerShare) / 10 ** decimals;
}
function pricePerShare(uint256 totalSupply, uint256 totalBalance, uint256 decimals)
internal
pure
returns (uint256)
{
uint256 singleShare = 10 ** decimals;
return totalSupply > 0 ? (singleShare * totalBalance) / totalSupply : singleShare;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)
pragma solidity ^0.8.0;
import "../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 {
/**
* @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);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @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 {
require(!paused(), "Pausable: paused");
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
/**
* @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: GPL-3.0
pragma solidity 0.8.17;
import { ERC20 } from "solmate/tokens/ERC20.sol";
interface IAggregateVault {
function handleWithdraw(ERC20 asset, uint256 _amount, address _account) external;
function handleDeposit(ERC20 asset, uint256 _amount, address _account) external;
function getVaultPPS(address _assetVault) external view returns (uint256);
function previewWithdrawalFee(address token, uint256 _size) external view returns (uint256);
function previewDepositFee(uint256 _size) external view returns (uint256);
function rebalanceOpen() external view returns (bool);
}pragma solidity 0.8.17;
bytes32 constant CONFIGURATOR_ROLE = keccak256("CONFIGURATOR");
bytes32 constant KEEPER_ROLE = keccak256("KEEPER_ROLE");
bytes32 constant SWAP_KEEPER = keccak256("SWAP_KEEPER");
/// @title Auth
/// @author Umami Developers
/// @notice Simple centralized ACL
contract Auth {
/// @dev user not authorized with given role
error NotAuthorized(bytes32 _role, address _user);
event RoleUpdated(bytes32 indexed role, address indexed user, bool authorized);
bytes32 public constant AUTH_MANAGER_ROLE = keccak256("AUTH_MANAGER");
mapping(bytes32 => mapping(address => bool)) public hasRole;
constructor() {
_updateRole(msg.sender, AUTH_MANAGER_ROLE, true);
}
function updateRole(address _user, bytes32 _role, bool _authorized) external {
onlyRole(AUTH_MANAGER_ROLE, msg.sender);
_updateRole(_user, _role, _authorized);
}
function onlyRole(bytes32 _role, address _user) public view {
if (!hasRole[_role][_user]) {
revert NotAuthorized(_role, _user);
}
}
function _updateRole(address _user, bytes32 _role, bool _authorized) internal {
hasRole[_role][_user] = _authorized;
emit RoleUpdated(_role, _user, _authorized);
}
}
abstract contract GlobalACL {
Auth public immutable AUTH;
constructor(Auth _auth) {
require(address(_auth) != address(0), "GlobalACL: zero address");
AUTH = _auth;
}
modifier onlyConfigurator() {
AUTH.onlyRole(CONFIGURATOR_ROLE, msg.sender);
_;
}
modifier onlyRole(bytes32 _role) {
AUTH.onlyRole(_role, msg.sender);
_;
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
/*//////////////////////////////////////////////////////////////
SIMPLIFIED FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/
uint256 internal constant MAX_UINT256 = 2**256 - 1;
uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.
function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
}
function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
}
function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
}
function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
}
/*//////////////////////////////////////////////////////////////
LOW LEVEL FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/
function mulDivDown(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
revert(0, 0)
}
// Divide x * y by the denominator.
z := div(mul(x, y), denominator)
}
}
function mulDivUp(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
revert(0, 0)
}
// If x * y modulo the denominator is strictly greater than 0,
// 1 is added to round up the division of x * y by the denominator.
z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator))
}
}
function rpow(
uint256 x,
uint256 n,
uint256 scalar
) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
switch x
case 0 {
switch n
case 0 {
// 0 ** 0 = 1
z := scalar
}
default {
// 0 ** n = 0
z := 0
}
}
default {
switch mod(n, 2)
case 0 {
// If n is even, store scalar in z for now.
z := scalar
}
default {
// If n is odd, store x in z for now.
z := x
}
// Shifting right by 1 is like dividing by 2.
let half := shr(1, scalar)
for {
// Shift n right by 1 before looping to halve it.
n := shr(1, n)
} n {
// Shift n right by 1 each iteration to halve it.
n := shr(1, n)
} {
// Revert immediately if x ** 2 would overflow.
// Equivalent to iszero(eq(div(xx, x), x)) here.
if shr(128, x) {
revert(0, 0)
}
// Store x squared.
let xx := mul(x, x)
// Round to the nearest number.
let xxRound := add(xx, half)
// Revert if xx + half overflowed.
if lt(xxRound, xx) {
revert(0, 0)
}
// Set x to scaled xxRound.
x := div(xxRound, scalar)
// If n is even:
if mod(n, 2) {
// Compute z * x.
let zx := mul(z, x)
// If z * x overflowed:
if iszero(eq(div(zx, x), z)) {
// Revert if x is non-zero.
if iszero(iszero(x)) {
revert(0, 0)
}
}
// Round to the nearest number.
let zxRound := add(zx, half)
// Revert if zx + half overflowed.
if lt(zxRound, zx) {
revert(0, 0)
}
// Return properly scaled zxRound.
z := div(zxRound, scalar)
}
}
}
}
}
/*//////////////////////////////////////////////////////////////
GENERAL NUMBER UTILITIES
//////////////////////////////////////////////////////////////*/
function sqrt(uint256 x) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
let y := x // We start y at x, which will help us make our initial estimate.
z := 181 // The "correct" value is 1, but this saves a multiplication later.
// This segment is to get a reasonable initial estimate for the Babylonian method. With a bad
// start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.
// We check y >= 2^(k + 8) but shift right by k bits
// each branch to ensure that if x >= 256, then y >= 256.
if iszero(lt(y, 0x10000000000000000000000000000000000)) {
y := shr(128, y)
z := shl(64, z)
}
if iszero(lt(y, 0x1000000000000000000)) {
y := shr(64, y)
z := shl(32, z)
}
if iszero(lt(y, 0x10000000000)) {
y := shr(32, y)
z := shl(16, z)
}
if iszero(lt(y, 0x1000000)) {
y := shr(16, y)
z := shl(8, z)
}
// Goal was to get z*z*y within a small factor of x. More iterations could
// get y in a tighter range. Currently, we will have y in [256, 256*2^16).
// We ensured y >= 256 so that the relative difference between y and y+1 is small.
// That's not possible if x < 256 but we can just verify those cases exhaustively.
// Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.
// Correctness can be checked exhaustively for x < 256, so we assume y >= 256.
// Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.
// For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range
// (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.
// Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate
// sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.
// There is no overflow risk here since y < 2^136 after the first branch above.
z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.
// Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
// If x+1 is a perfect square, the Babylonian method cycles between
// floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.
// See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
// Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.
// If you don't care whether the floor or ceil square root is returned, you can remove this statement.
z := sub(z, lt(div(x, z), z))
}
}
function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Mod x by y. Note this will return
// 0 instead of reverting if y is zero.
z := mod(x, y)
}
}
function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) {
/// @solidity memory-safe-assembly
assembly {
// Divide x by y. Note this will return
// 0 instead of reverting if y is zero.
r := div(x, y)
}
}
function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Add 1 to x * y if x % y > 0. Note this will
// return 0 instead of reverting if y is zero.
z := add(gt(mod(x, y), 0), div(x, y))
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}{
"remappings": [
"@chainlink/=lib/chainlink/",
"@openzeppelin/=lib/openzeppelin-contracts/",
"@solady/=lib/solady/src/",
"chainlink/=lib/chainlink/integration-tests/contracts/ethereum/src/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"gmx-contracts/=lib/gmx-contracts/contracts/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"solady/=lib/solady/",
"solmate/=lib/solmate/src/"
],
"optimizer": {
"enabled": true,
"runs": 888
},
"metadata": {
"bytecodeHash": "ipfs"
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "london",
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract ERC20","name":"_asset","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_withdrawDuration","type":"uint256"},{"internalType":"contract Auth","name":"_auth","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_asset","type":"address"},{"indexed":false,"internalType":"address","name":"_account","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_asset","type":"address"},{"indexed":false,"internalType":"address","name":"_account","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"WithdrawComplete","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_asset","type":"address"},{"indexed":false,"internalType":"address","name":"_account","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"WithdrawInitiated","type":"event"},{"inputs":[],"name":"AUTH","outputs":[{"internalType":"contract Auth","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ZAP","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"activeWithdrawals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"}],"name":"claimWithdrawals","outputs":[{"internalType":"uint256","name":"_totalWithdraw","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"claimWithdrawalsFor","outputs":[{"internalType":"uint256","name":"_totalWithdraw","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getLockState","outputs":[{"components":[{"internalType":"uint256","name":"withdrawDuration","type":"uint256"},{"internalType":"uint256","name":"activeWithdrawBalance","type":"uint256"}],"internalType":"struct TimelockBoost.TokenLockState","name":"state","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"initiateRedeem","outputs":[{"internalType":"uint256","name":"_assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"}],"name":"initiateWithdraw","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockState","outputs":[{"internalType":"uint256","name":"withdrawDuration","type":"uint256"},{"internalType":"uint256","name":"activeWithdrawBalance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseDepositWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"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":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pps","outputs":[{"internalType":"uint256","name":"pricePerShare","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"previewMint","outputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assets","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"_withdrawAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_withdrawalDuration","type":"uint256"}],"name":"setWithdrawalDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_zap","type":"address"}],"name":"setZap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"underlyingBalance","outputs":[{"internalType":"uint256","name":"_underlyingBalance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpauseDepositWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"withdrawRequests","outputs":[{"components":[{"internalType":"uint256","name":"queuedTimestamp","type":"uint256"},{"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"internalType":"struct TimelockBoost.QueuedWithdrawal[5]","name":"","type":"tuple[5]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdrawalQueue","outputs":[{"internalType":"uint256","name":"queuedTimestamp","type":"uint256"},{"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6101206040523480156200001257600080fd5b5060405162002fa538038062002fa58339810160408190526200003591620002db565b808585858181846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200007a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000a091906200037b565b6000620000ae848262000436565b506001620000bd838262000436565b5060ff81166080524660a052620000d362000161565b60c0525050506001600160a01b0392831660e05250506006805460ff191690558116620001465760405162461bcd60e51b815260206004820152601760248201527f476c6f62616c41434c3a207a65726f2061646472657373000000000000000000604482015260640160405180910390fd5b6001600160a01b031661010052506007555062000580915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600060405162000195919062000502565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6001600160a01b03811681146200021357600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200023e57600080fd5b81516001600160401b03808211156200025b576200025b62000216565b604051601f8301601f19908116603f0116810190828211818310171562000286576200028662000216565b81604052838152602092508683858801011115620002a357600080fd5b600091505b83821015620002c75785820183015181830184015290820190620002a8565b600093810190920192909252949350505050565b600080600080600060a08688031215620002f457600080fd5b85516200030181620001fd565b60208701519095506001600160401b03808211156200031f57600080fd5b6200032d89838a016200022c565b955060408801519150808211156200034457600080fd5b5062000353888289016200022c565b9350506060860151915060808601516200036d81620001fd565b809150509295509295909350565b6000602082840312156200038e57600080fd5b815160ff81168114620003a057600080fd5b9392505050565b600181811c90821680620003bc57607f821691505b602082108103620003dd57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200043157600081815260208120601f850160051c810160208610156200040c5750805b601f850160051c820191505b818110156200042d5782815560010162000418565b5050505b505050565b81516001600160401b0381111562000452576200045262000216565b6200046a81620004638454620003a7565b84620003e3565b602080601f831160018114620004a25760008415620004895750858301515b600019600386901b1c1916600185901b1785556200042d565b600085815260208120601f198616915b82811015620004d357888601518255948401946001909101908401620004b2565b5085821015620004f25787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008083546200051281620003a7565b600182811680156200052d5760018114620005435762000574565b60ff198416875282151583028701945062000574565b8760005260208060002060005b858110156200056b5781548a82015290840190820162000550565b50505082870194505b50929695505050505050565b60805160a05160c05160e0516101005161295462000651600039600081816103a701528181610b3101528181610f83015281816111a7015261156f01526000818161047b015281816107f701528181610c1701528181610eb301528181610ef4015281816110ed01528181611356015281816113950152818161140a015281816116b60152818161180a015281816118380152611c1701526000610bcf01526000610b9f01526000818161044c01528181610726015281816107720152818161092101526109dd01526129546000f3fe608060405234801561001057600080fd5b50600436106103095760003560e01c80636593c2c91161019c578063acfc67a5116100ee578063cc7d9ade11610097578063d905777e11610071578063d905777e146106ad578063dd62ed3e146106d6578063ef8b30f71461070157600080fd5b8063cc7d9ade14610665578063ce96cb77146104b5578063d505accf1461069a57600080fd5b8063ba087652116100c8578063ba0876521461063f578063c63d75b614610652578063c6e6f5921461038f57600080fd5b8063acfc67a514610624578063b3d7f6b914610359578063b460af941461062c57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105f6578063a9059cbb146105fe578063aa2cb4dc1461061157600080fd5b80637ecebe00146105b0578063930d3f17146105d057806394bf804d146105e357600080fd5b806370a082311161018157806370a0823114610575578063772fa701146105955780637e108d521461059d57600080fd5b80636593c2c91461054f5780636e553f651461056257600080fd5b806329f384e211610260578063402d267d1161020957806352df49ec116101e357806352df49ec1461051157806358d595b3146105315780635c975abb1461054457600080fd5b8063402d267d146104c857806346be9c48146104db5780634cdad506146104fe57600080fd5b806338d52e0f1161023a57806338d52e0f146104765780633e09ed961461049d5780633e642575146104b557600080fd5b806329f384e214610432578063313ce567146104475780633644e5151461046e57600080fd5b8063095ea7b3116102c257806318160ddd1161029c57806318160ddd146103e1578063236136a1146103ea57806323b872dd1461041f57600080fd5b8063095ea7b31461036c5780630a28a4771461038f5780630a5623fb146103a257600080fd5b806301e1d114116102f357806301e1d1141461033c57806306fdde031461034457806307a2d13a1461035957600080fd5b806218b1d31461030e578063010252f814610329575b600080fd5b610316610714565b6040519081526020015b60405180910390f35b6103166103373660046123f5565b61079e565b6103166107c2565b61034c610879565b604051610320919061240e565b6103166103673660046123f5565b610907565b61037f61037a366004612473565b610956565b6040519015158152602001610320565b61031661039d3660046123f5565b6109c3565b6103c97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610320565b61031660025481565b61040d6103f836600461249d565b60096020526000908152604090205460ff1681565b60405160ff9091168152602001610320565b61037f61042d3660046124b8565b610a04565b6104456104403660046123f5565b610af6565b005b61040d7f000000000000000000000000000000000000000000000000000000000000000081565b610316610b9b565b6103c97f000000000000000000000000000000000000000000000000000000000000000081565b6006546103c99061010090046001600160a01b031681565b6103166104c336600461249d565b610bf1565b6103166104d636600461249d565b610c13565b6007546008546104e9919082565b60408051928352602083019190915201610320565b61031661050c3660046123f5565b610c97565b61052461051f36600461249d565b610ca2565b60405161032091906124f4565b61031661053f36600461253b565b610d19565b60065460ff1661037f565b61044561055d36600461249d565b610f48565b61031661057036600461256e565b61107b565b61031661058336600461249d565b60036020526000908152604090205481565b61044561116c565b6103166105ab3660046123f5565b611213565b6103166105be36600461249d565b60056020526000908152604090205481565b6103166105de36600461249d565b611232565b6103166105f136600461256e565b6113e8565b61034c61147f565b61037f61060c366004612473565b61148c565b6104e961061f366004612473565b611504565b610445611534565b61031661063a366004612591565b6115d9565b61031661064d366004612591565b6116dd565b61031661066036600461249d565b611831565b6040805180820182526000808252602091820152815180830190925260075482526008549082015260405161032091906125cd565b6104456106a83660046125e4565b6118b8565b6103166106bb36600461249d565b6001600160a01b031660009081526003602052604090205490565b6103166106e436600461253b565b600460209081526000928352604080842090915290825290205481565b61031661070f3660046123f5565b611b0b565b600254600090801561076d578061074c7f0000000000000000000000000000000000000000000000000000000000000000600a612751565b6107546107c2565b61075e9190612760565b6107689190612777565b610798565b6107987f0000000000000000000000000000000000000000000000000000000000000000600a612751565b91505090565b60006107a8611b16565b6107b182610907565b90506107bd8282611b69565b919050565b6008546040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600091907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610846573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086a9190612799565b61087491906127b2565b905090565b60008054610886906127c5565b80601f01602080910402602001604051908101604052809291908181526020018280546108b2906127c5565b80156108ff5780601f106108d4576101008083540402835291602001916108ff565b820191906000526020600020905b8154815290600101906020018083116108e257829003601f168201915b505050505081565b600254600090801561094d576109488361091f610714565b7f000000000000000000000000000000000000000000000000000000000000000060ff16611c69565b61094f565b825b9392505050565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906109b19086815260200190565b60405180910390a35060015b92915050565b600254600090801561094d57610948836109db610714565b7f000000000000000000000000000000000000000000000000000000000000000060ff16611ce2565b6001600160a01b03831660009081526004602090815260408083203384529091528120546000198114610a6057610a3b83826127b2565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610a889084906127b2565b90915550506001600160a01b03808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610ae39087815260200190565b60405180910390a3506001949350505050565b6040516346ea9cc560e01b81527f530008d2b058137d9c475b1b7d83984f1fcf1dd0e607659d029fc1517ab8926860048201523360248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906346ea9cc59060440160006040518083038186803b158015610b7b57600080fd5b505afa158015610b8f573d6000803e3d6000fd5b50505060079190915550565b60007f00000000000000000000000000000000000000000000000000000000000000004614610bcc57610874611d4a565b507f000000000000000000000000000000000000000000000000000000000000000090565b6001600160a01b0381166000908152600360205260408120546109bd90610907565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c73573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bd9190612799565b60006109bd82610907565b610caa6123bc565b6001600160a01b0382166000908152600a6020526040808220815160a08101909252600583835b82821015610d0d578382600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610cd1565b50929695505050505050565b6000610d23611b16565b60065461010090046001600160a01b03163314610d875760405162461bcd60e51b815260206004820152601360248201527f54696d656c6f636b426f6f73743a20215a41500000000000000000000000000060448201526064015b60405180910390fd5b6001600160a01b03831660009081526009602052604090205460ff16610df95760405162461bcd60e51b815260206004820152602160248201527f54696d656c6f636b426f6f73743a20216163746976655769746864726177616c6044820152607360f81b6064820152608401610d7e565b6001600160a01b0383166000908152600a6020526040812090805b6005811015610e9f576007544290848360058110610e3457610e346127ff565b6002020154610e439190612815565b108015610e655750828160058110610e5d57610e5d6127ff565b600202015415155b15610e8d57610e748682611de4565b9150610e808683611ec2565b610e8a8285612815565b93505b80610e9781612828565b915050610e14565b508215610eda57610eda6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168585611f24565b604080516001600160a01b038781168252602082018690527f000000000000000000000000000000000000000000000000000000000000000016917fce67cd4e23f137729b8b844fbf25399d5130346f0d62c18afdc0a943e1d1f101910160405180910390a2505092915050565b6040516346ea9cc560e01b81527f530008d2b058137d9c475b1b7d83984f1fcf1dd0e607659d029fc1517ab8926860048201523360248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906346ea9cc59060440160006040518083038186803b158015610fcd57600080fd5b505afa158015610fe1573d6000803e3d6000fd5b5050506001600160a01b038216905061103c5760405162461bcd60e51b815260206004820152601660248201527f54696d656c6f636b426f6f73743a205a415020736574000000000000000000006044820152606401610d7e565b600680546001600160a01b03909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b6000611085611b16565b61108e83611b0b565b9050806000036110e05760405162461bcd60e51b815260206004820152600b60248201527f5a45524f5f5348415245530000000000000000000000000000000000000000006044820152606401610d7e565b6111156001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333086611fc9565b61111f8282612075565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d791015b60405180910390a392915050565b6040516346ea9cc560e01b81527f530008d2b058137d9c475b1b7d83984f1fcf1dd0e607659d029fc1517ab8926860048201523360248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906346ea9cc59060440160006040518083038186803b1580156111f157600080fd5b505afa158015611205573d6000803e3d6000fd5b505050506112116120e1565b565b600061121d611b16565b611226826109c3565b90506107bd8183611b69565b600061123c611b16565b3360009081526009602052604090205460ff166112a55760405162461bcd60e51b815260206004820152602160248201527f54696d656c6f636b426f6f73743a20216163746976655769746864726177616c6044820152607360f81b6064820152608401610d7e565b336000908152600a6020526040812090805b60058110156113425760075442908483600581106112d7576112d76127ff565b60020201546112e69190612815565b1080156113085750828160058110611300576113006127ff565b600202015415155b15611330576113173382611de4565b91506113233383611ec2565b61132d8285612815565b93505b8061133a81612828565b9150506112b7565b50821561137d5761137d6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168585611f24565b60408051338152602081018590526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016917fce67cd4e23f137729b8b844fbf25399d5130346f0d62c18afdc0a943e1d1f101910160405180910390a25050919050565b60006113f2611b16565b6113fb83610907565b90506114326001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333084611fc9565b61143c8284612075565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910161115e565b60018054610886906127c5565b336000908152600360205260408120805483919083906114ad9084906127b2565b90915550506001600160a01b038316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906109b19086815260200190565b600a602052816000526040600020816005811061152057600080fd5b600202018054600190910154909250905082565b6040516346ea9cc560e01b81527f530008d2b058137d9c475b1b7d83984f1fcf1dd0e607659d029fc1517ab8926860048201523360248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906346ea9cc59060440160006040518083038186803b1580156115b957600080fd5b505afa1580156115cd573d6000803e3d6000fd5b50505050611211612133565b60006115e4846109c3565b9050336001600160a01b03831614611654576001600160a01b038216600090815260046020908152604080832033845290915290205460001981146116525761162d82826127b2565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b61165e8282612174565b60408051858152602081018390526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a461094f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168486611f24565b6000336001600160a01b0383161461174d576001600160a01b0382166000908152600460209081526040808320338452909152902054600019811461174b5761172685826127b2565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b61175684610c97565b9050806000036117a85760405162461bcd60e51b815260206004820152600b60248201527f5a45524f5f4153534554530000000000000000000000000000000000000000006044820152606401610d7e565b6117b28285612174565b60408051828152602081018690526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a461094f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168483611f24565b60006109bd7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611894573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039d9190612799565b428410156119085760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610d7e565b60006001611914610b9b565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611a20573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590611a565750876001600160a01b0316816001600160a01b0316145b611aa25760405162461bcd60e51b815260206004820152600e60248201527f494e56414c49445f5349474e45520000000000000000000000000000000000006044820152606401610d7e565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b60006109bd826109c3565b60065460ff16156112115760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d7e565b33600090815260096020526040902054600560ff90911610611bd75760405162461bcd60e51b815260206004820152602160248201527f54696d656c6f636b426f6f73743a203e204c4f434b5f51554555455f4c494d496044820152601560fa1b6064820152608401610d7e565b611be133826121e8565b611beb33826122db565b611bf53383612174565b6007546040805133815260208101849052908101919091526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016907fcd8ae332c101158982911dd43228c7737f41d0a23cb7c71ca936fccf8df4f5339060600160405180910390a25050565b600060018311611cbb5760405162461bcd60e51b815260206004820152601560248201527f496e76616c6964206173736574506572536861726500000000000000000000006044820152606401610d7e565b611cc682600a612841565b611cd08486612760565b611cda9190612777565b949350505050565b600060018311611d345760405162461bcd60e51b815260206004820152601560248201527f496e76616c6964206173736574506572536861726500000000000000000000006044820152606401610d7e565b82611d4083600a612841565b611cd09086612760565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051611d7c919061284d565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6001600160a01b0382166000908152600a602052604081206007544290828560058110611e1357611e136127ff565b6002020154611e229190612815565b10611e7a5760405162461bcd60e51b815260206004820152602260248201527f54696d656c6f636b426f6f73743a20217769746864726177616c44757261746960448201526137b760f11b6064820152608401610d7e565b808360058110611e8c57611e8c6127ff565b60020201600101549150808360058110611ea857611ea86127ff565b600060029190910291909101818155600101555092915050565b8060076001016000828254611ed791906127b2565b90915550506001600160a01b0382166000908152600960205260408120805460019290611f0890849060ff166128ec565b92506101000a81548160ff021916908360ff1602179055505050565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080611fc35760405162461bcd60e51b815260206004820152600f60248201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152606401610d7e565b50505050565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d116001600051141617169150508061206e5760405162461bcd60e51b815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152606401610d7e565b5050505050565b80600260008282546120879190612815565b90915550506001600160a01b0382166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91015b60405180910390a35050565b6120e961236a565b6006805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b61213b611b16565b6006805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586121163390565b5050565b6001600160a01b0382166000908152600360205260408120805483929061219c9084906127b2565b90915550506002805482900390556040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016120d5565b80600760010160008282546121fd9190612815565b90915550506001600160a01b038216600090815260096020526040812080546001929061222e90849060ff16612905565b82546101009290920a60ff8181021990931691831602179091556001600160a01b03841660009081526009602052604090205460059116111590506121705760405162461bcd60e51b815260206004820152602760248201527f54696d656c6f636b426f6f73743a20216163746976655769746864726177616c60448201527f734c656e677468000000000000000000000000000000000000000000000000006064820152608401610d7e565b6001600160a01b0382166000908152600a60205260408120905b6005811015611fc357818160058110612310576123106127ff565b6002020154600003612358574282826005811061232f5761232f6127ff565b600202015582828260058110612347576123476127ff565b600202016001018190555050505050565b8061236281612828565b9150506122f5565b60065460ff166112115760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610d7e565b6040518060a001604052806005905b60408051808201909152600080825260208201528152602001906001900390816123cb5790505090565b60006020828403121561240757600080fd5b5035919050565b600060208083528351808285015260005b8181101561243b5785810183015185820160400152820161241f565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146107bd57600080fd5b6000806040838503121561248657600080fd5b61248f8361245c565b946020939093013593505050565b6000602082840312156124af57600080fd5b61094f8261245c565b6000806000606084860312156124cd57600080fd5b6124d68461245c565b92506124e46020850161245c565b9150604084013590509250925092565b6101408101818360005b60058110156125325761251c83835180518252602090810151910152565b60409290920191602091909101906001016124fe565b50505092915050565b6000806040838503121561254e57600080fd5b6125578361245c565b91506125656020840161245c565b90509250929050565b6000806040838503121561258157600080fd5b823591506125656020840161245c565b6000806000606084860312156125a657600080fd5b833592506125b66020850161245c565b91506125c46040850161245c565b90509250925092565b8151815260208083015190820152604081016109bd565b600080600080600080600060e0888a0312156125ff57600080fd5b6126088861245c565b96506126166020890161245c565b95506040880135945060608801359350608088013560ff8116811461263a57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b634e487b7160e01b600052601160045260246000fd5b600181815b808511156126a857816000190482111561268e5761268e612657565b8085161561269b57918102915b93841c9390800290612672565b509250929050565b6000826126bf575060016109bd565b816126cc575060006109bd565b81600181146126e257600281146126ec57612708565b60019150506109bd565b60ff8411156126fd576126fd612657565b50506001821b6109bd565b5060208310610133831016604e8410600b841016171561272b575081810a6109bd565b612735838361266d565b806000190482111561274957612749612657565b029392505050565b600061094f60ff8416836126b0565b80820281158282048414176109bd576109bd612657565b60008261279457634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156127ab57600080fd5b5051919050565b818103818111156109bd576109bd612657565b600181811c908216806127d957607f821691505b6020821081036127f957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b808201808211156109bd576109bd612657565b60006001820161283a5761283a612657565b5060010190565b600061094f83836126b0565b600080835481600182811c91508083168061286957607f831692505b6020808410820361288857634e487b7160e01b86526022600452602486fd5b81801561289c57600181146128b1576128de565b60ff19861689528415158502890196506128de565b60008a81526020902060005b868110156128d65781548b8201529085019083016128bd565b505084890196505b509498975050505050505050565b60ff82811682821603908111156109bd576109bd612657565b60ff81811683821601908111156109bd576109bd61265756fea26469706673582212209d49aa90f7b8a61b5eed7d7f5d85819ec7852082afb8b9e0a2eaf81af73bbc8364736f6c63430008110033000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e4200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000012750000000000000000000000000061ed60d00122ce44fc05d8577c7e4746b5cf3a890000000000000000000000000000000000000000000000000000000000000008676c7055534443620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008676c705553444362000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103095760003560e01c80636593c2c91161019c578063acfc67a5116100ee578063cc7d9ade11610097578063d905777e11610071578063d905777e146106ad578063dd62ed3e146106d6578063ef8b30f71461070157600080fd5b8063cc7d9ade14610665578063ce96cb77146104b5578063d505accf1461069a57600080fd5b8063ba087652116100c8578063ba0876521461063f578063c63d75b614610652578063c6e6f5921461038f57600080fd5b8063acfc67a514610624578063b3d7f6b914610359578063b460af941461062c57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105f6578063a9059cbb146105fe578063aa2cb4dc1461061157600080fd5b80637ecebe00146105b0578063930d3f17146105d057806394bf804d146105e357600080fd5b806370a082311161018157806370a0823114610575578063772fa701146105955780637e108d521461059d57600080fd5b80636593c2c91461054f5780636e553f651461056257600080fd5b806329f384e211610260578063402d267d1161020957806352df49ec116101e357806352df49ec1461051157806358d595b3146105315780635c975abb1461054457600080fd5b8063402d267d146104c857806346be9c48146104db5780634cdad506146104fe57600080fd5b806338d52e0f1161023a57806338d52e0f146104765780633e09ed961461049d5780633e642575146104b557600080fd5b806329f384e214610432578063313ce567146104475780633644e5151461046e57600080fd5b8063095ea7b3116102c257806318160ddd1161029c57806318160ddd146103e1578063236136a1146103ea57806323b872dd1461041f57600080fd5b8063095ea7b31461036c5780630a28a4771461038f5780630a5623fb146103a257600080fd5b806301e1d114116102f357806301e1d1141461033c57806306fdde031461034457806307a2d13a1461035957600080fd5b806218b1d31461030e578063010252f814610329575b600080fd5b610316610714565b6040519081526020015b60405180910390f35b6103166103373660046123f5565b61079e565b6103166107c2565b61034c610879565b604051610320919061240e565b6103166103673660046123f5565b610907565b61037f61037a366004612473565b610956565b6040519015158152602001610320565b61031661039d3660046123f5565b6109c3565b6103c97f00000000000000000000000061ed60d00122ce44fc05d8577c7e4746b5cf3a8981565b6040516001600160a01b039091168152602001610320565b61031660025481565b61040d6103f836600461249d565b60096020526000908152604090205460ff1681565b60405160ff9091168152602001610320565b61037f61042d3660046124b8565b610a04565b6104456104403660046123f5565b610af6565b005b61040d7f000000000000000000000000000000000000000000000000000000000000000681565b610316610b9b565b6103c97f000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e4281565b6006546103c99061010090046001600160a01b031681565b6103166104c336600461249d565b610bf1565b6103166104d636600461249d565b610c13565b6007546008546104e9919082565b60408051928352602083019190915201610320565b61031661050c3660046123f5565b610c97565b61052461051f36600461249d565b610ca2565b60405161032091906124f4565b61031661053f36600461253b565b610d19565b60065460ff1661037f565b61044561055d36600461249d565b610f48565b61031661057036600461256e565b61107b565b61031661058336600461249d565b60036020526000908152604090205481565b61044561116c565b6103166105ab3660046123f5565b611213565b6103166105be36600461249d565b60056020526000908152604090205481565b6103166105de36600461249d565b611232565b6103166105f136600461256e565b6113e8565b61034c61147f565b61037f61060c366004612473565b61148c565b6104e961061f366004612473565b611504565b610445611534565b61031661063a366004612591565b6115d9565b61031661064d366004612591565b6116dd565b61031661066036600461249d565b611831565b6040805180820182526000808252602091820152815180830190925260075482526008549082015260405161032091906125cd565b6104456106a83660046125e4565b6118b8565b6103166106bb36600461249d565b6001600160a01b031660009081526003602052604090205490565b6103166106e436600461253b565b600460209081526000928352604080842090915290825290205481565b61031661070f3660046123f5565b611b0b565b600254600090801561076d578061074c7f0000000000000000000000000000000000000000000000000000000000000006600a612751565b6107546107c2565b61075e9190612760565b6107689190612777565b610798565b6107987f0000000000000000000000000000000000000000000000000000000000000006600a612751565b91505090565b60006107a8611b16565b6107b182610907565b90506107bd8282611b69565b919050565b6008546040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600091907f000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e426001600160a01b0316906370a0823190602401602060405180830381865afa158015610846573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086a9190612799565b61087491906127b2565b905090565b60008054610886906127c5565b80601f01602080910402602001604051908101604052809291908181526020018280546108b2906127c5565b80156108ff5780601f106108d4576101008083540402835291602001916108ff565b820191906000526020600020905b8154815290600101906020018083116108e257829003601f168201915b505050505081565b600254600090801561094d576109488361091f610714565b7f000000000000000000000000000000000000000000000000000000000000000660ff16611c69565b61094f565b825b9392505050565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906109b19086815260200190565b60405180910390a35060015b92915050565b600254600090801561094d57610948836109db610714565b7f000000000000000000000000000000000000000000000000000000000000000660ff16611ce2565b6001600160a01b03831660009081526004602090815260408083203384529091528120546000198114610a6057610a3b83826127b2565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610a889084906127b2565b90915550506001600160a01b03808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610ae39087815260200190565b60405180910390a3506001949350505050565b6040516346ea9cc560e01b81527f530008d2b058137d9c475b1b7d83984f1fcf1dd0e607659d029fc1517ab8926860048201523360248201527f00000000000000000000000061ed60d00122ce44fc05d8577c7e4746b5cf3a896001600160a01b0316906346ea9cc59060440160006040518083038186803b158015610b7b57600080fd5b505afa158015610b8f573d6000803e3d6000fd5b50505060079190915550565b60007f000000000000000000000000000000000000000000000000000000000000a4b14614610bcc57610874611d4a565b507f00e54d99b5059caff080fa26abf5eec811cba05c2fd9c97f9927300fcec5341690565b6001600160a01b0381166000908152600360205260408120546109bd90610907565b60007f000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e426001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c73573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bd9190612799565b60006109bd82610907565b610caa6123bc565b6001600160a01b0382166000908152600a6020526040808220815160a08101909252600583835b82821015610d0d578382600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610cd1565b50929695505050505050565b6000610d23611b16565b60065461010090046001600160a01b03163314610d875760405162461bcd60e51b815260206004820152601360248201527f54696d656c6f636b426f6f73743a20215a41500000000000000000000000000060448201526064015b60405180910390fd5b6001600160a01b03831660009081526009602052604090205460ff16610df95760405162461bcd60e51b815260206004820152602160248201527f54696d656c6f636b426f6f73743a20216163746976655769746864726177616c6044820152607360f81b6064820152608401610d7e565b6001600160a01b0383166000908152600a6020526040812090805b6005811015610e9f576007544290848360058110610e3457610e346127ff565b6002020154610e439190612815565b108015610e655750828160058110610e5d57610e5d6127ff565b600202015415155b15610e8d57610e748682611de4565b9150610e808683611ec2565b610e8a8285612815565b93505b80610e9781612828565b915050610e14565b508215610eda57610eda6001600160a01b037f000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e42168585611f24565b604080516001600160a01b038781168252602082018690527f000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e4216917fce67cd4e23f137729b8b844fbf25399d5130346f0d62c18afdc0a943e1d1f101910160405180910390a2505092915050565b6040516346ea9cc560e01b81527f530008d2b058137d9c475b1b7d83984f1fcf1dd0e607659d029fc1517ab8926860048201523360248201527f00000000000000000000000061ed60d00122ce44fc05d8577c7e4746b5cf3a896001600160a01b0316906346ea9cc59060440160006040518083038186803b158015610fcd57600080fd5b505afa158015610fe1573d6000803e3d6000fd5b5050506001600160a01b038216905061103c5760405162461bcd60e51b815260206004820152601660248201527f54696d656c6f636b426f6f73743a205a415020736574000000000000000000006044820152606401610d7e565b600680546001600160a01b03909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b6000611085611b16565b61108e83611b0b565b9050806000036110e05760405162461bcd60e51b815260206004820152600b60248201527f5a45524f5f5348415245530000000000000000000000000000000000000000006044820152606401610d7e565b6111156001600160a01b037f000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e4216333086611fc9565b61111f8282612075565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d791015b60405180910390a392915050565b6040516346ea9cc560e01b81527f530008d2b058137d9c475b1b7d83984f1fcf1dd0e607659d029fc1517ab8926860048201523360248201527f00000000000000000000000061ed60d00122ce44fc05d8577c7e4746b5cf3a896001600160a01b0316906346ea9cc59060440160006040518083038186803b1580156111f157600080fd5b505afa158015611205573d6000803e3d6000fd5b505050506112116120e1565b565b600061121d611b16565b611226826109c3565b90506107bd8183611b69565b600061123c611b16565b3360009081526009602052604090205460ff166112a55760405162461bcd60e51b815260206004820152602160248201527f54696d656c6f636b426f6f73743a20216163746976655769746864726177616c6044820152607360f81b6064820152608401610d7e565b336000908152600a6020526040812090805b60058110156113425760075442908483600581106112d7576112d76127ff565b60020201546112e69190612815565b1080156113085750828160058110611300576113006127ff565b600202015415155b15611330576113173382611de4565b91506113233383611ec2565b61132d8285612815565b93505b8061133a81612828565b9150506112b7565b50821561137d5761137d6001600160a01b037f000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e42168585611f24565b60408051338152602081018590526001600160a01b037f000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e4216917fce67cd4e23f137729b8b844fbf25399d5130346f0d62c18afdc0a943e1d1f101910160405180910390a25050919050565b60006113f2611b16565b6113fb83610907565b90506114326001600160a01b037f000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e4216333084611fc9565b61143c8284612075565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910161115e565b60018054610886906127c5565b336000908152600360205260408120805483919083906114ad9084906127b2565b90915550506001600160a01b038316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906109b19086815260200190565b600a602052816000526040600020816005811061152057600080fd5b600202018054600190910154909250905082565b6040516346ea9cc560e01b81527f530008d2b058137d9c475b1b7d83984f1fcf1dd0e607659d029fc1517ab8926860048201523360248201527f00000000000000000000000061ed60d00122ce44fc05d8577c7e4746b5cf3a896001600160a01b0316906346ea9cc59060440160006040518083038186803b1580156115b957600080fd5b505afa1580156115cd573d6000803e3d6000fd5b50505050611211612133565b60006115e4846109c3565b9050336001600160a01b03831614611654576001600160a01b038216600090815260046020908152604080832033845290915290205460001981146116525761162d82826127b2565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b61165e8282612174565b60408051858152602081018390526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a461094f6001600160a01b037f000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e42168486611f24565b6000336001600160a01b0383161461174d576001600160a01b0382166000908152600460209081526040808320338452909152902054600019811461174b5761172685826127b2565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b61175684610c97565b9050806000036117a85760405162461bcd60e51b815260206004820152600b60248201527f5a45524f5f4153534554530000000000000000000000000000000000000000006044820152606401610d7e565b6117b28285612174565b60408051828152602081018690526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a461094f6001600160a01b037f000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e42168483611f24565b60006109bd7f000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e426001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611894573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039d9190612799565b428410156119085760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610d7e565b60006001611914610b9b565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611a20573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590611a565750876001600160a01b0316816001600160a01b0316145b611aa25760405162461bcd60e51b815260206004820152600e60248201527f494e56414c49445f5349474e45520000000000000000000000000000000000006044820152606401610d7e565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b60006109bd826109c3565b60065460ff16156112115760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d7e565b33600090815260096020526040902054600560ff90911610611bd75760405162461bcd60e51b815260206004820152602160248201527f54696d656c6f636b426f6f73743a203e204c4f434b5f51554555455f4c494d496044820152601560fa1b6064820152608401610d7e565b611be133826121e8565b611beb33826122db565b611bf53383612174565b6007546040805133815260208101849052908101919091526001600160a01b037f000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e4216907fcd8ae332c101158982911dd43228c7737f41d0a23cb7c71ca936fccf8df4f5339060600160405180910390a25050565b600060018311611cbb5760405162461bcd60e51b815260206004820152601560248201527f496e76616c6964206173736574506572536861726500000000000000000000006044820152606401610d7e565b611cc682600a612841565b611cd08486612760565b611cda9190612777565b949350505050565b600060018311611d345760405162461bcd60e51b815260206004820152601560248201527f496e76616c6964206173736574506572536861726500000000000000000000006044820152606401610d7e565b82611d4083600a612841565b611cd09086612760565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051611d7c919061284d565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6001600160a01b0382166000908152600a602052604081206007544290828560058110611e1357611e136127ff565b6002020154611e229190612815565b10611e7a5760405162461bcd60e51b815260206004820152602260248201527f54696d656c6f636b426f6f73743a20217769746864726177616c44757261746960448201526137b760f11b6064820152608401610d7e565b808360058110611e8c57611e8c6127ff565b60020201600101549150808360058110611ea857611ea86127ff565b600060029190910291909101818155600101555092915050565b8060076001016000828254611ed791906127b2565b90915550506001600160a01b0382166000908152600960205260408120805460019290611f0890849060ff166128ec565b92506101000a81548160ff021916908360ff1602179055505050565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080611fc35760405162461bcd60e51b815260206004820152600f60248201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152606401610d7e565b50505050565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d116001600051141617169150508061206e5760405162461bcd60e51b815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152606401610d7e565b5050505050565b80600260008282546120879190612815565b90915550506001600160a01b0382166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91015b60405180910390a35050565b6120e961236a565b6006805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b61213b611b16565b6006805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586121163390565b5050565b6001600160a01b0382166000908152600360205260408120805483929061219c9084906127b2565b90915550506002805482900390556040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016120d5565b80600760010160008282546121fd9190612815565b90915550506001600160a01b038216600090815260096020526040812080546001929061222e90849060ff16612905565b82546101009290920a60ff8181021990931691831602179091556001600160a01b03841660009081526009602052604090205460059116111590506121705760405162461bcd60e51b815260206004820152602760248201527f54696d656c6f636b426f6f73743a20216163746976655769746864726177616c60448201527f734c656e677468000000000000000000000000000000000000000000000000006064820152608401610d7e565b6001600160a01b0382166000908152600a60205260408120905b6005811015611fc357818160058110612310576123106127ff565b6002020154600003612358574282826005811061232f5761232f6127ff565b600202015582828260058110612347576123476127ff565b600202016001018190555050505050565b8061236281612828565b9150506122f5565b60065460ff166112115760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610d7e565b6040518060a001604052806005905b60408051808201909152600080825260208201528152602001906001900390816123cb5790505090565b60006020828403121561240757600080fd5b5035919050565b600060208083528351808285015260005b8181101561243b5785810183015185820160400152820161241f565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146107bd57600080fd5b6000806040838503121561248657600080fd5b61248f8361245c565b946020939093013593505050565b6000602082840312156124af57600080fd5b61094f8261245c565b6000806000606084860312156124cd57600080fd5b6124d68461245c565b92506124e46020850161245c565b9150604084013590509250925092565b6101408101818360005b60058110156125325761251c83835180518252602090810151910152565b60409290920191602091909101906001016124fe565b50505092915050565b6000806040838503121561254e57600080fd5b6125578361245c565b91506125656020840161245c565b90509250929050565b6000806040838503121561258157600080fd5b823591506125656020840161245c565b6000806000606084860312156125a657600080fd5b833592506125b66020850161245c565b91506125c46040850161245c565b90509250925092565b8151815260208083015190820152604081016109bd565b600080600080600080600060e0888a0312156125ff57600080fd5b6126088861245c565b96506126166020890161245c565b95506040880135945060608801359350608088013560ff8116811461263a57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b634e487b7160e01b600052601160045260246000fd5b600181815b808511156126a857816000190482111561268e5761268e612657565b8085161561269b57918102915b93841c9390800290612672565b509250929050565b6000826126bf575060016109bd565b816126cc575060006109bd565b81600181146126e257600281146126ec57612708565b60019150506109bd565b60ff8411156126fd576126fd612657565b50506001821b6109bd565b5060208310610133831016604e8410600b841016171561272b575081810a6109bd565b612735838361266d565b806000190482111561274957612749612657565b029392505050565b600061094f60ff8416836126b0565b80820281158282048414176109bd576109bd612657565b60008261279457634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156127ab57600080fd5b5051919050565b818103818111156109bd576109bd612657565b600181811c908216806127d957607f821691505b6020821081036127f957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b808201808211156109bd576109bd612657565b60006001820161283a5761283a612657565b5060010190565b600061094f83836126b0565b600080835481600182811c91508083168061286957607f831692505b6020808410820361288857634e487b7160e01b86526022600452602486fd5b81801561289c57600181146128b1576128de565b60ff19861689528415158502890196506128de565b60008a81526020902060005b868110156128d65781548b8201529085019083016128bd565b505084890196505b509498975050505050505050565b60ff82811682821603908111156109bd576109bd612657565b60ff81811683821601908111156109bd576109bd61265756fea26469706673582212209d49aa90f7b8a61b5eed7d7f5d85819ec7852082afb8b9e0a2eaf81af73bbc8364736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e4200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000012750000000000000000000000000061ed60d00122ce44fc05d8577c7e4746b5cf3a890000000000000000000000000000000000000000000000000000000000000008676c7055534443620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008676c705553444362000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _asset (address): 0x727eD4eF04bB2a96Ec77e44C1a91dbB01B605e42
Arg [1] : _name (string): glpUSDCb
Arg [2] : _symbol (string): glpUSDCb
Arg [3] : _withdrawDuration (uint256): 1209600
Arg [4] : _auth (address): 0x61Ed60d00122ce44fC05D8577C7E4746B5CF3A89
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 000000000000000000000000727ed4ef04bb2a96ec77e44c1a91dbb01b605e42
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000127500
Arg [4] : 00000000000000000000000061ed60d00122ce44fc05d8577c7e4746b5cf3a89
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [6] : 676c705553444362000000000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [8] : 676c705553444362000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.
Add Token to MetaMask (Web3)