Source Code
Latest 17 from a total of 17 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer Ownersh... | 18964194 | 293 days ago | IN | 0 S | 0.00166229 | ||||
| Release Schedule | 18323185 | 296 days ago | IN | 0 S | 0.0031661 | ||||
| Create Schedule | 18323185 | 296 days ago | IN | 0 S | 0.0057767 | ||||
| Release Schedule | 18322752 | 296 days ago | IN | 0 S | 0.00319025 | ||||
| Create Schedule | 18322752 | 296 days ago | IN | 0 S | 0.00666495 | ||||
| Release Schedule | 18008579 | 297 days ago | IN | 0 S | 0.0031661 | ||||
| Create Schedule | 18008579 | 297 days ago | IN | 0 S | 0.00577735 | ||||
| Release Schedule | 18008579 | 297 days ago | IN | 0 S | 0.0031661 | ||||
| Create Schedule | 18008577 | 297 days ago | IN | 0 S | 0.00577735 | ||||
| Release Schedule | 18008577 | 297 days ago | IN | 0 S | 0.00319025 | ||||
| Create Schedule | 18008577 | 297 days ago | IN | 0 S | 0.00666495 | ||||
| Release Schedule | 17913255 | 298 days ago | IN | 0 S | 0.00489304 | ||||
| Create Schedule | 17913255 | 298 days ago | IN | 0 S | 0.00892859 | ||||
| Release Schedule | 17913255 | 298 days ago | IN | 0 S | 0.00489304 | ||||
| Create Schedule | 17913255 | 298 days ago | IN | 0 S | 0.00892859 | ||||
| Release Schedule | 17913255 | 298 days ago | IN | 0 S | 0.00493036 | ||||
| Create Schedule | 17913255 | 298 days ago | IN | 0 S | 0.01030033 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 15893366 | 307 days ago | Contract Creation | 0 S |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Treasury
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 200 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
import {CustomRevert} from "./libs/CustomRevert.sol";
import {ITreasury} from "./interfaces/ITreasury.sol";
/**
* @title Treasury
* @notice A contract that manages schedules of reserved tokens for multiple vesting
* contracts (beneficiaries). The owner can create/delete schedules, release them,
* and deposit tokens. Each vesting contract can pull only its released tokens.
*/
contract Treasury is Ownable, Pausable, ReentrancyGuard, ITreasury {
using SafeERC20 for IERC20;
using CustomRevert for bytes4;
/**
* @notice The ERC20 token this Treasury manages.
*/
IERC20 public immutable token;
/**
* @notice Total amount of tokens reserved across all schedules
*/
uint256 public totalReservedTokens;
/**
* @notice Flag to prevent schedule index reuse after deletion, keyed by (vestingContract => scheduleIndex).
*/
mapping(address => mapping(uint256 => bool)) public isScheduleDeleted;
/**
* @notice Holds an array of vesting schedules for each vesting contract (beneficiary).
* Using an array allows the same address to have multiple schedules.
*/
mapping(address => VestingSchedule[]) public schedules;
/**
* @notice Constructor that sets the token managed by this contract.
* @param _token The address of the ERC20 token to manage.
* @param _admin The address that can create/delete schedules and release them.
*/
constructor(address _token, address _admin) Ownable(_admin) {
if (_token == address(0))
ITreasury.ErrorZeroAddress.selector.revertWith();
if (_admin == address(0))
ITreasury.ErrorZeroAddress.selector.revertWith();
token = IERC20(_token);
}
receive() external payable {
ITreasury.ErrorNoEtherAccepted.selector.revertWith();
}
fallback() external payable {
ITreasury.ErrorNoEtherAccepted.selector.revertWith();
}
/**
* @notice Creates a new vesting schedule for a given vesting contract (beneficiary).
* Tokens do not immediately leave the Treasury; they are reserved.
* They can only be pulled once the schedule is released.
*
* @param _vestingContract The vesting contract (beneficiary) address for this schedule.
* @param _reservedTokenAmount Amount of tokens to reserve for this schedule.
* @return scheduleIndex The index of the newly created schedule in schedules[_vestingContract].
*/
function createSchedule(
address _vestingContract,
uint256 _reservedTokenAmount
) external onlyOwner returns (uint256 scheduleIndex) {
if (_vestingContract == address(0))
ITreasury.ErrorZeroAddress.selector.revertWith();
if (_reservedTokenAmount == 0)
ITreasury.ErrorZeroAmount.selector.revertWith();
uint256 balance = token.balanceOf(address(this));
if (balance < totalReservedTokens + _reservedTokenAmount) {
ITreasury.ErrorInsufficientTreasuryBalance.selector.revertWith();
}
if (_reservedTokenAmount > balance - totalReservedTokens) {
ITreasury.ErrorExceedsAvailableBalance.selector.revertWith();
}
VestingSchedule memory newSchedule = VestingSchedule({
reservedTokenAmount: _reservedTokenAmount,
createdAt: block.timestamp,
validUntil: 0,
lastClaimedTimestamp: 0,
isReleased: false
});
schedules[_vestingContract].push(newSchedule);
totalReservedTokens += _reservedTokenAmount;
scheduleIndex = schedules[_vestingContract].length - 1;
emit ScheduleCreated(
_vestingContract,
scheduleIndex,
_reservedTokenAmount
);
return scheduleIndex;
}
/**
* @notice Releases a vesting schedule so that the vesting contract can pull its tokens.
* Sets an optional expiry timestamp. If _validUntil is 0, there's effectively
* no expiration on pulling tokens.
*
* @param _vestingContract The vesting contract (beneficiary) address.
* @param _scheduleIndex Index of the schedule in schedules[_vestingContract].
* @param _validUntil Timestamp until which the schedule is valid (0 if unlimited).
*/
function releaseSchedule(
address _vestingContract,
uint256 _scheduleIndex,
uint256 _validUntil
) external onlyOwner {
if (_vestingContract == address(0))
ITreasury.ErrorZeroAddress.selector.revertWith();
if (_scheduleIndex >= schedules[_vestingContract].length) {
ITreasury.ErrorInvalidScheduleIndex.selector.revertWith();
}
if (_validUntil != 0 && _validUntil <= block.timestamp) {
ITreasury.ErrorInvalidValidUntil.selector.revertWith();
}
VestingSchedule storage vestingSchedule = schedules[_vestingContract][
_scheduleIndex
];
if (vestingSchedule.isReleased)
ITreasury.ErrorScheduleAlreadyReleased.selector.revertWith();
if (
token.balanceOf(address(this)) < vestingSchedule.reservedTokenAmount
) {
ITreasury.ErrorInsufficientTreasuryBalance.selector.revertWith();
}
vestingSchedule.isReleased = true;
vestingSchedule.validUntil = _validUntil;
emit ScheduleReleased(_vestingContract, _scheduleIndex, _validUntil);
}
/**
* @notice Deletes (cancels) a vesting schedule before it is released or after it expires.
*
* @param _vestingContract The vesting contract (beneficiary) address.
* @param _scheduleIndex Index of the schedule to delete.
*/
function deleteSchedule(
address _vestingContract,
uint256 _scheduleIndex
) external nonReentrant onlyOwner {
if (_vestingContract == address(0))
ITreasury.ErrorZeroAddress.selector.revertWith();
if (_scheduleIndex >= schedules[_vestingContract].length) {
ITreasury.ErrorInvalidScheduleIndex.selector.revertWith();
}
VestingSchedule memory vestingSchedule = schedules[_vestingContract][
_scheduleIndex
];
bool canDelete = (!vestingSchedule.isReleased ||
(vestingSchedule.isReleased &&
vestingSchedule.validUntil > 0 &&
block.timestamp > vestingSchedule.validUntil &&
vestingSchedule.reservedTokenAmount > 0));
if (!canDelete)
ITreasury.ErrorCannotDeleteSchedule.selector.revertWith();
isScheduleDeleted[_vestingContract][_scheduleIndex] = true;
totalReservedTokens -= vestingSchedule.reservedTokenAmount;
_deleteArrayElement(_vestingContract, _scheduleIndex);
emit ScheduleDeleted(_vestingContract, _scheduleIndex);
}
/**
* @notice Pulls (transfers) the reserved tokens from this Treasury into the calling
* vesting contract, but only if the schedule is released.
*
* @param _scheduleIndex The index of the schedule to pull.
* @return amountToSend The amount of tokens sent to the vesting contract.
*/
function pullForVesting(
uint256 _scheduleIndex
) external nonReentrant whenNotPaused returns (uint256) {
address _vestingContract = msg.sender;
if (_scheduleIndex >= schedules[_vestingContract].length) {
ITreasury.ErrorInvalidScheduleIndex.selector.revertWith();
}
if (isScheduleDeleted[_vestingContract][_scheduleIndex]) {
ITreasury.ErrorScheduleDeleted.selector.revertWith();
}
VestingSchedule storage vestingSchedule = schedules[_vestingContract][
_scheduleIndex
];
if (!vestingSchedule.isReleased)
ITreasury.ErrorScheduleNotReleased.selector.revertWith();
if (
vestingSchedule.validUntil != 0 &&
block.timestamp > vestingSchedule.validUntil
) {
ITreasury.ErrorScheduleExpired.selector.revertWith();
}
if (vestingSchedule.reservedTokenAmount == 0)
ITreasury.ErrorNoTokensToPull.selector.revertWith();
if (
token.balanceOf(address(this)) < vestingSchedule.reservedTokenAmount
) {
ITreasury.ErrorInsufficientTreasuryBalance.selector.revertWith();
}
uint256 amountToSend = vestingSchedule.reservedTokenAmount;
vestingSchedule.lastClaimedTimestamp = block.timestamp;
vestingSchedule.reservedTokenAmount = 0;
totalReservedTokens -= amountToSend;
token.safeTransfer(msg.sender, amountToSend);
emit TokensPulled(msg.sender, _scheduleIndex, amountToSend);
return amountToSend;
}
/**
* @notice Deposits tokens into this Treasury from the caller's wallet.
* @param _amount The amount of tokens to deposit.
*/
function deposit(uint256 _amount) external onlyOwner nonReentrant {
if (_amount == 0) ITreasury.ErrorZeroAmount.selector.revertWith();
uint256 currentBalance = token.balanceOf(address(this));
if (_amount > type(uint256).max - currentBalance) {
ITreasury.ErrorAmountTooLarge.selector.revertWith();
}
uint256 balanceBefore = currentBalance;
token.safeTransferFrom(msg.sender, address(this), _amount);
uint256 newBalance = token.balanceOf(address(this));
if (newBalance - balanceBefore != _amount) {
ITreasury.ErrorTransferAmountMismatch.selector.revertWith();
}
if (newBalance < totalReservedTokens) {
ITreasury.ErrorInsufficientTotalBalance.selector.revertWith();
}
emit TokensDeposited(msg.sender, _amount);
}
/**
* @notice Returns the current token balance of this Treasury.
*
* @return balance The ERC20 token balance of this contract.
*/
function getBalance() external view returns (uint256 balance) {
balance = token.balanceOf(address(this));
}
/**
* @notice Returns the number of schedules for a given vesting contract.
* @param _vestingContract The vesting contract address to check.
* @return count The number of schedules.
*/
function getScheduleCount(
address _vestingContract
) external view returns (uint256) {
return schedules[_vestingContract].length;
}
/**
* @notice Returns the amount of unreserved tokens in the Treasury.
* @return amount The amount of tokens not reserved in any schedule.
*/
function getUnreservedTokens() external view returns (uint256) {
uint256 balance = token.balanceOf(address(this));
return
balance > totalReservedTokens ? balance - totalReservedTokens : 0;
}
/**
* @dev Internal helper to remove a schedule from the array by index.
*/
function _deleteArrayElement(
address _vestingContract,
uint256 _index
) internal {
VestingSchedule storage schedule = schedules[_vestingContract][_index];
schedule.reservedTokenAmount = 0;
schedule.isReleased = false;
schedule.validUntil = 0;
}
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}
function recoverERC20(
address tokenAddress,
uint256 tokenAmount
) external onlyOwner nonReentrant {
IERC20(tokenAddress).safeTransfer(msg.sender, tokenAmount);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.2.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
bool private _paused;
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
/**
* @dev The operation failed because the contract is paused.
*/
error EnforcedPause();
/**
* @dev The operation failed because the contract is not paused.
*/
error ExpectedPause();
/**
* @dev 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 {
if (paused()) {
revert EnforcedPause();
}
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
// solhint-disable
/// @title Library for reverting with custom errors efficiently
/// @notice Contains functions for reverting with custom errors with different argument types efficiently
/// @dev To use this library, declare `using CustomRevert for bytes4;` and replace `revert CustomError()` with
/// `CustomError.selector.revertWith()`
/// @dev The functions may tamper with the free memory pointer but it is fine since the call context is exited immediately
library CustomRevert {
/// @dev Reverts with the selector of a custom error in the scratch space
function revertWith(bytes4 selector) internal pure {
assembly ("memory-safe") {
mstore(0, selector)
revert(0, 0x04)
}
}
/// @dev Reverts with a custom error with an address argument in the scratch space
function revertWith(bytes4 selector, address addr) internal pure {
assembly ("memory-safe") {
mstore(0, selector)
mstore(0x04, and(addr, 0xffffffffffffffffffffffffffffffffffffffff))
revert(0, 0x24)
}
}
/// @dev Reverts with a custom error with an int24 argument in the scratch space
function revertWith(bytes4 selector, int24 value) internal pure {
assembly ("memory-safe") {
mstore(0, selector)
mstore(0x04, signextend(2, value))
revert(0, 0x24)
}
}
/// @dev Reverts with a custom error with a uint160 argument in the scratch space
function revertWith(bytes4 selector, uint160 value) internal pure {
assembly ("memory-safe") {
mstore(0, selector)
mstore(0x04, and(value, 0xffffffffffffffffffffffffffffffffffffffff))
revert(0, 0x24)
}
}
/// @dev Reverts with a custom error with two int24 arguments
function revertWith(bytes4 selector, int24 value1, int24 value2) internal pure {
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(fmp, selector)
mstore(add(fmp, 0x04), signextend(2, value1))
mstore(add(fmp, 0x24), signextend(2, value2))
revert(fmp, 0x44)
}
}
/// @dev Reverts with a custom error with two uint160 arguments
function revertWith(bytes4 selector, uint160 value1, uint160 value2) internal pure {
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(fmp, selector)
mstore(add(fmp, 0x04), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(fmp, 0x24), and(value2, 0xffffffffffffffffffffffffffffffffffffffff))
revert(fmp, 0x44)
}
}
/// @dev Reverts with a custom error with two address arguments
function revertWith(bytes4 selector, address value1, address value2) internal pure {
assembly ("memory-safe") {
mstore(0, selector)
mstore(0x04, and(value1, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(0x24, and(value2, 0xffffffffffffffffffffffffffffffffffffffff))
revert(0, 0x44)
}
}
/// @dev Reverts with a custom error with a bytes32 argument in the scratch space
function revertWith(bytes4 selector, bytes32 value) internal pure {
assembly ("memory-safe") {
mstore(0, selector)
mstore(0x04, value)
revert(0, 0x24)
}
}
/// @notice bubble up the revert message returned by a call and revert with the selector provided
/// @dev this function should only be used with custom errors of the type `CustomError(address target, bytes revertReason)`
function bubbleUpAndRevertWith(bytes4 selector, address addr) internal pure {
assembly ("memory-safe") {
let size := returndatasize()
let fmp := mload(0x40)
// Encode selector, address, offset, size, data
mstore(fmp, selector)
mstore(add(fmp, 0x04), addr)
mstore(add(fmp, 0x24), 0x40)
mstore(add(fmp, 0x44), size)
returndatacopy(add(fmp, 0x64), 0, size)
// Ensure the size is a multiple of 32 bytes
let encodedSize := add(0x64, mul(div(add(size, 31), 32), 32))
revert(fmp, encodedSize)
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
interface ITreasury {
// Custom Errors
error ErrorZeroAddress();
error ErrorZeroAmount();
error ErrorInvalidScheduleIndex();
error ErrorScheduleAlreadyReleased();
error ErrorInvalidValidUntil();
error ErrorInsufficientTreasuryBalance();
error ErrorExceedsAvailableBalance();
error ErrorCannotDeleteSchedule();
error ErrorScheduleDeleted();
error ErrorScheduleNotReleased();
error ErrorScheduleExpired();
error ErrorNoTokensToPull();
error ErrorTransferAmountMismatch();
error ErrorInsufficientTotalBalance();
error ErrorAmountTooLarge();
error ErrorNoEtherAccepted();
error ErrorNotOwner();
error ErrorCannotRecoverTreasuryToken();
/**
* @notice Represents a single vesting schedule for a particular vesting contract.
* @dev Multiple schedules can exist for the same vesting contract (beneficiary).
*
* @param reservedTokenAmount Amount of tokens reserved for this schedule.
* @param createdAt Timestamp when this schedule was created.
* @param validUntil When this schedule expires. If zero, no expiry limit.
* @param lastClaimedTimestamp When tokens were last pulled for vesting (set on pull).
* @param isReleased Whether the schedule is released. Must be true to pull.
*/
struct VestingSchedule {
uint256 reservedTokenAmount;
uint256 createdAt;
uint256 validUntil;
uint256 lastClaimedTimestamp;
bool isReleased;
}
/**
* @notice Emitted when a new vesting schedule is created.
*
* @param vestingContract The vesting contract (beneficiary) that this schedule belongs to.
* @param scheduleIndex Index of the newly created schedule in schedules[vestingContract].
* @param reservedAmount Amount of tokens reserved for this schedule.
*/
event ScheduleCreated(
address indexed vestingContract,
uint256 indexed scheduleIndex,
uint256 reservedAmount
);
/**
* @notice Emitted when a vesting schedule is released.
*
* @param vestingContract The vesting contract (beneficiary) that this schedule belongs to.
* @param scheduleIndex Index of the released schedule.
* @param validUntil The expiration timestamp set for this schedule.
*/
event ScheduleReleased(
address indexed vestingContract,
uint256 indexed scheduleIndex,
uint256 validUntil
);
/**
* @notice Emitted when a vesting schedule is deleted (cancelled) by the owner.
*
* @param vestingContract The vesting contract (beneficiary) that this schedule belongs to.
* @param scheduleIndex Index of the deleted schedule.
*/
event ScheduleDeleted(
address indexed vestingContract,
uint256 indexed scheduleIndex
);
/**
* @notice Emitted when tokens are deposited into this Treasury.
*
* @param sender Address that sent the tokens.
* @param amount Amount of tokens deposited.
*/
event TokensDeposited(address indexed sender, uint256 amount);
/**
* @notice Emitted when tokens are pulled for vesting by a vesting contract.
*
* @param vestingContract Address of the vesting contract (msg.sender).
* @param scheduleIndex Index of the schedule that was pulled.
* @param amount Amount of tokens pulled.
*/
event TokensPulled(
address indexed vestingContract,
uint256 indexed scheduleIndex,
uint256 amount
);
function pullForVesting(uint256 scheduleIndex) external returns (uint256 vestedAmount);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol)
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"ds-test/=lib/layerzero-v2/lib/forge-std/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"@layerzerolabs/oft-evm/=lib/devtools/packages/oft-evm/",
"@layerzerolabs/oapp-evm/=lib/devtools/packages/oapp-evm/",
"@layerzerolabs/lz-evm-protocol-v2/=lib/layerzero-v2/packages/layerzero-v2/evm/protocol/",
"@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
"@openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"@layerzerolabs/test-devtools-evm-foundry/contracts/=node_modules/@layerzerolabs/test-devtools-evm-foundry/contracts/",
"@layerzerolabs/lz-evm-messagelib-v2/=lib/layerzero-v2/packages/layerzero-v2/evm/messagelib/",
"solidity-bytes-utils/=node_modules/@layerzerolabs/solidity-bytes-utils/",
"@layerzerolabs/lz-evm-v1-0.7/=node_modules/@layerzerolabs/lz-evm-v1-0.7/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"devtools/=lib/devtools/packages/toolbox-foundry/src/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
"layerzero-v2/=lib/layerzero-v2/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/",
"openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "london",
"viaIR": true,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_admin","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ErrorAmountTooLarge","type":"error"},{"inputs":[],"name":"ErrorCannotDeleteSchedule","type":"error"},{"inputs":[],"name":"ErrorCannotRecoverTreasuryToken","type":"error"},{"inputs":[],"name":"ErrorExceedsAvailableBalance","type":"error"},{"inputs":[],"name":"ErrorInsufficientTotalBalance","type":"error"},{"inputs":[],"name":"ErrorInsufficientTreasuryBalance","type":"error"},{"inputs":[],"name":"ErrorInvalidScheduleIndex","type":"error"},{"inputs":[],"name":"ErrorInvalidValidUntil","type":"error"},{"inputs":[],"name":"ErrorNoEtherAccepted","type":"error"},{"inputs":[],"name":"ErrorNoTokensToPull","type":"error"},{"inputs":[],"name":"ErrorNotOwner","type":"error"},{"inputs":[],"name":"ErrorScheduleAlreadyReleased","type":"error"},{"inputs":[],"name":"ErrorScheduleDeleted","type":"error"},{"inputs":[],"name":"ErrorScheduleExpired","type":"error"},{"inputs":[],"name":"ErrorScheduleNotReleased","type":"error"},{"inputs":[],"name":"ErrorTransferAmountMismatch","type":"error"},{"inputs":[],"name":"ErrorZeroAddress","type":"error"},{"inputs":[],"name":"ErrorZeroAmount","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vestingContract","type":"address"},{"indexed":true,"internalType":"uint256","name":"scheduleIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reservedAmount","type":"uint256"}],"name":"ScheduleCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vestingContract","type":"address"},{"indexed":true,"internalType":"uint256","name":"scheduleIndex","type":"uint256"}],"name":"ScheduleDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vestingContract","type":"address"},{"indexed":true,"internalType":"uint256","name":"scheduleIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"validUntil","type":"uint256"}],"name":"ScheduleReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vestingContract","type":"address"},{"indexed":true,"internalType":"uint256","name":"scheduleIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensPulled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"_vestingContract","type":"address"},{"internalType":"uint256","name":"_reservedTokenAmount","type":"uint256"}],"name":"createSchedule","outputs":[{"internalType":"uint256","name":"scheduleIndex","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vestingContract","type":"address"},{"internalType":"uint256","name":"_scheduleIndex","type":"uint256"}],"name":"deleteSchedule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vestingContract","type":"address"}],"name":"getScheduleCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUnreservedTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"isScheduleDeleted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_scheduleIndex","type":"uint256"}],"name":"pullForVesting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vestingContract","type":"address"},{"internalType":"uint256","name":"_scheduleIndex","type":"uint256"},{"internalType":"uint256","name":"_validUntil","type":"uint256"}],"name":"releaseSchedule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"schedules","outputs":[{"internalType":"uint256","name":"reservedTokenAmount","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"uint256","name":"validUntil","type":"uint256"},{"internalType":"uint256","name":"lastClaimedTimestamp","type":"uint256"},{"internalType":"bool","name":"isReleased","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReservedTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60a03461012857601f6112b138819003918201601f19168301916001600160401b0383118484101761012d5780849260409485528339810103126101285761004681610143565b906001600160a01b039061005c90602001610143565b169081156101125760008054604051939182906001600160a01b038316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a36001600160a81b03191617600055600180556001600160a01b03168015610101576080526111599081610158823960805181818161012c0152818161023f015281816104930152818161083b01528181610b6f01528181610c770152610f0a0152f35b63a7f9319d60e01b60005260046000fd5b631e4fbdf760e01b600052600060045260246000fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b03821682036101285756fe6080806040526004361015610038575b503615610027576353a4b68560e11b60005260046000fd5b6353a4b68560e11b60005260046000fd5b60003560e01c90816312065fe014610ee1575080631bf45ba814610d48578063240894aa14610d0e5780632e55b2a414610c4b5780633eddd6d714610ad05780633f4ba83a14610a5f5780635c975abb14610a395780635cfa946a14610a1b5780636dfa00a8146109ce578063715018a61461097557806377772ebe146107875780638456cb5914610725578063854e9682146106a05780638980f11f1461065a5780638da5cb5b14610631578063b6b55f2514610454578063cf86cf69146101e9578063f2fde38b146101605763fc0c546a14610116573861000f565b3461015b57600036600319011261015b576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b600080fd5b3461015b57602036600319011261015b57610179610f80565b610181611042565b6001600160a01b031680156101d357600080546001600160a01b03198116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b631e4fbdf760e01b600052600060045260246000fd5b3461015b57604036600319011261015b57610202610f80565b6024359061020e611042565b6001600160a01b0316908115610443578015610432576040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610426576000916103f1575b506002546102868382611013565b82106103e05761029591611006565b81116103cf576040516102a781610fc8565b8181526020810190428252604081019160008352606082016000815260808301936000855286600052600460205260406000208054680100000000000000008110156103b9576102fc91600182018155610f96565b9390936103a357600494518455516001840155516002830155516003820155019051151560ff8019835416911617905561033881600254611013565b60025581600052600460205260406000205490600019820191821161038d576020927fb871057cd3f316a478a827f65b30581628abf740760eb31d9c6df28c98ffc438848493604051908152a3604051908152f35b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600060045260246000fd5b634e487b7160e01b600052604160045260246000fd5b637f7afb7960e01b60005260046000fd5b6338985e0960e21b60005260046000fd5b906020823d60201161041e575b8161040b60209383610fe4565b8101031261041b57505183610278565b80fd5b3d91506103fe565b6040513d6000823e3d90fd5b633245e1f960e21b60005260046000fd5b63a7f9319d60e01b60005260046000fd5b3461015b57602036600319011261015b57600435610470611042565b610478611020565b8015610432576040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03811690602083602481855afa928315610426576000936105fd575b50821984116105ec5760249161051c602092604051906323b872dd60e01b85830152338683015230604483015287606483015260648252610517608483610fe4565b6110c8565b6040516370a0823160e01b815230600482015292839182905afa9182156104265783916000936105b3575b506105529083611006565b036105a25760025411610591576040519081527f59062170a285eb80e8c6b8ced60428442a51910635005233fc4ce084a475845e60203392a260018055005b638c53e5cb60e01b60005260046000fd5b63e40eec7160e01b60005260046000fd5b9150916020823d6020116105e4575b816105cf60209383610fe4565b8101031261041b575051908290610552610547565b3d91506105c2565b636c31405b60e01b60005260046000fd5b90926020823d602011610629575b8161061860209383610fe4565b8101031261041b57505191846104d5565b3d915061060b565b3461015b57600036600319011261015b576000546040516001600160a01b039091168152602090f35b3461015b57604036600319011261015b5761069a610676610f80565b61067e611042565b610686611020565b6024359033906001600160a01b031661108b565b60018055005b3461015b57604036600319011261015b576106b9610f80565b6001600160a01b031660009081526004602052604090208054602435919082101561015b5760a0916106ea91610f96565b50805490600181015490600281015460ff60046003840154930154169260405194855260208501526040840152606083015215156080820152f35b3461015b57600036600319011261015b5761073e611042565b61074661106b565b6000805460ff60a01b1916600160a01b1790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602090a1005b3461015b57602036600319011261015b576004356107a3611020565b6107ab61106b565b3360005260046020526040600020548110156109645733600052600360205260406000208160005260205260ff60406000205416610953573360005260046020526107fa816040600020610f96565b509060ff600483015416156109425760028201548015159081610938575b50610927578154908115610916576040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000906020816024816001600160a01b0386165afa80156104265784916000916108e1575b50106103e057826108aa916000602096426003820155556108a082600254611006565b600255339061108b565b6040518281527f8614f23128d0a8e985869427ff11ceaddbf20d7bba7b150fc59aa091496283e9843392a360018055604051908152f35b9150506020813d60201161090e575b816108fd60209383610fe4565b8101031261015b578390518661087d565b3d91506108f0565b6313b1306560e11b60005260046000fd5b636ea469c160e11b60005260046000fd5b9050421183610818565b6339c5476d60e11b60005260046000fd5b630a7f9f9360e11b60005260046000fd5b630ec4187760e41b60005260046000fd5b3461015b57600036600319011261015b5761098e611042565b600080546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461015b57604036600319011261015b576001600160a01b036109ef610f80565b1660005260036020526040600020602435600052602052602060ff604060002054166040519015158152f35b3461015b57600036600319011261015b576020600254604051908152f35b3461015b57600036600319011261015b57602060ff60005460a01c166040519015158152f35b3461015b57600036600319011261015b57610a78611042565b60005460ff8160a01c1615610abf5760ff60a01b19166000556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602090a1005b638dfc202b60e01b60005260046000fd5b3461015b57606036600319011261015b57610ae9610f80565b6024359060443590610af9611042565b6001600160a01b0316908115610443578160005260046020526040600020548310156109645780151580610c41575b610c3057816000526004602052610b43836040600020610f96565b50600481019182549260ff8416610c1f576040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561042657600091610bed575b508354116103e0576002602093839260017f064bfba6a7df806040dba4fda0e456633569d804251c82c861cbfac64411b6ea9760ff19161790550155604051908152a3005b90506020813d602011610c17575b81610c0860209383610fe4565b8101031261015b575187610ba8565b3d9150610bfb565b632488da9560e11b60005260046000fd5b63048c286960e01b60005260046000fd5b5042811115610b28565b3461015b57600036600319011261015b576040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561042657600091610cdc575b506002549081811115610cd157602091610cc991611006565b604051908152f35b505060206000610cc9565b906020823d602011610d06575b81610cf660209383610fe4565b8101031261041b57505181610cb0565b3d9150610ce9565b3461015b57602036600319011261015b576001600160a01b03610d2f610f80565b1660005260046020526020604060002054604051908152f35b3461015b57604036600319011261015b57610d61610f80565b60243590610d6d611020565b610d75611042565b6001600160a01b031680156104435780600052600460205260406000205482101561096457806000526004602052610db1826040600020610f96565b5060405190610dbf82610fc8565b80548083526001820154602084015260ff6004600284015493846040870152600381015460608701520154161590811592839283608087015293610ea3575b50505015610e9257610e38908260005260036020526040600020846000526020526040600020600160ff1982541617905551600254611006565b60025580600052600460205260006002610e558460408420610f96565b5082815560048101805460ff1916905501557f579a48202337e96d4c3ec2de2b6a10a8eca56d61b9e21a7e6b29a9f04d82e7a7600080a360018055005b636ef6fcc160e01b60005260046000fd5b9192509082610ed7575b82610ecd575b5081610ec3575b50848080610dfe565b9050151584610eba565b4211915085610eb3565b8015159250610ead565b3461015b57600036600319011261015b576370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa801561042657600090610f4d575b602090604051908152f35b506020813d602011610f78575b81610f6760209383610fe4565b8101031261015b5760209051610f42565b3d9150610f5a565b600435906001600160a01b038216820361015b57565b8054821015610fb2576000526005602060002091020190600090565b634e487b7160e01b600052603260045260246000fd5b60a0810190811067ffffffffffffffff8211176103b957604052565b90601f8019910116810190811067ffffffffffffffff8211176103b957604052565b9190820391821161038d57565b9190820180921161038d57565b600260015414611031576002600155565b633ee5aeb560e01b60005260046000fd5b6000546001600160a01b0316330361105657565b63118cdaa760e01b6000523360045260246000fd5b60ff60005460a01c1661107a57565b63d93c066560e01b60005260046000fd5b60405163a9059cbb60e01b60208201526001600160a01b0390921660248301526044808301939093529181526110c691610517606483610fe4565b565b906000602091828151910182855af115610426576000513d61111a57506001600160a01b0381163b155b6110f95750565b635274afe760e01b60009081526001600160a01b0391909116600452602490fd5b600114156110f256fea264697066735822122073675234f41a97f877b38502bc4e43e4ff28f150832268f3b04ff2ec28ad4c4e64736f6c634300081c00330000000000000000000000009d549c39e5e1a0e7ef41d4b7d74c49f976102e3600000000000000000000000055d02fafd4fb34662940d28f548d2859b898f5ab
Deployed Bytecode
0x6080806040526004361015610038575b503615610027576353a4b68560e11b60005260046000fd5b6353a4b68560e11b60005260046000fd5b60003560e01c90816312065fe014610ee1575080631bf45ba814610d48578063240894aa14610d0e5780632e55b2a414610c4b5780633eddd6d714610ad05780633f4ba83a14610a5f5780635c975abb14610a395780635cfa946a14610a1b5780636dfa00a8146109ce578063715018a61461097557806377772ebe146107875780638456cb5914610725578063854e9682146106a05780638980f11f1461065a5780638da5cb5b14610631578063b6b55f2514610454578063cf86cf69146101e9578063f2fde38b146101605763fc0c546a14610116573861000f565b3461015b57600036600319011261015b576040517f0000000000000000000000009d549c39e5e1a0e7ef41d4b7d74c49f976102e366001600160a01b03168152602090f35b600080fd5b3461015b57602036600319011261015b57610179610f80565b610181611042565b6001600160a01b031680156101d357600080546001600160a01b03198116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b631e4fbdf760e01b600052600060045260246000fd5b3461015b57604036600319011261015b57610202610f80565b6024359061020e611042565b6001600160a01b0316908115610443578015610432576040516370a0823160e01b81523060048201526020816024817f0000000000000000000000009d549c39e5e1a0e7ef41d4b7d74c49f976102e366001600160a01b03165afa908115610426576000916103f1575b506002546102868382611013565b82106103e05761029591611006565b81116103cf576040516102a781610fc8565b8181526020810190428252604081019160008352606082016000815260808301936000855286600052600460205260406000208054680100000000000000008110156103b9576102fc91600182018155610f96565b9390936103a357600494518455516001840155516002830155516003820155019051151560ff8019835416911617905561033881600254611013565b60025581600052600460205260406000205490600019820191821161038d576020927fb871057cd3f316a478a827f65b30581628abf740760eb31d9c6df28c98ffc438848493604051908152a3604051908152f35b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600060045260246000fd5b634e487b7160e01b600052604160045260246000fd5b637f7afb7960e01b60005260046000fd5b6338985e0960e21b60005260046000fd5b906020823d60201161041e575b8161040b60209383610fe4565b8101031261041b57505183610278565b80fd5b3d91506103fe565b6040513d6000823e3d90fd5b633245e1f960e21b60005260046000fd5b63a7f9319d60e01b60005260046000fd5b3461015b57602036600319011261015b57600435610470611042565b610478611020565b8015610432576040516370a0823160e01b81523060048201527f0000000000000000000000009d549c39e5e1a0e7ef41d4b7d74c49f976102e366001600160a01b03811690602083602481855afa928315610426576000936105fd575b50821984116105ec5760249161051c602092604051906323b872dd60e01b85830152338683015230604483015287606483015260648252610517608483610fe4565b6110c8565b6040516370a0823160e01b815230600482015292839182905afa9182156104265783916000936105b3575b506105529083611006565b036105a25760025411610591576040519081527f59062170a285eb80e8c6b8ced60428442a51910635005233fc4ce084a475845e60203392a260018055005b638c53e5cb60e01b60005260046000fd5b63e40eec7160e01b60005260046000fd5b9150916020823d6020116105e4575b816105cf60209383610fe4565b8101031261041b575051908290610552610547565b3d91506105c2565b636c31405b60e01b60005260046000fd5b90926020823d602011610629575b8161061860209383610fe4565b8101031261041b57505191846104d5565b3d915061060b565b3461015b57600036600319011261015b576000546040516001600160a01b039091168152602090f35b3461015b57604036600319011261015b5761069a610676610f80565b61067e611042565b610686611020565b6024359033906001600160a01b031661108b565b60018055005b3461015b57604036600319011261015b576106b9610f80565b6001600160a01b031660009081526004602052604090208054602435919082101561015b5760a0916106ea91610f96565b50805490600181015490600281015460ff60046003840154930154169260405194855260208501526040840152606083015215156080820152f35b3461015b57600036600319011261015b5761073e611042565b61074661106b565b6000805460ff60a01b1916600160a01b1790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602090a1005b3461015b57602036600319011261015b576004356107a3611020565b6107ab61106b565b3360005260046020526040600020548110156109645733600052600360205260406000208160005260205260ff60406000205416610953573360005260046020526107fa816040600020610f96565b509060ff600483015416156109425760028201548015159081610938575b50610927578154908115610916576040516370a0823160e01b81523060048201527f0000000000000000000000009d549c39e5e1a0e7ef41d4b7d74c49f976102e36906020816024816001600160a01b0386165afa80156104265784916000916108e1575b50106103e057826108aa916000602096426003820155556108a082600254611006565b600255339061108b565b6040518281527f8614f23128d0a8e985869427ff11ceaddbf20d7bba7b150fc59aa091496283e9843392a360018055604051908152f35b9150506020813d60201161090e575b816108fd60209383610fe4565b8101031261015b578390518661087d565b3d91506108f0565b6313b1306560e11b60005260046000fd5b636ea469c160e11b60005260046000fd5b9050421183610818565b6339c5476d60e11b60005260046000fd5b630a7f9f9360e11b60005260046000fd5b630ec4187760e41b60005260046000fd5b3461015b57600036600319011261015b5761098e611042565b600080546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461015b57604036600319011261015b576001600160a01b036109ef610f80565b1660005260036020526040600020602435600052602052602060ff604060002054166040519015158152f35b3461015b57600036600319011261015b576020600254604051908152f35b3461015b57600036600319011261015b57602060ff60005460a01c166040519015158152f35b3461015b57600036600319011261015b57610a78611042565b60005460ff8160a01c1615610abf5760ff60a01b19166000556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602090a1005b638dfc202b60e01b60005260046000fd5b3461015b57606036600319011261015b57610ae9610f80565b6024359060443590610af9611042565b6001600160a01b0316908115610443578160005260046020526040600020548310156109645780151580610c41575b610c3057816000526004602052610b43836040600020610f96565b50600481019182549260ff8416610c1f576040516370a0823160e01b81523060048201526020816024817f0000000000000000000000009d549c39e5e1a0e7ef41d4b7d74c49f976102e366001600160a01b03165afa90811561042657600091610bed575b508354116103e0576002602093839260017f064bfba6a7df806040dba4fda0e456633569d804251c82c861cbfac64411b6ea9760ff19161790550155604051908152a3005b90506020813d602011610c17575b81610c0860209383610fe4565b8101031261015b575187610ba8565b3d9150610bfb565b632488da9560e11b60005260046000fd5b63048c286960e01b60005260046000fd5b5042811115610b28565b3461015b57600036600319011261015b576040516370a0823160e01b81523060048201526020816024817f0000000000000000000000009d549c39e5e1a0e7ef41d4b7d74c49f976102e366001600160a01b03165afa90811561042657600091610cdc575b506002549081811115610cd157602091610cc991611006565b604051908152f35b505060206000610cc9565b906020823d602011610d06575b81610cf660209383610fe4565b8101031261041b57505181610cb0565b3d9150610ce9565b3461015b57602036600319011261015b576001600160a01b03610d2f610f80565b1660005260046020526020604060002054604051908152f35b3461015b57604036600319011261015b57610d61610f80565b60243590610d6d611020565b610d75611042565b6001600160a01b031680156104435780600052600460205260406000205482101561096457806000526004602052610db1826040600020610f96565b5060405190610dbf82610fc8565b80548083526001820154602084015260ff6004600284015493846040870152600381015460608701520154161590811592839283608087015293610ea3575b50505015610e9257610e38908260005260036020526040600020846000526020526040600020600160ff1982541617905551600254611006565b60025580600052600460205260006002610e558460408420610f96565b5082815560048101805460ff1916905501557f579a48202337e96d4c3ec2de2b6a10a8eca56d61b9e21a7e6b29a9f04d82e7a7600080a360018055005b636ef6fcc160e01b60005260046000fd5b9192509082610ed7575b82610ecd575b5081610ec3575b50848080610dfe565b9050151584610eba565b4211915085610eb3565b8015159250610ead565b3461015b57600036600319011261015b576370a0823160e01b81523060048201526020816024817f0000000000000000000000009d549c39e5e1a0e7ef41d4b7d74c49f976102e366001600160a01b03165afa801561042657600090610f4d575b602090604051908152f35b506020813d602011610f78575b81610f6760209383610fe4565b8101031261015b5760209051610f42565b3d9150610f5a565b600435906001600160a01b038216820361015b57565b8054821015610fb2576000526005602060002091020190600090565b634e487b7160e01b600052603260045260246000fd5b60a0810190811067ffffffffffffffff8211176103b957604052565b90601f8019910116810190811067ffffffffffffffff8211176103b957604052565b9190820391821161038d57565b9190820180921161038d57565b600260015414611031576002600155565b633ee5aeb560e01b60005260046000fd5b6000546001600160a01b0316330361105657565b63118cdaa760e01b6000523360045260246000fd5b60ff60005460a01c1661107a57565b63d93c066560e01b60005260046000fd5b60405163a9059cbb60e01b60208201526001600160a01b0390921660248301526044808301939093529181526110c691610517606483610fe4565b565b906000602091828151910182855af115610426576000513d61111a57506001600160a01b0381163b155b6110f95750565b635274afe760e01b60009081526001600160a01b0391909116600452602490fd5b600114156110f256fea264697066735822122073675234f41a97f877b38502bc4e43e4ff28f150832268f3b04ff2ec28ad4c4e64736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000009d549c39e5e1a0e7ef41d4b7d74c49f976102e3600000000000000000000000055d02fafd4fb34662940d28f548d2859b898f5ab
-----Decoded View---------------
Arg [0] : _token (address): 0x9d549C39E5E1A0e7eF41D4b7d74c49f976102E36
Arg [1] : _admin (address): 0x55d02fAfD4fb34662940d28f548D2859B898f5AB
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000009d549c39e5e1a0e7ef41d4b7d74c49f976102e36
Arg [1] : 00000000000000000000000055d02fafd4fb34662940d28f548d2859b898f5ab
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in S
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.