Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 202 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Claim Multiple L... | 24247475 | 69 days ago | IN | 0 ETH | 0.00002455 | ||||
| Claim Multiple L... | 23698133 | 145 days ago | IN | 0 ETH | 0.00053081 | ||||
| Claim Multiple L... | 23671509 | 149 days ago | IN | 0 ETH | 0.00011581 | ||||
| Claim Loot | 23341054 | 195 days ago | IN | 0 ETH | 0.00012229 | ||||
| Claim Multiple L... | 23316961 | 199 days ago | IN | 0 ETH | 0.00006635 | ||||
| Claim Loot | 23258191 | 207 days ago | IN | 0 ETH | 0.00002898 | ||||
| Claim Multiple L... | 23188430 | 217 days ago | IN | 0 ETH | 0.00137321 | ||||
| Claim Multiple L... | 23157074 | 221 days ago | IN | 0 ETH | 0.00003974 | ||||
| Claim Multiple L... | 23144860 | 223 days ago | IN | 0 ETH | 0.00015736 | ||||
| Claim Loot | 23084136 | 231 days ago | IN | 0 ETH | 0.000085 | ||||
| Claim Loot | 23062210 | 234 days ago | IN | 0 ETH | 0.00003511 | ||||
| Claim Loot | 23062206 | 234 days ago | IN | 0 ETH | 0.00004203 | ||||
| Claim Multiple L... | 23054335 | 235 days ago | IN | 0 ETH | 0.00007769 | ||||
| Claim Multiple L... | 23037747 | 238 days ago | IN | 0 ETH | 0.00035589 | ||||
| Claim Multiple L... | 23025164 | 240 days ago | IN | 0 ETH | 0.00615591 | ||||
| Claim Loot | 22990301 | 244 days ago | IN | 0 ETH | 0.00021954 | ||||
| Claim Multiple L... | 22989565 | 244 days ago | IN | 0 ETH | 0.00393583 | ||||
| Claim Loot | 22942353 | 251 days ago | IN | 0 ETH | 0.00055686 | ||||
| Claim Loot | 22938889 | 252 days ago | IN | 0 ETH | 0.00047783 | ||||
| Claim Loot | 22921019 | 254 days ago | IN | 0 ETH | 0.00033366 | ||||
| Claim Multiple L... | 22888290 | 259 days ago | IN | 0 ETH | 0.00015255 | ||||
| Claim Loot | 22887627 | 259 days ago | IN | 0 ETH | 0.0001838 | ||||
| Claim Loot | 22861920 | 262 days ago | IN | 0 ETH | 0.00032868 | ||||
| Claim Multiple L... | 22849105 | 264 days ago | IN | 0 ETH | 0.00004637 | ||||
| Claim Loot | 22846297 | 265 days ago | IN | 0 ETH | 0.00032811 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Loot
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 999999 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
//██████╗ █████╗ ██╗ █████╗ ██████╗ ██╗███╗ ██╗
//██╔══██╗██╔══██╗██║ ██╔══██╗██╔══██╗██║████╗ ██║
//██████╔╝███████║██║ ███████║██║ ██║██║██╔██╗ ██║
//██╔═══╝ ██╔══██║██║ ██╔══██║██║ ██║██║██║╚██╗██║
//██║ ██║ ██║███████╗██║ ██║██████╔╝██║██║ ╚████║
//╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═════╝ ╚═╝╚═╝ ╚═══╝
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.20;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {ILootCreator} from "./interfaces/ILootCreator.sol";
import "./libraries/Errors.sol";
import "./utils/Owner.sol";
/** @title Loot contract */
/// @author Paladin
/*
Contract handling the Loot data, vesting & distribution
*/
contract Loot is Owner, ReentrancyGuard {
using SafeERC20 for IERC20;
// Structs
/** @notice Loot Data strcut */
struct LootData {
// ID of the Loot for the user
uint256 id;
// Amount of PAL to be distributed through vesting
uint256 palAmount;
// Amount of extra token to be distributed
uint256 extraAmount;
// Timestamp at which the vesting starts
uint256 startTs;
// Timestamp at which the vesting starts
uint256 endTs;
// Flag to check if the Loot has been claimed
bool claimed;
}
// Storage
/** @notice PAL token */
IERC20 public immutable pal;
/** @notice Extra reward token */
IERC20 public immutable extraToken;
/** @notice Address of the Reserve contract holding token to be distributed */
address public immutable tokenReserve;
/** @notice Loot Creator contract */
ILootCreator public lootCreator;
/** @notice Duration of vesting for Loots */
uint256 public vestingDuration;
/** @notice List of Loot for each user */
mapping(address => LootData[]) public userLoots;
// Events
/** @notice Event emitted when a Loot is created */
event LootCreated(address indexed user, uint256 indexed id, uint256 palAmount, uint256 extraAmount, uint256 startTs);
/** @notice Event emitted when a Loot is claimed */
event LootClaimed(address indexed user, uint256 indexed id, uint256 palAmount, uint256 extraAmount);
/** @notice Event emitted when the vesting duration is updated */
event VestingDurationUpdated(uint256 oldDuration, uint256 newDuration);
/** @notice Event emitted when the Loot Creator address is updated */
event LootCreatorUpdated(address oldCreator, address newCreator);
// Modifiers
/** @notice Checks the caller is the allowed Loot Creator */
modifier onlyLootCreator() {
if(msg.sender != address(lootCreator)) revert Errors.CallerNotAllowed();
_;
}
// Constructor
constructor(
address _pal,
address _extraToken,
address _tokenReserve,
uint256 _vestingDuration
){
if(
_pal == address(0)
|| _extraToken == address(0)
|| _tokenReserve == address(0)
) revert Errors.AddressZero();
pal = IERC20(_pal);
extraToken = IERC20(_extraToken);
tokenReserve = _tokenReserve;
vestingDuration = _vestingDuration;
}
/**
* @notice Sets the Loot Creator contract address
* @dev Sets the inital Loot Creator contract address
* @param _lootCreator Address of the Loot Creator contract
*/
function setInitialLootCreator(address _lootCreator) external onlyOwner {
if(address(lootCreator) != address(0)) revert Errors.CreatorAlreadySet();
lootCreator = ILootCreator(_lootCreator);
}
// View functions
/**
* @notice Returns the data of a Loot for a user & an id
* @dev Returns the data of a Loot for a user & an id
* @param user Address of the user
* @param id ID of the Loot
* @return palAmount (uint256) : Amount of PAL
* @return extraAmount (uint256) : Amount of extra token
* @return startTs (uint256) : Timestamp at which the vesting starts
* @return endTs (uint256) : Timestamp at which the vesting ends
* @return claimed (uint256) : Is Loot already claimed
*/
function getLootData(address user, uint256 id) external view returns(
uint256 palAmount,
uint256 extraAmount,
uint256 startTs,
uint256 endTs,
bool claimed
){
LootData memory loot = userLoots[user][id];
palAmount = loot.palAmount;
extraAmount = loot.extraAmount;
startTs = loot.startTs;
endTs = loot.endTs;
claimed = loot.claimed;
}
/**
* @notice Returns all the user Loot IDs
* @dev Returns all the user Loot IDs
* @param user Address of the user
* @return uint256[] : List of Loot IDs
*/
function getAllUserLootIds(address user) external view returns(uint256[] memory){
uint256 length = userLoots[user].length;
uint256[] memory ids = new uint256[](length);
for(uint256 i; i < length;){
ids[i] = userLoots[user][i].id;
unchecked { i++; }
}
return ids;
}
/**
* @notice Returns all the user active Loot IDs
* @dev Returns all the user active Loot IDs
* @param user Address of the user
* @return uint256[] : List of active Loot IDs
*/
function getAllActiveUserLootIds(address user) external view returns(uint256[] memory){
LootData[] memory _loots = userLoots[user];
uint256 length = _loots.length;
uint256 activeCount;
for(uint256 i; i < length;){
if(!_loots[i].claimed) activeCount++;
unchecked { i++; }
}
// Reduce the array to the actual active Loot size
uint256[] memory ids = new uint256[](activeCount);
uint256 j;
for(uint256 i; i < length;){
if(!_loots[i].claimed) {
ids[j] = _loots[i].id;
unchecked { j++; }
}
unchecked { i++; }
}
return ids;
}
/**
* @notice Returns all the user Loots
* @dev Returns all the user Loots
* @param user Address of the user
* @return LootData[] : List of Loots
*/
function getAllUserLoot(address user) external view returns(LootData[] memory){
return userLoots[user];
}
/**
* @notice Returns all the user active Loots
* @dev Returns all the user active Loots
* @param user Address of the user
* @return LootData[] : List of active Loots
*/
function getAllActiveUserLoot(address user) external view returns(LootData[] memory){
LootData[] memory _loots = userLoots[user];
uint256 length = _loots.length;
uint256 activeCount;
for(uint256 i; i < length;){
if(!_loots[i].claimed) activeCount++;
unchecked { i++; }
}
// Reduce the array to the actual active Loot size
LootData[] memory loots = new LootData[](activeCount);
uint256 j;
for(uint256 i; i < length;){
if(!_loots[i].claimed) {
loots[j] = _loots[i];
unchecked { j++; }
}
unchecked { i++; }
}
return loots;
}
// State-changing functions
/**
* @notice Creates a new Loot for a user
* @dev Creates a new Loot for a user
* @param user Address of the user
* @param startTs Timestamp at which the vesting starts
* @param palAmount Amount of PAL
* @param extraAmount Amount of extra token
*/
function createLoot(address user, uint256 startTs, uint256 palAmount, uint256 extraAmount) external onlyLootCreator returns(int256) {
if(palAmount == 0 && extraAmount == 0) return -1;
uint256 lootId = userLoots[user].length;
// Write the Loot parameters based on inputs
userLoots[user].push(LootData({
id: lootId,
palAmount: palAmount,
extraAmount: extraAmount,
startTs: startTs,
endTs: startTs + vestingDuration,
claimed: false
}));
emit LootCreated(user, lootId, palAmount, extraAmount, startTs);
return int256(lootId);
}
/**
* @notice Claims a Loot for a user
* @dev Claims a Loot for a user & slashes the PAL amount if the vesting isn't over
* @param id ID of the Loot
* @param receiver Address to receive the PAL & extra token
*/
function claimLoot(uint256 id, address receiver) external nonReentrant {
if(id >= userLoots[msg.sender].length) revert Errors.InvalidId(id);
if(receiver == address(0)) revert Errors.AddressZero();
// Load the Loot state
LootData storage loot = userLoots[msg.sender][id];
if(loot.claimed) revert Errors.AlreadyClaimed();
if(block.timestamp < loot.startTs) revert Errors.VestingNotStarted(id);
loot.claimed = true;
uint256 palAmount = loot.palAmount;
if(palAmount > 0) {
// Check if the Loot is still vesting, and slash the PAL amount if needed
if(block.timestamp < loot.endTs){
uint256 remainingVesting = loot.endTs - block.timestamp;
uint256 slashingAmount = palAmount * remainingVesting / vestingDuration;
// Notify the LootCreator of the slashed amount
lootCreator.notifyUndistributedRewards(slashingAmount);
palAmount -= slashingAmount;
}
// Transfer the PAL to the receiver
pal.safeTransferFrom(tokenReserve, receiver, palAmount);
}
uint256 extraAmount = loot.extraAmount;
if(extraAmount > 0) {
// Transfer the extra token to the receiver
extraToken.safeTransferFrom(tokenReserve, receiver, extraAmount);
}
emit LootClaimed(msg.sender, id, palAmount, extraAmount);
}
/**
* @notice Claims multiple Loots for a user
* @dev Claims multiple Loots for a user & slashes the PAL amounts if the vesting isn't over
* @param ids List of Loot IDs
* @param receiver Address to receive the PAL & extra token
*/
function claimMultipleLoot(uint256[] calldata ids, address receiver) external nonReentrant {
if(receiver == address(0)) revert Errors.AddressZero();
uint256 length = ids.length;
uint256 totalPalAmount;
uint256 totalExtraAmount;
for(uint256 i; i < length;){
if(ids[i] >= userLoots[msg.sender].length) revert Errors.InvalidId(ids[i]);
// Load the Loot state
LootData storage loot = userLoots[msg.sender][ids[i]];
if(loot.claimed) revert Errors.AlreadyClaimed();
if(block.timestamp < loot.startTs) revert Errors.VestingNotStarted(ids[i]);
loot.claimed = true;
// Check if the Loot is still vesting, and slash the PAL amount if needed
uint256 palAmount = loot.palAmount;
uint256 extraAmount = loot.extraAmount;
if(palAmount > 0) {
if(block.timestamp < loot.endTs){
uint256 remainingVesting = loot.endTs - block.timestamp;
uint256 slashingAmount = palAmount * remainingVesting / vestingDuration;
// Notify the LootCreator of the slashed amount
lootCreator.notifyUndistributedRewards(slashingAmount);
palAmount -= slashingAmount;
}
}
// Sum up all the PAL & extra token to be transferred
totalPalAmount += palAmount;
totalExtraAmount += extraAmount;
emit LootClaimed(msg.sender, ids[i], palAmount, extraAmount);
unchecked { i++; }
}
// Transfer the PAL & extra token to the receiver
if(totalPalAmount > 0) {
pal.safeTransferFrom(tokenReserve, receiver, totalPalAmount);
}
if(totalExtraAmount > 0) {
extraToken.safeTransferFrom(tokenReserve, receiver, totalExtraAmount);
}
}
// Admin functions
/**
* @notice Updates the vesting duration for Loots
* @dev Updates the vesting duration for Loots
* @param _vestingDuration New vesting duration
*/
function updateVestingDuration(uint256 _vestingDuration) external onlyOwner {
if(_vestingDuration < 1 weeks) revert Errors.InvalidParameter();
uint256 oldDuration = vestingDuration;
vestingDuration = _vestingDuration;
emit VestingDurationUpdated(oldDuration, _vestingDuration);
}
/**
* @notice Updates the Loot Creator contract address
* @dev Updates the Loot Creator contract address
* @param _lootCreator Address of the new Loot Creator contract
*/
function updateLootCreator(address _lootCreator) external onlyOwner {
if(_lootCreator == address(0)) revert Errors.InvalidParameter();
address oldCreator = address(lootCreator);
if(_lootCreator == oldCreator) revert Errors.SameAddress();
lootCreator = ILootCreator(_lootCreator);
emit LootCreatorUpdated(oldCreator, _lootCreator);
}
}// 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.0.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 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 {
using Address for address;
/**
* @dev An operation with an ERC20 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.
*/
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.
*/
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.
*/
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 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).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
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 silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {FailedInnerCall} error.
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
* unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {FailedInnerCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
*/
function _revert(bytes memory returndata) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}// 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.0.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 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: Unlicensed
pragma solidity 0.8.20;
interface ILootCreator {
struct MultiCreate {
// Address of the Distributor handling the Quest rewards
address distributor;
// ID of the Quest
uint256 questId;
// Timestamp of the period
uint256 period;
}
function getBudgetForPeriod(uint256 period) external view returns(uint256 palAmount, uint256 extraAmount);
function getGaugeBudgetForPeriod(
address gauge,
uint256 period
) external view returns(uint256 palAmount, uint256 extraAmount);
function getQuestAllocationForPeriod(
uint256 questId,
address distributor,
uint256 period
) external view returns(uint256 palPerVote, uint256 extraPerVote);
function getListedDistributors() external view returns(address[] memory);
function createLoot(address user, address distributor, uint256 questId, uint256 period) external;
function createMultipleLoot(address user, MultiCreate[] calldata params) external;
function notifyQuestClaim(address user, uint256 questId, uint256 period, uint256 claimedAmount) external;
function notifyDistributedQuestPeriod(uint256 questId, uint256 period, uint256 totalRewards) external;
function notifyAddedRewardsQuestPeriod(uint256 questId, uint256 period, uint256 addedRewards) external;
function notifyUndistributedRewards(uint256 palAmount) external;
function notifyNewBudget(uint256 palAmount, uint256 extraAmount) external;
function updatePeriod() external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
library Errors {
// Commons
error AddressZero();
error NullAmount();
error InvalidParameter();
error SameAddress();
error ArraySizeMismatch();
error AlreadyInitialized();
// Access Control
error CannotBeOwner();
error CallerNotPendingOwner();
error CallerNotAllowed();
// Merkle Distributor
error EmptyParameters();
error InvalidProof();
error AlreadyClaimed();
error MerkleRootNotUpdated();
error EmptyMerkleRoot();
error IncorrectQuestID();
error QuestAlreadyListed();
error QuestNotListed();
error PeriodAlreadyUpdated();
error PeriodNotClosed();
error IncorrectPeriod();
error PeriodNotListed();
error TokenNotWhitelisted();
error IncorrectRewardAmount();
error CannotRecoverToken();
// HolyPalPower
error InvalidTimestamp();
// Vote Controller
error AlreadyListed();
error LockExpired();
error VotingPowerInvalid();
error VotingPowerExceeded();
error VotingPowerProxyExceeded();
error VotingCooldown();
error KilledGauge();
error NotKilledGauge();
error NotAllowedManager();
error NotAllowedProxyVoter();
error ExpiredProxy();
error ProxyAlreadyActive();
error ProxyPowerExceeded();
error ProxyDurationExceeded();
error NotAllowedVoteChange();
error MaxVoteListExceeded();
error MaxProxyListExceeded();
error InvalidGaugeCap();
// Loot
error CreatorAlreadySet();
error InvalidId(uint256 id);
error VestingNotStarted(uint256 id);
// Loot Creator
error NotListed();
// Loot Buget
error LootBudgetExceedLimit();
//Maths
error ConversionOverflow();
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import "../libraries/Errors.sol";
/** @title 2-step Ownership */
/// @author Paladin
/*
Extends OZ Ownable contract to add 2-step ownership transfer
*/
contract Owner is Ownable {
address public pendingOwner;
event NewPendingOwner(address indexed previousPendingOwner, address indexed newPendingOwner);
constructor() Ownable(msg.sender) {}
function transferOwnership(address newOwner) public override virtual onlyOwner {
if(newOwner == address(0)) revert Errors.AddressZero();
if(newOwner == owner()) revert Errors.CannotBeOwner();
address oldPendingOwner = pendingOwner;
pendingOwner = newOwner;
emit NewPendingOwner(oldPendingOwner, newOwner);
}
function acceptOwnership() public virtual {
if(msg.sender != pendingOwner) revert Errors.CallerNotPendingOwner();
address newOwner = pendingOwner;
_transferOwnership(pendingOwner);
pendingOwner = address(0);
emit NewPendingOwner(newOwner, address(0));
}
}{
"optimizer": {
"enabled": true,
"runs": 999999
},
"viaIR": true,
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_pal","type":"address"},{"internalType":"address","name":"_extraToken","type":"address"},{"internalType":"address","name":"_tokenReserve","type":"address"},{"internalType":"uint256","name":"_vestingDuration","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"AddressZero","type":"error"},{"inputs":[],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"CallerNotAllowed","type":"error"},{"inputs":[],"name":"CallerNotPendingOwner","type":"error"},{"inputs":[],"name":"CannotBeOwner","type":"error"},{"inputs":[],"name":"CreatorAlreadySet","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"InvalidId","type":"error"},{"inputs":[],"name":"InvalidParameter","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"},{"inputs":[],"name":"SameAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"VestingNotStarted","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"palAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"extraAmount","type":"uint256"}],"name":"LootClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"palAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"extraAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTs","type":"uint256"}],"name":"LootCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldCreator","type":"address"},{"indexed":false,"internalType":"address","name":"newCreator","type":"address"}],"name":"LootCreatorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousPendingOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newPendingOwner","type":"address"}],"name":"NewPendingOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"VestingDurationUpdated","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"claimLoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"receiver","type":"address"}],"name":"claimMultipleLoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"startTs","type":"uint256"},{"internalType":"uint256","name":"palAmount","type":"uint256"},{"internalType":"uint256","name":"extraAmount","type":"uint256"}],"name":"createLoot","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"extraToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getAllActiveUserLoot","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"palAmount","type":"uint256"},{"internalType":"uint256","name":"extraAmount","type":"uint256"},{"internalType":"uint256","name":"startTs","type":"uint256"},{"internalType":"uint256","name":"endTs","type":"uint256"},{"internalType":"bool","name":"claimed","type":"bool"}],"internalType":"struct Loot.LootData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getAllActiveUserLootIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getAllUserLoot","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"palAmount","type":"uint256"},{"internalType":"uint256","name":"extraAmount","type":"uint256"},{"internalType":"uint256","name":"startTs","type":"uint256"},{"internalType":"uint256","name":"endTs","type":"uint256"},{"internalType":"bool","name":"claimed","type":"bool"}],"internalType":"struct Loot.LootData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getAllUserLootIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getLootData","outputs":[{"internalType":"uint256","name":"palAmount","type":"uint256"},{"internalType":"uint256","name":"extraAmount","type":"uint256"},{"internalType":"uint256","name":"startTs","type":"uint256"},{"internalType":"uint256","name":"endTs","type":"uint256"},{"internalType":"bool","name":"claimed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lootCreator","outputs":[{"internalType":"contract ILootCreator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pal","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lootCreator","type":"address"}],"name":"setInitialLootCreator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenReserve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lootCreator","type":"address"}],"name":"updateLootCreator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vestingDuration","type":"uint256"}],"name":"updateVestingDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userLoots","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"palAmount","type":"uint256"},{"internalType":"uint256","name":"extraAmount","type":"uint256"},{"internalType":"uint256","name":"startTs","type":"uint256"},{"internalType":"uint256","name":"endTs","type":"uint256"},{"internalType":"bool","name":"claimed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vestingDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60e0346200019357601f62001fdf38819003918201601f19168301916001600160401b03831184841017620001985780849260809460405283398101031262000193576200004d81620001ae565b906200005c60208201620001ae565b9160606200006d60408401620001ae565b9201519233156200017a5760008054336001600160a01b03198216811783556040516001600160a01b0395909386939192918416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a360016002551690811580156200016f575b801562000164575b6200015557506080521660a05260c052600455604051611e1b9081620001c4823960805181818161075c01528181610bdc0152610dc8015260a05181818161070901528181610b740152610d59015260c051818181610366015281816106e80152818161073b01528181610b530152610bbb0152f35b639fabe1c160e01b8152600490fd5b5083851615620000df565b5083831615620000d7565b604051631e4fbdf760e01b815260006004820152602490fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203620001935756fe6080604052600436101561001257600080fd5b6000803560e01c8062c0b12c146114ad5780631514617e14611471578063303a6cbf146113bb5780633f62900614611313578063489091d71461126a57806354ec46de146112185780635f69a56014611128578063715018a61461108c57806379ba509714610f915780638da5cb5b14610f405780638e246d1614610ea05780638e3524ff14610dec5780639bd2a16e14610d7d578063a1a4ddeb14610d0e578063ae4a8c8814610a2b578063b26e919414610620578063b2d747f714610567578063cb91c0521461038a578063cbcb31711461031b578063dd19aa5714610272578063e30c3978146102205763f2fde38b1461010e57600080fd5b3461021d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d576101456115f7565b61014d61173d565b73ffffffffffffffffffffffffffffffffffffffff8091169081156101f3578083541682146101c957600154827fffffffffffffffffffffffff0000000000000000000000000000000000000000821617600155167fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b8380a380f35b60046040517fd5e889bf000000000000000000000000000000000000000000000000000000008152fd5b60046040517f9fabe1c1000000000000000000000000000000000000000000000000000000008152fd5b80fd5b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d57602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b503461021d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d576004356102ad61173d565b62093a8081106102f15760407f45bb6881f3c9c1cb1cc34819c0d4ec9ae48623f202097557a3b8ec79d9fcb96991600454908060045582519182526020820152a180f35b60046040517f613970e0000000000000000000000000000000000000000000000000000000008152fd5b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b503461021d57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d5773ffffffffffffffffffffffffffffffffffffffff6103d96115f7565b16815260058252604081209081546103f081611879565b926103fe60405194856117ed565b81845282528382208290858086015b848410610548575085858151918193825b84811061051757507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061046961045387611879565b9661046160405198896117ed565b808852611879565b01835b8181106104dd57505050815b838110610491576040518061048d878261167d565b0390f35b60a061049d82846118e0565b510151156104ae575b600101610478565b91600180916104bd85856118e0565b516104c882896118e0565b526104d381886118e0565b50019290506104a6565b82906040516104eb816117d1565b86815286838201528660408201528660608201528660808201528660a082015282828a0101520161046c565b60a061052382856118e0565b51015115610534575b60010161041e565b946105406001916118f4565b95905061052c565b6001916006916105578561182e565b815201920192019190869061040d565b503461021d5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d5761059f6115f7565b73ffffffffffffffffffffffffffffffffffffffff1681526005602052604081208054602435929083101561021d5760c06105da84846116f2565b50805490600181015490600281015460038201549060ff6005600485015494015416936040519586526020860152604085015260608401526080830152151560a0820152f35b503461021d5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d5760043567ffffffffffffffff808211610a275736602383011215610a275781600401351161097457366024826004013560051b830101116109745761069361161f565b9061069c611d9c565b73ffffffffffffffffffffffffffffffffffffffff8216156101f35782908390845b816004013581106107865750509080610734575b50806106e2575b82600160025580f35b61072d917f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000611b71565b38806106d9565b61078090837f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000611b71565b386106d2565b61079881836004013560248501611dd5565b353387526005602052604087205411156109e45733865260056020526107d4604087206107cd83856004013560248701611dd5565b35906116f2565b5060058101805460ff81166109ba5760038301544210610978577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00600191161790556001810154809560028301549282610891575b508261083c600195949361084293611950565b96611950565b9561085583866004013560248801611dd5565b359160405191825260208201527f10b5a9c888eac47334aeb062fb61e868d55c152689dd6e97aa9010cc0e1d94d160403392a3019291926106be565b600491925001548042106108a8575b908691610829565b6108c46108be6108cd9298959493984290611b18565b85611b25565b60045490611b38565b8873ffffffffffffffffffffffffffffffffffffffff60035416803b15610974578180916024604051809481937f6c3f25a20000000000000000000000000000000000000000000000000000000083528860048401525af1801561096957610951575b50508161083c61094561084293600197611b18565b989350509293506108a0565b61095a9061178e565b610965578838610930565b8880fd5b6040513d84823e3d90fd5b5080fd5b602461098b856004880135888401611dd5565b35604051907fddb9c56a0000000000000000000000000000000000000000000000000000000082526004820152fd5b60046040517f646cf558000000000000000000000000000000000000000000000000000000008152fd5b6109f8908260248094600401359101611dd5565b35604051907fe4a471820000000000000000000000000000000000000000000000000000000082526004820152fd5b8280fd5b503461021d5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d57600435610a6661161f565b610a6e611d9c565b33835260056020526040832054821015610cdd5773ffffffffffffffffffffffffffffffffffffffff90818116156101f3573384526005602052610ab583604086206116f2565b5060058101805460ff81166109ba5760038301544210610cac577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00600191161790556001810154928384610b9f575b505060020154908180610b4d575b505060405191825260208201527f10b5a9c888eac47334aeb062fb61e868d55c152689dd6e97aa9010cc0e1d94d160403392a3600160025580f35b610b98917f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000611b71565b3881610b12565b866004840154804210610c07575b50505050600290610c0084847f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000611b71565b9038610b04565b610c239192939496610c1d6108c4924290611b18565b90611b25565b9260035416803b156109745781906024604051809481937f6c3f25a20000000000000000000000000000000000000000000000000000000083528860048401525af18015610ca157610c87575b50600291610c7d91611b18565b9290388681610bad565b91610c7d9196610c9860029461178e565b96915091610c70565b6040513d89823e3d90fd5b602486604051907fddb9c56a0000000000000000000000000000000000000000000000000000000082526004820152fd5b602482604051907fe4a471820000000000000000000000000000000000000000000000000000000082526004820152fd5b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b503461021d576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126109745773ffffffffffffffffffffffffffffffffffffffff610e3a6115f7565b1682526005815260408220805490610e5182611879565b92610e5f60405194856117ed565b82845280840191855280852094915b838310610e83576040518061048d878261167d565b600682600192610e928961182e565b815201960192019194610e6e565b503461021d5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d57610ed86115f7565b73ffffffffffffffffffffffffffffffffffffffff600354163303610f1657610f0e60209160643590604435906024359061195d565b604051908152f35b60046040517f2af07d20000000000000000000000000000000000000000000000000000000008152fd5b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d5773ffffffffffffffffffffffffffffffffffffffff6020915416604051908152f35b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d5760015473ffffffffffffffffffffffffffffffffffffffff80821690813303611062578392828454927fffffffffffffffffffffffff00000000000000000000000000000000000000009382858216178755167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08680a3166001557fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b8280a380f35b60046040517f2f02da58000000000000000000000000000000000000000000000000000000008152fd5b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d576110c361173d565b8073ffffffffffffffffffffffffffffffffffffffff81547fffffffffffffffffffffffff000000000000000000000000000000000000000081168355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b503461021d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d576111606115f7565b61116861173d565b73ffffffffffffffffffffffffffffffffffffffff8091169081156102f1576003549081168083146111ee57827f8352ba19c21cdb525381f325922bf54276532b75cd30d187ea8d8733d6001898937fffffffffffffffffffffffff0000000000000000000000000000000000000000604094161760035582519182526020820152a180f35b60046040517f367558c3000000000000000000000000000000000000000000000000000000008152fd5b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d57602073ffffffffffffffffffffffffffffffffffffffff60035416604051908152f35b503461021d5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d576112da6112d460a09273ffffffffffffffffffffffffffffffffffffffff6112c06115f7565b1681526005602052604060243591206116f2565b5061182e565b60208101519060408101519060608101518460808301519201511515926040519485526020850152604084015260608301526080820152f35b503461021d576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126109745773ffffffffffffffffffffffffffffffffffffffff6113616115f7565b1691828152600580835260408220549261137a84611891565b94835b858110611392576040518061048d8982611642565b6001908286528484526113a881604088206116f2565b50546113b4828a6118e0565b520161137d565b503461021d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d576113f36115f7565b6113fb61173d565b6003549073ffffffffffffffffffffffffffffffffffffffff808316611447577fffffffffffffffffffffffff0000000000000000000000000000000000000000911691161760035580f35b60046040517f5176b12f000000000000000000000000000000000000000000000000000000008152fd5b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d576020600454604051908152f35b503461021d57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d5773ffffffffffffffffffffffffffffffffffffffff6114fc6115f7565b168152600582526040812080549061151382611879565b9361152160405195866117ed565b82855280850191845280842084925b8484106115da578686815181825b8281106115a9575061154f90611891565b91805b828110611567576040518061048d8682611642565b60a061157382876118e0565b51015115611584575b600101611552565b906001809161159384886118e0565b515161159f82886118e0565b520191905061157c565b60a06115b582876118e0565b510151156115c6575b60010161153e565b906115d26001916118f4565b9190506115be565b6006836001926115e98561182e565b815201920193019290611530565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361161a57565b600080fd5b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361161a57565b6020908160408183019282815285518094520193019160005b828110611669575050505090565b83518552938101939281019260010161165b565b60208082019080835283518092528060408094019401926000905b8382106116a757505050505090565b84518051875280840151878501528082015187830152606080820151908801526080808201519088015260a09081015115159087015260c09095019493820193600190910190611698565b805482101561170e576000526006602060002091020190600090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff60005416330361175e57565b60246040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152fd5b67ffffffffffffffff81116117a257604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60c0810190811067ffffffffffffffff8211176117a257604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176117a257604052565b9060405161183b816117d1565b60a060ff6005839580548552600181015460208601526002810154604086015260038101546060860152600481015460808601520154161515910152565b67ffffffffffffffff81116117a25760051b60200190565b9061189b82611879565b6118a860405191826117ed565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06118d68294611879565b0190602036910137565b805182101561170e5760209160051b010190565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146119215760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9190820180921161192157565b919091811580611b10575b611ae85773ffffffffffffffffffffffffffffffffffffffff16916000938385526005602052604085208054956119a160045485611950565b6040516119ad816117d1565b88815260208101878152604082019086825260608301928884526080810194855260a0810196868852680100000000000000008d1015611abb578c6119f7916001820181556116f2565b969096611a8f5750938b9a9996936005937fe22a6a2aa4e4fd33e4087815087f265c780696d4477361e0f0734e7752b246379a979360609a97518555516001850155516002840155516003830155516004820155019051151560ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00835416911617905560405192835260208301526040820152a390565b807f4e487b71000000000000000000000000000000000000000000000000000000006024925280600452fd5b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b505050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90565b508315611968565b9190820391821161192157565b8181029291811591840414171561192157565b8115611b42570490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b90916040519360208501937f23b872dd00000000000000000000000000000000000000000000000000000000855273ffffffffffffffffffffffffffffffffffffffff9283809216602488015216604486015260648501526064845260a084019167ffffffffffffffff92858110848211176117a2576040521692600080938192519082875af13d15611cef573d918211611cc25790611c519160405191611c4160207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601846117ed565b82523d84602084013e5b84611cfc565b908151918215159283611c9a575b505050611c695750565b602490604051907f5274afe70000000000000000000000000000000000000000000000000000000082526004820152fd5b81929350906020918101031261097457602001519081159182150361021d5750388080611c5f565b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b611c519150606090611c4b565b90611d3b5750805115611d1157805190602001fd5b60046040517f1425ea42000000000000000000000000000000000000000000000000000000008152fd5b81511580611d93575b611d4c575090565b60249073ffffffffffffffffffffffffffffffffffffffff604051917f9996b315000000000000000000000000000000000000000000000000000000008352166004820152fd5b50803b15611d44565b6002805414611dab5760028055565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b919081101561170e5760051b019056fea2646970667358221220864538173d1cb39d8182d0da9b3739530fca18ef01ee353aaab9d757997960dd64736f6c63430008140033000000000000000000000000ab846fb6c81370327e784ae7cbb6d6a6af6ff4bf000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000c4677c513aec114b65cee1c95d505c708cc77f6d000000000000000000000000000000000000000000000000000000000024ea00
Deployed Bytecode
0x6080604052600436101561001257600080fd5b6000803560e01c8062c0b12c146114ad5780631514617e14611471578063303a6cbf146113bb5780633f62900614611313578063489091d71461126a57806354ec46de146112185780635f69a56014611128578063715018a61461108c57806379ba509714610f915780638da5cb5b14610f405780638e246d1614610ea05780638e3524ff14610dec5780639bd2a16e14610d7d578063a1a4ddeb14610d0e578063ae4a8c8814610a2b578063b26e919414610620578063b2d747f714610567578063cb91c0521461038a578063cbcb31711461031b578063dd19aa5714610272578063e30c3978146102205763f2fde38b1461010e57600080fd5b3461021d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d576101456115f7565b61014d61173d565b73ffffffffffffffffffffffffffffffffffffffff8091169081156101f3578083541682146101c957600154827fffffffffffffffffffffffff0000000000000000000000000000000000000000821617600155167fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b8380a380f35b60046040517fd5e889bf000000000000000000000000000000000000000000000000000000008152fd5b60046040517f9fabe1c1000000000000000000000000000000000000000000000000000000008152fd5b80fd5b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d57602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b503461021d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d576004356102ad61173d565b62093a8081106102f15760407f45bb6881f3c9c1cb1cc34819c0d4ec9ae48623f202097557a3b8ec79d9fcb96991600454908060045582519182526020820152a180f35b60046040517f613970e0000000000000000000000000000000000000000000000000000000008152fd5b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d57602060405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c4677c513aec114b65cee1c95d505c708cc77f6d168152f35b503461021d57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d5773ffffffffffffffffffffffffffffffffffffffff6103d96115f7565b16815260058252604081209081546103f081611879565b926103fe60405194856117ed565b81845282528382208290858086015b848410610548575085858151918193825b84811061051757507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061046961045387611879565b9661046160405198896117ed565b808852611879565b01835b8181106104dd57505050815b838110610491576040518061048d878261167d565b0390f35b60a061049d82846118e0565b510151156104ae575b600101610478565b91600180916104bd85856118e0565b516104c882896118e0565b526104d381886118e0565b50019290506104a6565b82906040516104eb816117d1565b86815286838201528660408201528660608201528660808201528660a082015282828a0101520161046c565b60a061052382856118e0565b51015115610534575b60010161041e565b946105406001916118f4565b95905061052c565b6001916006916105578561182e565b815201920192019190869061040d565b503461021d5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d5761059f6115f7565b73ffffffffffffffffffffffffffffffffffffffff1681526005602052604081208054602435929083101561021d5760c06105da84846116f2565b50805490600181015490600281015460038201549060ff6005600485015494015416936040519586526020860152604085015260608401526080830152151560a0820152f35b503461021d5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d5760043567ffffffffffffffff808211610a275736602383011215610a275781600401351161097457366024826004013560051b830101116109745761069361161f565b9061069c611d9c565b73ffffffffffffffffffffffffffffffffffffffff8216156101f35782908390845b816004013581106107865750509080610734575b50806106e2575b82600160025580f35b61072d917f000000000000000000000000c4677c513aec114b65cee1c95d505c708cc77f6d7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2611b71565b38806106d9565b61078090837f000000000000000000000000c4677c513aec114b65cee1c95d505c708cc77f6d7f000000000000000000000000ab846fb6c81370327e784ae7cbb6d6a6af6ff4bf611b71565b386106d2565b61079881836004013560248501611dd5565b353387526005602052604087205411156109e45733865260056020526107d4604087206107cd83856004013560248701611dd5565b35906116f2565b5060058101805460ff81166109ba5760038301544210610978577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00600191161790556001810154809560028301549282610891575b508261083c600195949361084293611950565b96611950565b9561085583866004013560248801611dd5565b359160405191825260208201527f10b5a9c888eac47334aeb062fb61e868d55c152689dd6e97aa9010cc0e1d94d160403392a3019291926106be565b600491925001548042106108a8575b908691610829565b6108c46108be6108cd9298959493984290611b18565b85611b25565b60045490611b38565b8873ffffffffffffffffffffffffffffffffffffffff60035416803b15610974578180916024604051809481937f6c3f25a20000000000000000000000000000000000000000000000000000000083528860048401525af1801561096957610951575b50508161083c61094561084293600197611b18565b989350509293506108a0565b61095a9061178e565b610965578838610930565b8880fd5b6040513d84823e3d90fd5b5080fd5b602461098b856004880135888401611dd5565b35604051907fddb9c56a0000000000000000000000000000000000000000000000000000000082526004820152fd5b60046040517f646cf558000000000000000000000000000000000000000000000000000000008152fd5b6109f8908260248094600401359101611dd5565b35604051907fe4a471820000000000000000000000000000000000000000000000000000000082526004820152fd5b8280fd5b503461021d5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d57600435610a6661161f565b610a6e611d9c565b33835260056020526040832054821015610cdd5773ffffffffffffffffffffffffffffffffffffffff90818116156101f3573384526005602052610ab583604086206116f2565b5060058101805460ff81166109ba5760038301544210610cac577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00600191161790556001810154928384610b9f575b505060020154908180610b4d575b505060405191825260208201527f10b5a9c888eac47334aeb062fb61e868d55c152689dd6e97aa9010cc0e1d94d160403392a3600160025580f35b610b98917f000000000000000000000000c4677c513aec114b65cee1c95d505c708cc77f6d7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2611b71565b3881610b12565b866004840154804210610c07575b50505050600290610c0084847f000000000000000000000000c4677c513aec114b65cee1c95d505c708cc77f6d7f000000000000000000000000ab846fb6c81370327e784ae7cbb6d6a6af6ff4bf611b71565b9038610b04565b610c239192939496610c1d6108c4924290611b18565b90611b25565b9260035416803b156109745781906024604051809481937f6c3f25a20000000000000000000000000000000000000000000000000000000083528860048401525af18015610ca157610c87575b50600291610c7d91611b18565b9290388681610bad565b91610c7d9196610c9860029461178e565b96915091610c70565b6040513d89823e3d90fd5b602486604051907fddb9c56a0000000000000000000000000000000000000000000000000000000082526004820152fd5b602482604051907fe4a471820000000000000000000000000000000000000000000000000000000082526004820152fd5b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d57602060405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2168152f35b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d57602060405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ab846fb6c81370327e784ae7cbb6d6a6af6ff4bf168152f35b503461021d576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126109745773ffffffffffffffffffffffffffffffffffffffff610e3a6115f7565b1682526005815260408220805490610e5182611879565b92610e5f60405194856117ed565b82845280840191855280852094915b838310610e83576040518061048d878261167d565b600682600192610e928961182e565b815201960192019194610e6e565b503461021d5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d57610ed86115f7565b73ffffffffffffffffffffffffffffffffffffffff600354163303610f1657610f0e60209160643590604435906024359061195d565b604051908152f35b60046040517f2af07d20000000000000000000000000000000000000000000000000000000008152fd5b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d5773ffffffffffffffffffffffffffffffffffffffff6020915416604051908152f35b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d5760015473ffffffffffffffffffffffffffffffffffffffff80821690813303611062578392828454927fffffffffffffffffffffffff00000000000000000000000000000000000000009382858216178755167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08680a3166001557fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b8280a380f35b60046040517f2f02da58000000000000000000000000000000000000000000000000000000008152fd5b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d576110c361173d565b8073ffffffffffffffffffffffffffffffffffffffff81547fffffffffffffffffffffffff000000000000000000000000000000000000000081168355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b503461021d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d576111606115f7565b61116861173d565b73ffffffffffffffffffffffffffffffffffffffff8091169081156102f1576003549081168083146111ee57827f8352ba19c21cdb525381f325922bf54276532b75cd30d187ea8d8733d6001898937fffffffffffffffffffffffff0000000000000000000000000000000000000000604094161760035582519182526020820152a180f35b60046040517f367558c3000000000000000000000000000000000000000000000000000000008152fd5b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d57602073ffffffffffffffffffffffffffffffffffffffff60035416604051908152f35b503461021d5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d576112da6112d460a09273ffffffffffffffffffffffffffffffffffffffff6112c06115f7565b1681526005602052604060243591206116f2565b5061182e565b60208101519060408101519060608101518460808301519201511515926040519485526020850152604084015260608301526080820152f35b503461021d576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126109745773ffffffffffffffffffffffffffffffffffffffff6113616115f7565b1691828152600580835260408220549261137a84611891565b94835b858110611392576040518061048d8982611642565b6001908286528484526113a881604088206116f2565b50546113b4828a6118e0565b520161137d565b503461021d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d576113f36115f7565b6113fb61173d565b6003549073ffffffffffffffffffffffffffffffffffffffff808316611447577fffffffffffffffffffffffff0000000000000000000000000000000000000000911691161760035580f35b60046040517f5176b12f000000000000000000000000000000000000000000000000000000008152fd5b503461021d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d576020600454604051908152f35b503461021d57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021d5773ffffffffffffffffffffffffffffffffffffffff6114fc6115f7565b168152600582526040812080549061151382611879565b9361152160405195866117ed565b82855280850191845280842084925b8484106115da578686815181825b8281106115a9575061154f90611891565b91805b828110611567576040518061048d8682611642565b60a061157382876118e0565b51015115611584575b600101611552565b906001809161159384886118e0565b515161159f82886118e0565b520191905061157c565b60a06115b582876118e0565b510151156115c6575b60010161153e565b906115d26001916118f4565b9190506115be565b6006836001926115e98561182e565b815201920193019290611530565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361161a57565b600080fd5b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361161a57565b6020908160408183019282815285518094520193019160005b828110611669575050505090565b83518552938101939281019260010161165b565b60208082019080835283518092528060408094019401926000905b8382106116a757505050505090565b84518051875280840151878501528082015187830152606080820151908801526080808201519088015260a09081015115159087015260c09095019493820193600190910190611698565b805482101561170e576000526006602060002091020190600090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff60005416330361175e57565b60246040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152fd5b67ffffffffffffffff81116117a257604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60c0810190811067ffffffffffffffff8211176117a257604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176117a257604052565b9060405161183b816117d1565b60a060ff6005839580548552600181015460208601526002810154604086015260038101546060860152600481015460808601520154161515910152565b67ffffffffffffffff81116117a25760051b60200190565b9061189b82611879565b6118a860405191826117ed565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06118d68294611879565b0190602036910137565b805182101561170e5760209160051b010190565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146119215760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9190820180921161192157565b919091811580611b10575b611ae85773ffffffffffffffffffffffffffffffffffffffff16916000938385526005602052604085208054956119a160045485611950565b6040516119ad816117d1565b88815260208101878152604082019086825260608301928884526080810194855260a0810196868852680100000000000000008d1015611abb578c6119f7916001820181556116f2565b969096611a8f5750938b9a9996936005937fe22a6a2aa4e4fd33e4087815087f265c780696d4477361e0f0734e7752b246379a979360609a97518555516001850155516002840155516003830155516004820155019051151560ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00835416911617905560405192835260208301526040820152a390565b807f4e487b71000000000000000000000000000000000000000000000000000000006024925280600452fd5b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b505050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90565b508315611968565b9190820391821161192157565b8181029291811591840414171561192157565b8115611b42570490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b90916040519360208501937f23b872dd00000000000000000000000000000000000000000000000000000000855273ffffffffffffffffffffffffffffffffffffffff9283809216602488015216604486015260648501526064845260a084019167ffffffffffffffff92858110848211176117a2576040521692600080938192519082875af13d15611cef573d918211611cc25790611c519160405191611c4160207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601846117ed565b82523d84602084013e5b84611cfc565b908151918215159283611c9a575b505050611c695750565b602490604051907f5274afe70000000000000000000000000000000000000000000000000000000082526004820152fd5b81929350906020918101031261097457602001519081159182150361021d5750388080611c5f565b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b611c519150606090611c4b565b90611d3b5750805115611d1157805190602001fd5b60046040517f1425ea42000000000000000000000000000000000000000000000000000000008152fd5b81511580611d93575b611d4c575090565b60249073ffffffffffffffffffffffffffffffffffffffff604051917f9996b315000000000000000000000000000000000000000000000000000000008352166004820152fd5b50803b15611d44565b6002805414611dab5760028055565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b919081101561170e5760051b019056fea2646970667358221220864538173d1cb39d8182d0da9b3739530fca18ef01ee353aaab9d757997960dd64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ab846fb6c81370327e784ae7cbb6d6a6af6ff4bf000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000c4677c513aec114b65cee1c95d505c708cc77f6d000000000000000000000000000000000000000000000000000000000024ea00
-----Decoded View---------------
Arg [0] : _pal (address): 0xAB846Fb6C81370327e784Ae7CbB6d6a6af6Ff4BF
Arg [1] : _extraToken (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [2] : _tokenReserve (address): 0xc4677C513aEC114B65cEe1C95D505c708CC77f6d
Arg [3] : _vestingDuration (uint256): 2419200
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000ab846fb6c81370327e784ae7cbb6d6a6af6ff4bf
Arg [1] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [2] : 000000000000000000000000c4677c513aec114b65cee1c95d505c708cc77f6d
Arg [3] : 000000000000000000000000000000000000000000000000000000000024ea00
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.