Source Code
EVM
Latest 21 from a total of 21 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Process Fees Wit... | 35556880 | 13 days ago | IN | 0 ETH | 0.00004646 | ||||
| Set Use Amount | 35371762 | 14 days ago | IN | 0 ETH | 0.00000545 | ||||
| Set Threshold | 35371725 | 14 days ago | IN | 0 ETH | 0.00000628 | ||||
| Process Fees Wit... | 35370089 | 14 days ago | IN | 0 ETH | 0.00004553 | ||||
| Set Threshold | 35370007 | 14 days ago | IN | 0 ETH | 0.00000758 | ||||
| Set Use Amount | 35369901 | 14 days ago | IN | 0 ETH | 0.00000627 | ||||
| Transfer Ownersh... | 28245036 | 61 days ago | IN | 0 ETH | 0.00000691 | ||||
| Process Fees Wit... | 24632287 | 82 days ago | IN | 0 ETH | 0.00004444 | ||||
| Process Fees Wit... | 23749583 | 87 days ago | IN | 0 ETH | 0.00004641 | ||||
| Process Fees Wit... | 23435348 | 88 days ago | IN | 0 ETH | 0.00004686 | ||||
| Process Fees Wit... | 23261626 | 89 days ago | IN | 0 ETH | 0.00004628 | ||||
| Process Fees Wit... | 23256801 | 89 days ago | IN | 0 ETH | 0.00004748 | ||||
| Process Fees Wit... | 23254531 | 89 days ago | IN | 0 ETH | 0.00004419 | ||||
| Process Fees Wit... | 23252940 | 89 days ago | IN | 0 ETH | 0.00003984 | ||||
| Process Fees Wit... | 23252125 | 89 days ago | IN | 0 ETH | 0.00004422 | ||||
| Process Fees Wit... | 23251577 | 89 days ago | IN | 0 ETH | 0.00003983 | ||||
| Process Fees Wit... | 23250809 | 89 days ago | IN | 0 ETH | 0.00004296 | ||||
| Process Fees Wit... | 23249870 | 89 days ago | IN | 0 ETH | 0.00003987 | ||||
| Process Fees Wit... | 23249498 | 89 days ago | IN | 0 ETH | 0.00003987 | ||||
| Process Fees Wit... | 23249051 | 89 days ago | IN | 0 ETH | 0.00004433 | ||||
| Set Strategy Cor... | 23245654 | 89 days ago | IN | 0 ETH | 0.00000567 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 37480564 | 2 days ago | 0.00075652 ETH | ||||
| 37337621 | 3 days ago | 0.00075747 ETH | ||||
| 37337621 | 3 days ago | 0.00078679 ETH | ||||
| 37238776 | 3 days ago | 0.00084831 ETH | ||||
| 37194212 | 3 days ago | 0.00085045 ETH | ||||
| 37118035 | 4 days ago | 0.00089603 ETH | ||||
| 37081920 | 4 days ago | 0.00535033 ETH | ||||
| 37033433 | 4 days ago | 0.00091052 ETH | ||||
| 37007120 | 4 days ago | 0.00091174 ETH | ||||
| 36944045 | 4 days ago | 0.0009153 ETH | ||||
| 36790941 | 5 days ago | 0.0009339 ETH | ||||
| 36582740 | 6 days ago | 0.00093487 ETH | ||||
| 36581351 | 6 days ago | 0.00108787 ETH | ||||
| 36580416 | 6 days ago | 0.00108951 ETH | ||||
| 36580416 | 6 days ago | 0.00114039 ETH | ||||
| 36336101 | 8 days ago | 0.00115071 ETH | ||||
| 36141862 | 9 days ago | 0.00027876 ETH | ||||
| 35941488 | 10 days ago | 0.00115741 ETH | ||||
| 35731591 | 12 days ago | 0.00019583 ETH | ||||
| 35577016 | 13 days ago | 0.00115581 ETH | ||||
| 35575209 | 13 days ago | 0.00040878 ETH | ||||
| 35574731 | 13 days ago | 0.0007884 ETH | ||||
| 35574212 | 13 days ago | 0.01521407 ETH | ||||
| 35556928 | 13 days ago | 0.00096457 ETH | ||||
| 35556914 | 13 days ago | 0.00096587 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
FeeCollector
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
No with 200 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../interfaces/IUniswapV2Router02.sol";
// Interface for StrategyCore contract
interface IStrategyCore {
function depositPengu(uint256 amountPengu, uint256 ethSpent) external;
}
// Interface for Treasury contract
interface ITreasury {
function depositPengu(uint256 amount) external;
}
/**
* @title FeeCollector
* @dev Collects ETH from StratToken, buys PENGU tokens, and distributes them
* @notice This contract accumulates ETH and converts it to PENGU for the ecosystem
*/
contract FeeCollector is Ownable, ReentrancyGuard {
using SafeERC20 for IERC20;
// ============ CUSTOM ERRORS ============
error InsufficientBalance();
error InvalidThreshold();
error InvalidUseAmount();
error InvalidAddress();
error InvalidDistributionRatio();
error SwapFailed();
error InsufficientTokensReceived();
error TransferFailed();
error InvalidDeadline();
error ZeroAmount();
error SlippageTooHigh();
error ApprovalFailed();
// ============ EVENTS ============
event ETHReceived(address indexed from, uint256 amount);
event FeeProcessed(
uint256 ethUsed,
uint256 penguReceived,
uint256 toStrategy,
uint256 toTreasury
);
event ThresholdUpdated(uint256 oldThreshold, uint256 newThreshold);
event UseAmountUpdated(uint256 oldAmount, uint256 newAmount);
event RouterUpdated(address indexed oldRouter, address indexed newRouter);
event StrategyUpdated(
address indexed oldStrategy,
address indexed newStrategy
);
event TreasuryUpdated(
address indexed oldTreasury,
address indexed newTreasury
);
event EmergencyWithdraw(address indexed token, uint256 amount);
// ============ STATE VARIABLES ============
// Core addresses
address public penguAddress;
IUniswapV2Router02 public router;
IStrategyCore public strategyCore;
ITreasury public treasury;
// Configuration parameters
uint256 public threshold = 0.2 ether; // Minimum ETH to trigger processFees
uint256 public useAmount = 0.19 ether; // Amount to use per process
// Distribution ratios (basis points)
uint256 public constant STRATEGY_RATIO = 7000; // 70%
uint256 public constant TREASURY_RATIO = 3000; // 30%
uint256 public constant BPS_DENOM = 10000; // 100%
// Constants
uint256 private constant MAX_DEADLINE_BUFFER = 20 minutes;
uint256 public totalPenguPurchased;
// ============ CONSTRUCTOR ============
/**
* @dev Initialize FeeCollector with required addresses and parameters
* @param _penguAddress Address of PENGU token contract
* @param _router Address of Uniswap V2 router
* @param _strategyCore Address of StrategyCore contract
* @param _treasury Address of Treasury contract
* @param _owner Address of contract owner (multisig)
*/
constructor(
address _penguAddress,
address _router,
address _strategyCore,
address _treasury,
address _owner
) Ownable(_owner) {
if (_penguAddress == address(0)) revert InvalidAddress();
if (_router == address(0)) revert InvalidAddress();
if (_strategyCore == address(0)) revert InvalidAddress();
if (_treasury == address(0)) revert InvalidAddress();
if (_owner == address(0)) revert InvalidAddress();
penguAddress = _penguAddress;
router = IUniswapV2Router02(_router);
strategyCore = IStrategyCore(_strategyCore);
treasury = ITreasury(_treasury);
// Validate distribution ratios
if (STRATEGY_RATIO + TREASURY_RATIO != BPS_DENOM) {
revert InvalidDistributionRatio();
}
}
// ============ RECEIVE FUNCTIONS ============
/**
* @dev Receive ETH from any source
*/
receive() external payable {
emit ETHReceived(msg.sender, msg.value);
}
/**
* @dev Explicit function for receiving ETH from StratToken
*/
function receiveETH() external payable {
emit ETHReceived(msg.sender, msg.value);
}
// ============ MAIN FUNCTIONS ============
/**
* @dev Process fees received, swap for PENGU, and distribute between strategy and treasury.
* @param slippageBps Slippage tolerance (basis points)
*/
function processFeesWithSlippage(uint256 slippageBps) external nonReentrant {
if (slippageBps > 1500) revert SlippageTooHigh();
uint256 currentBalance = address(this).balance;
if (currentBalance < threshold) revert InsufficientBalance();
uint256 ethToUse = useAmount > currentBalance ? currentBalance : useAmount;
if (ethToUse == 0) revert ZeroAmount();
uint256 minTokensOut = _calculateMinTokensOut(ethToUse, slippageBps);
uint256 penguReceived = _swapETHForPengu(ethToUse, minTokensOut);
_distributePengu(penguReceived, ethToUse);
emit FeeProcessed(
ethToUse, penguReceived,
(penguReceived * STRATEGY_RATIO) / BPS_DENOM,
(penguReceived * TREASURY_RATIO) / BPS_DENOM
);
}
// ============ INTERNAL FUNCTIONS ============
/**
* @dev Swap ETH for PENGU tokens via Uniswap
* @param ethAmount Amount of ETH to swap
* @param minTokensOut Minimum tokens expected
* @return penguReceived Amount of PENGU tokens received
*/
function _swapETHForPengu(
uint256 ethAmount,
uint256 minTokensOut
) internal returns (uint256 penguReceived) {
// Build swap path: WETH -> PENGU
address[] memory path = new address[](2);
path[0] = router.WETH();
path[1] = penguAddress;
// Record PENGU balance before swap
uint256 balanceBefore = IERC20(penguAddress).balanceOf(address(this));
try
router.swapExactETHForTokensSupportingFeeOnTransferTokens{
value: ethAmount
}(
minTokensOut,
path,
address(this),
block.timestamp + MAX_DEADLINE_BUFFER
)
{
// Calculate actual tokens received
uint256 balanceAfter = IERC20(penguAddress).balanceOf(
address(this)
);
penguReceived = balanceAfter - balanceBefore;
// Verify minimum amount received
if (penguReceived < minTokensOut) {
revert InsufficientTokensReceived();
}
} catch {
revert SwapFailed();
}
}
/**
* @dev Distribute PENGU tokens to StrategyCore and Treasury
* @param totalAmount Total PENGU amount to distribute
* @param ethSpent Amount of ETH spent for this PENGU purchase
*/
function _distributePengu(uint256 totalAmount, uint256 ethSpent) internal {
totalPenguPurchased += totalAmount;
uint256 toStrategy = (totalAmount * STRATEGY_RATIO) / BPS_DENOM;
uint256 toTreasury = totalAmount - toStrategy;
IERC20 pengu = IERC20(penguAddress);
// Send to StrategyCore with proportional ETH spent
if (toStrategy > 0) {
if (!pengu.approve(address(strategyCore), toStrategy)) {
revert ApprovalFailed();
}
uint256 strategyEthSpent = (ethSpent * STRATEGY_RATIO) / BPS_DENOM;
strategyCore.depositPengu(toStrategy, strategyEthSpent);
}
// Send to Treasury
if (toTreasury > 0) {
if (!pengu.approve(address(treasury), toTreasury)) {
revert ApprovalFailed();
}
treasury.depositPengu(toTreasury);
}
}
/**
* @dev Calculate minimum tokens out based on current price and slippage
* @param ethAmount ETH amount to swap
* @param slippageBps Slippage in basis points
* @return minTokensOut Minimum expected tokens
*/
function _calculateMinTokensOut(
uint256 ethAmount,
uint256 slippageBps
) internal view returns (uint256 minTokensOut) {
address[] memory path = new address[](2);
path[0] = router.WETH();
path[1] = penguAddress;
try router.getAmountsOut(ethAmount, path) returns (
uint[] memory amounts
) {
uint256 expectedTokens = amounts[1];
minTokensOut =
(expectedTokens * (BPS_DENOM - slippageBps)) /
BPS_DENOM;
} catch {
// Fallback to 0 if price lookup fails
minTokensOut = 0;
}
}
// ============ ADMIN FUNCTIONS ============
/**
* @dev Set processing threshold
* @param _threshold New threshold in wei
*/
function setThreshold(uint256 _threshold) external onlyOwner {
if (_threshold == 0) revert InvalidThreshold();
uint256 oldThreshold = threshold;
threshold = _threshold;
emit ThresholdUpdated(oldThreshold, _threshold);
}
/**
* @dev Set use amount per processing
* @param _useAmount New use amount in wei
*/
function setUseAmount(uint256 _useAmount) external onlyOwner {
if (_useAmount == 0) revert InvalidUseAmount();
uint256 oldAmount = useAmount;
useAmount = _useAmount;
emit UseAmountUpdated(oldAmount, _useAmount);
}
/**
* @dev Update Uniswap router address
* @param _router New router address
*/
function setRouter(address _router) external onlyOwner {
if (_router == address(0)) revert InvalidAddress();
address oldRouter = address(router);
router = IUniswapV2Router02(_router);
emit RouterUpdated(oldRouter, _router);
}
/**
* @dev Update StrategyCore contract address
* @param _strategyCore New StrategyCore address
*/
function setStrategyCore(address _strategyCore) external onlyOwner {
if (_strategyCore == address(0)) revert InvalidAddress();
address oldStrategy = address(strategyCore);
strategyCore = IStrategyCore(_strategyCore);
emit StrategyUpdated(oldStrategy, _strategyCore);
}
/**
* @dev Update Treasury contract address
* @param _treasury New Treasury address
*/
function setTreasury(address _treasury) external onlyOwner {
if (_treasury == address(0)) revert InvalidAddress();
address oldTreasury = address(treasury);
treasury = ITreasury(_treasury);
emit TreasuryUpdated(oldTreasury, _treasury);
}
/**
* @dev Update PENGU token address
* @param _penguAddress New PENGU token address
*/
function setPenguAddress(address _penguAddress) external onlyOwner {
if (_penguAddress == address(0)) revert InvalidAddress();
penguAddress = _penguAddress;
}
// ============ EMERGENCY FUNCTIONS ============
/**
* @dev Emergency withdraw ETH
* @param amount Amount to withdraw (0 = all)
*/
function emergencyWithdrawETH(uint256 amount) external onlyOwner {
uint256 balance = address(this).balance;
uint256 withdrawAmount = amount == 0 ? balance : amount;
if (withdrawAmount > balance) {
withdrawAmount = balance;
}
(bool success, ) = payable(owner()).call{value: withdrawAmount}("");
if (!success) revert TransferFailed();
emit EmergencyWithdraw(address(0), withdrawAmount);
}
/**
* @dev Emergency withdraw any ERC20 token
* @param token Token address to withdraw
* @param amount Amount to withdraw (0 = all)
*/
function emergencyWithdrawToken(
address token,
uint256 amount
) external onlyOwner {
if (token == address(0)) revert InvalidAddress();
IERC20 tokenContract = IERC20(token);
uint256 balance = tokenContract.balanceOf(address(this));
uint256 withdrawAmount = amount == 0 ? balance : amount;
if (withdrawAmount > balance) {
withdrawAmount = balance;
}
tokenContract.safeTransfer(owner(), withdrawAmount);
emit EmergencyWithdraw(token, withdrawAmount);
}
// ============ VIEW FUNCTIONS ============
/**
* @dev Check if processing can be triggered
* @return canProcessNow True if threshold is met
* @return availableAmount Amount available for processing
*/
function canProcess()
external
view
returns (bool canProcessNow, uint256 availableAmount)
{
uint256 currentBalance = address(this).balance;
canProcessNow = currentBalance >= threshold;
if (canProcessNow) {
availableAmount = useAmount > currentBalance
? currentBalance
: useAmount;
}
}
/**
* @dev Get current contract configuration
* @return _threshold Current threshold value
* @return _useAmount Current use amount
* @return _penguAddress PENGU token address
* @return _router Router address
* @return _strategyCore StrategyCore address
* @return _treasury Treasury address
*/
function getConfig()
external
view
returns (
uint256 _threshold,
uint256 _useAmount,
address _penguAddress,
address _router,
address _strategyCore,
address _treasury
)
{
return (
threshold,
useAmount,
penguAddress,
address(router),
address(strategyCore),
address(treasury)
);
}
/**
* @dev Get expected PENGU tokens for ETH amount
* @param ethAmount ETH amount to check
* @return expectedTokens Expected PENGU tokens (may be 0 if price lookup fails)
*/
function getExpectedTokens(
uint256 ethAmount
) external view returns (uint256 expectedTokens) {
if (ethAmount == 0) return 0;
address[] memory path = new address[](2);
path[0] = router.WETH();
path[1] = penguAddress;
try router.getAmountsOut(ethAmount, path) returns (
uint[] memory amounts
) {
expectedTokens = amounts[1];
} catch {
expectedTokens = 0;
}
}
function getTotalPenguPurchased() external view returns (uint256) {
return totalPenguPurchased;
}
function getETHBalance() external view returns (uint256) {
return address(this).balance;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IUniswapV2Router02 {
function factory() external pure returns (address);
function WETH() external view returns (address);
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function getAmountsOut(uint amountIn, address[] calldata path)
external view returns (uint[] memory amounts);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
external payable returns (uint[] memory amounts);
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
external returns (uint[] memory amounts);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @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": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": false,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "shanghai",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_penguAddress","type":"address"},{"internalType":"address","name":"_router","type":"address"},{"internalType":"address","name":"_strategyCore","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalFailed","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InsufficientTokensReceived","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidDeadline","type":"error"},{"inputs":[],"name":"InvalidDistributionRatio","type":"error"},{"inputs":[],"name":"InvalidThreshold","type":"error"},{"inputs":[],"name":"InvalidUseAmount","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":"SlippageTooHigh","type":"error"},{"inputs":[],"name":"SwapFailed","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ETHReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"ethUsed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"penguReceived","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toStrategy","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTreasury","type":"uint256"}],"name":"FeeProcessed","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":true,"internalType":"address","name":"oldRouter","type":"address"},{"indexed":true,"internalType":"address","name":"newRouter","type":"address"}],"name":"RouterUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldStrategy","type":"address"},{"indexed":true,"internalType":"address","name":"newStrategy","type":"address"}],"name":"StrategyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldThreshold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newThreshold","type":"uint256"}],"name":"ThresholdUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldTreasury","type":"address"},{"indexed":true,"internalType":"address","name":"newTreasury","type":"address"}],"name":"TreasuryUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"UseAmountUpdated","type":"event"},{"inputs":[],"name":"BPS_DENOM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STRATEGY_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canProcess","outputs":[{"internalType":"bool","name":"canProcessNow","type":"bool"},{"internalType":"uint256","name":"availableAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyWithdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyWithdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getConfig","outputs":[{"internalType":"uint256","name":"_threshold","type":"uint256"},{"internalType":"uint256","name":"_useAmount","type":"uint256"},{"internalType":"address","name":"_penguAddress","type":"address"},{"internalType":"address","name":"_router","type":"address"},{"internalType":"address","name":"_strategyCore","type":"address"},{"internalType":"address","name":"_treasury","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getETHBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"ethAmount","type":"uint256"}],"name":"getExpectedTokens","outputs":[{"internalType":"uint256","name":"expectedTokens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalPenguPurchased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"penguAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"slippageBps","type":"uint256"}],"name":"processFeesWithSlippage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"receiveETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_penguAddress","type":"address"}],"name":"setPenguAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_router","type":"address"}],"name":"setRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyCore","type":"address"}],"name":"setStrategyCore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_threshold","type":"uint256"}],"name":"setThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_useAmount","type":"uint256"}],"name":"setUseAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategyCore","outputs":[{"internalType":"contract IStrategyCore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"threshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalPenguPurchased","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":"treasury","outputs":[{"internalType":"contract ITreasury","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"useAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60806040526702c68af0bb1400006006556702a303fe4b53000060075534801562000028575f80fd5b50604051620031363803806200313683398181016040528101906200004e919062000557565b805f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000c2575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401620000b99190620005ec565b60405180910390fd5b620000d3816200043160201b60201c565b50600180819055505f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160362000141576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603620001a7576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036200020d576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000273576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620002d9576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508260045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612710610bb8611b58620003ee91906200063d565b1462000426576040517fbb00f28200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505062000677565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200052182620004f6565b9050919050565b620005338162000515565b81146200053e575f80fd5b50565b5f81519050620005518162000528565b92915050565b5f805f805f60a08688031215620005735762000572620004f2565b5b5f620005828882890162000541565b9550506020620005958882890162000541565b9450506040620005a88882890162000541565b9350506060620005bb8882890162000541565b9250506080620005ce8882890162000541565b9150509295509295909350565b620005e68162000515565b82525050565b5f602082019050620006015f830184620005db565b92915050565b5f819050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f620006498262000607565b9150620006568362000607565b925082820190508082111562000671576200067062000610565b5b92915050565b612ab180620006855f395ff3fe6080604052600436106101ba575f3560e01c80638da5cb5b116100eb578063c0d7865511610089578063dfe1ba7c11610063578063dfe1ba7c146105d9578063f0f4426014610601578063f2fde38b14610629578063f887ea40146106515761020f565b8063c0d786551461055a578063c3f909d414610582578063c55f2c7c146105b15761020f565b8063960bfe04116100c5578063960bfe04146104b65780639ce3dd28146104de578063a4c3b09114610508578063ae448119146105305761020f565b80638da5cb5b146104265780638e03400e14610450578063952e13831461048c5761020f565b806361d027b3116101585780636e947298116101325780636e94729814610394578063715018a6146103be5780637f4b437f146103d4578063842f3814146103fc5761020f565b806361d027b3146103185780636637e38c146103425780636b792c4b1461036c5761020f565b806338e5112c1161019457806338e5112c146102905780633ecfd51e146102ba57806342cde4e8146102c45780635b9dd1c9146102ee5761020f565b8063072e0c9f146102135780632729da681461023d57806327e67603146102655761020f565b3661020f573373ffffffffffffffffffffffffffffffffffffffff167fbfe611b001dfcd411432f7bf0d79b82b4b2ee81511edac123a3403c357fb972a3460405161020591906121c2565b60405180910390a2005b5f80fd5b34801561021e575f80fd5b5061022761067b565b60405161023491906121c2565b60405180910390f35b348015610248575f80fd5b50610263600480360381019061025e9190612246565b610681565b005b348015610270575f80fd5b50610279610731565b60405161028792919061228b565b60405180910390f35b34801561029b575f80fd5b506102a4610760565b6040516102b1919061230d565b60405180910390f35b6102c2610785565b005b3480156102cf575f80fd5b506102d86107d5565b6040516102e591906121c2565b60405180910390f35b3480156102f9575f80fd5b506103026107db565b60405161030f9190612335565b60405180910390f35b348015610323575f80fd5b5061032c610800565b604051610339919061236e565b60405180910390f35b34801561034d575f80fd5b50610356610825565b60405161036391906121c2565b60405180910390f35b348015610377575f80fd5b50610392600480360381019061038d91906123b1565b61082b565b005b34801561039f575f80fd5b506103a861094f565b6040516103b591906121c2565b60405180910390f35b3480156103c9575f80fd5b506103d2610956565b005b3480156103df575f80fd5b506103fa60048036038101906103f59190612246565b610969565b005b348015610407575f80fd5b50610410610a99565b60405161041d91906121c2565b60405180910390f35b348015610431575f80fd5b5061043a610a9f565b6040516104479190612335565b60405180910390f35b34801561045b575f80fd5b50610476600480360381019061047191906123b1565b610ac6565b60405161048391906121c2565b60405180910390f35b348015610497575f80fd5b506104a0610d3a565b6040516104ad91906121c2565b60405180910390f35b3480156104c1575f80fd5b506104dc60048036038101906104d791906123b1565b610d43565b005b3480156104e9575f80fd5b506104f2610dce565b6040516104ff91906121c2565b60405180910390f35b348015610513575f80fd5b5061052e600480360381019061052991906123dc565b610dd4565b005b34801561053b575f80fd5b50610544610f65565b60405161055191906121c2565b60405180910390f35b348015610565575f80fd5b50610580600480360381019061057b9190612246565b610f6b565b005b34801561058d575f80fd5b5061059661109b565b6040516105a89695949392919061241a565b60405180910390f35b3480156105bc575f80fd5b506105d760048036038101906105d291906123b1565b611143565b005b3480156105e4575f80fd5b506105ff60048036038101906105fa91906123b1565b6112ba565b005b34801561060c575f80fd5b5061062760048036038101906106229190612246565b611345565b005b348015610634575f80fd5b5061064f600480360381019061064a9190612246565b611475565b005b34801561065c575f80fd5b506106656114f9565b6040516106729190612499565b60405180910390f35b610bb881565b61068961151e565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036106ee576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f805f4790506006548110159250821561075b57806007541161075657600754610758565b805b91505b509091565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff167fbfe611b001dfcd411432f7bf0d79b82b4b2ee81511edac123a3403c357fb972a346040516107cb91906121c2565b60405180910390a2565b60065481565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61271081565b61083361151e565b5f4790505f8083146108455782610847565b815b905081811115610855578190505b5f61085e610a9f565b73ffffffffffffffffffffffffffffffffffffffff1682604051610881906124df565b5f6040518083038185875af1925050503d805f81146108bb576040519150601f19603f3d011682016040523d82523d5f602084013e6108c0565b606091505b50509050806108fb576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff167f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd96958360405161094191906121c2565b60405180910390a250505050565b5f47905090565b61095e61151e565b6109675f6115a5565b565b61097161151e565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109d6576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fe4cec16b1a7e6b7979e923da619a8b1e5fd0f0fb6e5c1cf647f350430ee61ca960405160405180910390a35050565b60085481565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f808203610ad6575f9050610d35565b5f600267ffffffffffffffff811115610af257610af16124f3565b5b604051908082528060200260200182016040528015610b205781602001602082028036833780820191505090505b50905060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bb19190612534565b815f81518110610bc457610bc361255f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681600181518110610c3457610c3361255f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d06ca61f84836040518363ffffffff1660e01b8152600401610cca929190612643565b5f60405180830381865afa925050508015610d0757506040513d5f823e3d601f19601f82011682018060405250810190610d0491906127a8565b60015b610d13575f9150610d33565b80600181518110610d2757610d2661255f565b5b60200260200101519250505b505b919050565b5f600854905090565b610d4b61151e565b5f8103610d84576040517faabd5a0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6006549050816006819055507fb06a54caabe58475c86c2bf9df3f2f06dd1213e9e10659c293117fe4893b274b8183604051610dc29291906127ef565b60405180910390a15050565b611b5881565b610ddc61151e565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610e41576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8290505f8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610e7f9190612335565b602060405180830381865afa158015610e9a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ebe9190612816565b90505f808414610ece5783610ed0565b815b905081811115610ede578190505b610f10610ee9610a9f565b828573ffffffffffffffffffffffffffffffffffffffff166116669092919063ffffffff16565b8473ffffffffffffffffffffffffffffffffffffffff167f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd969582604051610f5691906121c2565b60405180910390a25050505050565b60075481565b610f7361151e565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610fd8576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f168460405160405180910390a35050565b5f805f805f8060065460075460025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16955095509550955095509550909192939495565b61114b6116e5565b6105dc811115611187576040517f850c6f7600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f4790506006548110156111c7576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f81600754116111d9576007546111db565b815b90505f8103611216576040517f1f2a200500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f611221828561172b565b90505f61122e83836119ba565b905061123a8184611da9565b7f4816db49bfc91a0172699baedf430e5d308b8034f966fb25681b27c17bcd3a478382612710611b588561126e919061286e565b61127891906128dc565b612710610bb886611289919061286e565b61129391906128dc565b6040516112a3949392919061290c565b60405180910390a1505050506112b76120ff565b50565b6112c261151e565b5f81036112fb576040517fb7e8247100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6007549050816007819055507f71fbf5c34cfc4adc3a6e97606cc9ceb1285548bc4199aebd25ab48025878a5ce81836040516113399291906127ef565b60405180910390a15050565b61134d61151e565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113b2576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f4ab5be82436d353e61ca18726e984e561f5c1cc7c6d38b29d2553c790434705a60405160405180910390a35050565b61147d61151e565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036114ed575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016114e49190612335565b60405180910390fd5b6114f6816115a5565b50565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611526612108565b73ffffffffffffffffffffffffffffffffffffffff16611544610a9f565b73ffffffffffffffffffffffffffffffffffffffff16146115a357611567612108565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161159a9190612335565b60405180910390fd5b565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6116e0838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb858560405160240161169992919061294f565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061210f565b505050565b600260015403611721576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600181905550565b5f80600267ffffffffffffffff811115611748576117476124f3565b5b6040519080825280602002602001820160405280156117765781602001602082028036833780820191505090505b50905060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117e3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118079190612534565b815f8151811061181a5761181961255f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff168160018151811061188a5761188961255f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d06ca61f85836040518363ffffffff1660e01b8152600401611920929190612643565b5f60405180830381865afa92505050801561195d57506040513d5f823e3d601f19601f8201168201806040525081019061195a91906127a8565b60015b611969575f91506119b3565b5f8160018151811061197e5761197d61255f565b5b60200260200101519050612710856127106119999190612976565b826119a4919061286e565b6119ae91906128dc565b935050505b5092915050565b5f80600267ffffffffffffffff8111156119d7576119d66124f3565b5b604051908082528060200260200182016040528015611a055781602001602082028036833780820191505090505b50905060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a72573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a969190612534565b815f81518110611aa957611aa861255f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681600181518110611b1957611b1861255f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611bae9190612335565b602060405180830381865afa158015611bc9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bed9190612816565b905060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b6f9de95868685306104b042611c3e91906129a9565b6040518663ffffffff1660e01b8152600401611c5d94939291906129dc565b5f604051808303818588803b158015611c74575f80fd5b505af193505050508015611c86575060015b611cbc576040517f81ceff3000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611d179190612335565b602060405180830381865afa158015611d32573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d569190612816565b90508181611d649190612976565b935084841015611da0576040517faf56342000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505092915050565b8160085f828254611dba91906129a9565b925050819055505f612710611b5884611dd3919061286e565b611ddd91906128dc565b90505f8184611dec9190612976565b90505f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f831115611f96578073ffffffffffffffffffffffffffffffffffffffff1663095ea7b360045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856040518363ffffffff1660e01b8152600401611e7792919061294f565b6020604051808303815f875af1158015611e93573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eb79190612a50565b611eed576040517f8164f84200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f612710611b5886611eff919061286e565b611f0991906128dc565b905060045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c3c8f6ca85836040518363ffffffff1660e01b8152600401611f679291906127ef565b5f604051808303815f87803b158015611f7e575f80fd5b505af1158015611f90573d5f803e3d5ffd5b50505050505b5f8211156120f8578073ffffffffffffffffffffffffffffffffffffffff1663095ea7b360055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401611ffa92919061294f565b6020604051808303815f875af1158015612016573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061203a9190612a50565b612070576040517f8164f84200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631a22de67836040518263ffffffff1660e01b81526004016120ca91906121c2565b5f604051808303815f87803b1580156120e1575f80fd5b505af11580156120f3573d5f803e3d5ffd5b505050505b5050505050565b60018081905550565b5f33905090565b5f8060205f8451602086015f885af18061212e576040513d5f823e3d81fd5b3d92505f519150505f8214612147576001811415612162565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b156121a457836040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161219b9190612335565b60405180910390fd5b50505050565b5f819050919050565b6121bc816121aa565b82525050565b5f6020820190506121d55f8301846121b3565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612215826121ec565b9050919050565b6122258161220b565b811461222f575f80fd5b50565b5f813590506122408161221c565b92915050565b5f6020828403121561225b5761225a6121e4565b5b5f61226884828501612232565b91505092915050565b5f8115159050919050565b61228581612271565b82525050565b5f60408201905061229e5f83018561227c565b6122ab60208301846121b3565b9392505050565b5f819050919050565b5f6122d56122d06122cb846121ec565b6122b2565b6121ec565b9050919050565b5f6122e6826122bb565b9050919050565b5f6122f7826122dc565b9050919050565b612307816122ed565b82525050565b5f6020820190506123205f8301846122fe565b92915050565b61232f8161220b565b82525050565b5f6020820190506123485f830184612326565b92915050565b5f612358826122dc565b9050919050565b6123688161234e565b82525050565b5f6020820190506123815f83018461235f565b92915050565b612390816121aa565b811461239a575f80fd5b50565b5f813590506123ab81612387565b92915050565b5f602082840312156123c6576123c56121e4565b5b5f6123d38482850161239d565b91505092915050565b5f80604083850312156123f2576123f16121e4565b5b5f6123ff85828601612232565b92505060206124108582860161239d565b9150509250929050565b5f60c08201905061242d5f8301896121b3565b61243a60208301886121b3565b6124476040830187612326565b6124546060830186612326565b6124616080830185612326565b61246e60a0830184612326565b979650505050505050565b5f612483826122dc565b9050919050565b61249381612479565b82525050565b5f6020820190506124ac5f83018461248a565b92915050565b5f81905092915050565b50565b5f6124ca5f836124b2565b91506124d5826124bc565b5f82019050919050565b5f6124e9826124bf565b9150819050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f8151905061252e8161221c565b92915050565b5f60208284031215612549576125486121e4565b5b5f61255684828501612520565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6125be8161220b565b82525050565b5f6125cf83836125b5565b60208301905092915050565b5f602082019050919050565b5f6125f18261258c565b6125fb8185612596565b9350612606836125a6565b805f5b8381101561263657815161261d88826125c4565b9750612628836125db565b925050600181019050612609565b5085935050505092915050565b5f6040820190506126565f8301856121b3565b818103602083015261266881846125e7565b90509392505050565b5f80fd5b5f601f19601f8301169050919050565b61268e82612675565b810181811067ffffffffffffffff821117156126ad576126ac6124f3565b5b80604052505050565b5f6126bf6121db565b90506126cb8282612685565b919050565b5f67ffffffffffffffff8211156126ea576126e96124f3565b5b602082029050602081019050919050565b5f80fd5b5f8151905061270d81612387565b92915050565b5f612725612720846126d0565b6126b6565b90508083825260208201905060208402830185811115612748576127476126fb565b5b835b81811015612771578061275d88826126ff565b84526020840193505060208101905061274a565b5050509392505050565b5f82601f83011261278f5761278e612671565b5b815161279f848260208601612713565b91505092915050565b5f602082840312156127bd576127bc6121e4565b5b5f82015167ffffffffffffffff8111156127da576127d96121e8565b5b6127e68482850161277b565b91505092915050565b5f6040820190506128025f8301856121b3565b61280f60208301846121b3565b9392505050565b5f6020828403121561282b5761282a6121e4565b5b5f612838848285016126ff565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612878826121aa565b9150612883836121aa565b9250828202612891816121aa565b915082820484148315176128a8576128a7612841565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6128e6826121aa565b91506128f1836121aa565b925082612901576129006128af565b5b828204905092915050565b5f60808201905061291f5f8301876121b3565b61292c60208301866121b3565b61293960408301856121b3565b61294660608301846121b3565b95945050505050565b5f6040820190506129625f830185612326565b61296f60208301846121b3565b9392505050565b5f612980826121aa565b915061298b836121aa565b92508282039050818111156129a3576129a2612841565b5b92915050565b5f6129b3826121aa565b91506129be836121aa565b92508282019050808211156129d6576129d5612841565b5b92915050565b5f6080820190506129ef5f8301876121b3565b8181036020830152612a0181866125e7565b9050612a106040830185612326565b612a1d60608301846121b3565b95945050505050565b612a2f81612271565b8114612a39575f80fd5b50565b5f81519050612a4a81612a26565b92915050565b5f60208284031215612a6557612a646121e4565b5b5f612a7284828501612a3c565b9150509291505056fea2646970667358221220cac4875bd7f2659711f97aca883b532a413f5b06eee3b25d6916601d0b8cbcd364736f6c63430008140033000000000000000000000000987cf44f3f5d854ec0703123d7fd003a8b56ebb4000000000000000000000000ad1eca41e6f772be3cb5a48a6141f9bcc1af9f7c0000000000000000000000006b973a20a7f5beb311e38d19e7b4a634f1f0b54e000000000000000000000000e8fa3aae1693ee1c7220e0ba8da2a9462a829d610000000000000000000000006b973a20a7f5beb311e38d19e7b4a634f1f0b54e
Deployed Bytecode
0x6080604052600436106101ba575f3560e01c80638da5cb5b116100eb578063c0d7865511610089578063dfe1ba7c11610063578063dfe1ba7c146105d9578063f0f4426014610601578063f2fde38b14610629578063f887ea40146106515761020f565b8063c0d786551461055a578063c3f909d414610582578063c55f2c7c146105b15761020f565b8063960bfe04116100c5578063960bfe04146104b65780639ce3dd28146104de578063a4c3b09114610508578063ae448119146105305761020f565b80638da5cb5b146104265780638e03400e14610450578063952e13831461048c5761020f565b806361d027b3116101585780636e947298116101325780636e94729814610394578063715018a6146103be5780637f4b437f146103d4578063842f3814146103fc5761020f565b806361d027b3146103185780636637e38c146103425780636b792c4b1461036c5761020f565b806338e5112c1161019457806338e5112c146102905780633ecfd51e146102ba57806342cde4e8146102c45780635b9dd1c9146102ee5761020f565b8063072e0c9f146102135780632729da681461023d57806327e67603146102655761020f565b3661020f573373ffffffffffffffffffffffffffffffffffffffff167fbfe611b001dfcd411432f7bf0d79b82b4b2ee81511edac123a3403c357fb972a3460405161020591906121c2565b60405180910390a2005b5f80fd5b34801561021e575f80fd5b5061022761067b565b60405161023491906121c2565b60405180910390f35b348015610248575f80fd5b50610263600480360381019061025e9190612246565b610681565b005b348015610270575f80fd5b50610279610731565b60405161028792919061228b565b60405180910390f35b34801561029b575f80fd5b506102a4610760565b6040516102b1919061230d565b60405180910390f35b6102c2610785565b005b3480156102cf575f80fd5b506102d86107d5565b6040516102e591906121c2565b60405180910390f35b3480156102f9575f80fd5b506103026107db565b60405161030f9190612335565b60405180910390f35b348015610323575f80fd5b5061032c610800565b604051610339919061236e565b60405180910390f35b34801561034d575f80fd5b50610356610825565b60405161036391906121c2565b60405180910390f35b348015610377575f80fd5b50610392600480360381019061038d91906123b1565b61082b565b005b34801561039f575f80fd5b506103a861094f565b6040516103b591906121c2565b60405180910390f35b3480156103c9575f80fd5b506103d2610956565b005b3480156103df575f80fd5b506103fa60048036038101906103f59190612246565b610969565b005b348015610407575f80fd5b50610410610a99565b60405161041d91906121c2565b60405180910390f35b348015610431575f80fd5b5061043a610a9f565b6040516104479190612335565b60405180910390f35b34801561045b575f80fd5b50610476600480360381019061047191906123b1565b610ac6565b60405161048391906121c2565b60405180910390f35b348015610497575f80fd5b506104a0610d3a565b6040516104ad91906121c2565b60405180910390f35b3480156104c1575f80fd5b506104dc60048036038101906104d791906123b1565b610d43565b005b3480156104e9575f80fd5b506104f2610dce565b6040516104ff91906121c2565b60405180910390f35b348015610513575f80fd5b5061052e600480360381019061052991906123dc565b610dd4565b005b34801561053b575f80fd5b50610544610f65565b60405161055191906121c2565b60405180910390f35b348015610565575f80fd5b50610580600480360381019061057b9190612246565b610f6b565b005b34801561058d575f80fd5b5061059661109b565b6040516105a89695949392919061241a565b60405180910390f35b3480156105bc575f80fd5b506105d760048036038101906105d291906123b1565b611143565b005b3480156105e4575f80fd5b506105ff60048036038101906105fa91906123b1565b6112ba565b005b34801561060c575f80fd5b5061062760048036038101906106229190612246565b611345565b005b348015610634575f80fd5b5061064f600480360381019061064a9190612246565b611475565b005b34801561065c575f80fd5b506106656114f9565b6040516106729190612499565b60405180910390f35b610bb881565b61068961151e565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036106ee576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f805f4790506006548110159250821561075b57806007541161075657600754610758565b805b91505b509091565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff167fbfe611b001dfcd411432f7bf0d79b82b4b2ee81511edac123a3403c357fb972a346040516107cb91906121c2565b60405180910390a2565b60065481565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61271081565b61083361151e565b5f4790505f8083146108455782610847565b815b905081811115610855578190505b5f61085e610a9f565b73ffffffffffffffffffffffffffffffffffffffff1682604051610881906124df565b5f6040518083038185875af1925050503d805f81146108bb576040519150601f19603f3d011682016040523d82523d5f602084013e6108c0565b606091505b50509050806108fb576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff167f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd96958360405161094191906121c2565b60405180910390a250505050565b5f47905090565b61095e61151e565b6109675f6115a5565b565b61097161151e565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109d6576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fe4cec16b1a7e6b7979e923da619a8b1e5fd0f0fb6e5c1cf647f350430ee61ca960405160405180910390a35050565b60085481565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f808203610ad6575f9050610d35565b5f600267ffffffffffffffff811115610af257610af16124f3565b5b604051908082528060200260200182016040528015610b205781602001602082028036833780820191505090505b50905060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bb19190612534565b815f81518110610bc457610bc361255f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681600181518110610c3457610c3361255f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d06ca61f84836040518363ffffffff1660e01b8152600401610cca929190612643565b5f60405180830381865afa925050508015610d0757506040513d5f823e3d601f19601f82011682018060405250810190610d0491906127a8565b60015b610d13575f9150610d33565b80600181518110610d2757610d2661255f565b5b60200260200101519250505b505b919050565b5f600854905090565b610d4b61151e565b5f8103610d84576040517faabd5a0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6006549050816006819055507fb06a54caabe58475c86c2bf9df3f2f06dd1213e9e10659c293117fe4893b274b8183604051610dc29291906127ef565b60405180910390a15050565b611b5881565b610ddc61151e565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610e41576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8290505f8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610e7f9190612335565b602060405180830381865afa158015610e9a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ebe9190612816565b90505f808414610ece5783610ed0565b815b905081811115610ede578190505b610f10610ee9610a9f565b828573ffffffffffffffffffffffffffffffffffffffff166116669092919063ffffffff16565b8473ffffffffffffffffffffffffffffffffffffffff167f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd969582604051610f5691906121c2565b60405180910390a25050505050565b60075481565b610f7361151e565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610fd8576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f168460405160405180910390a35050565b5f805f805f8060065460075460025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16955095509550955095509550909192939495565b61114b6116e5565b6105dc811115611187576040517f850c6f7600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f4790506006548110156111c7576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f81600754116111d9576007546111db565b815b90505f8103611216576040517f1f2a200500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f611221828561172b565b90505f61122e83836119ba565b905061123a8184611da9565b7f4816db49bfc91a0172699baedf430e5d308b8034f966fb25681b27c17bcd3a478382612710611b588561126e919061286e565b61127891906128dc565b612710610bb886611289919061286e565b61129391906128dc565b6040516112a3949392919061290c565b60405180910390a1505050506112b76120ff565b50565b6112c261151e565b5f81036112fb576040517fb7e8247100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6007549050816007819055507f71fbf5c34cfc4adc3a6e97606cc9ceb1285548bc4199aebd25ab48025878a5ce81836040516113399291906127ef565b60405180910390a15050565b61134d61151e565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113b2576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f4ab5be82436d353e61ca18726e984e561f5c1cc7c6d38b29d2553c790434705a60405160405180910390a35050565b61147d61151e565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036114ed575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016114e49190612335565b60405180910390fd5b6114f6816115a5565b50565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611526612108565b73ffffffffffffffffffffffffffffffffffffffff16611544610a9f565b73ffffffffffffffffffffffffffffffffffffffff16146115a357611567612108565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161159a9190612335565b60405180910390fd5b565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6116e0838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb858560405160240161169992919061294f565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061210f565b505050565b600260015403611721576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600181905550565b5f80600267ffffffffffffffff811115611748576117476124f3565b5b6040519080825280602002602001820160405280156117765781602001602082028036833780820191505090505b50905060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117e3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118079190612534565b815f8151811061181a5761181961255f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff168160018151811061188a5761188961255f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d06ca61f85836040518363ffffffff1660e01b8152600401611920929190612643565b5f60405180830381865afa92505050801561195d57506040513d5f823e3d601f19601f8201168201806040525081019061195a91906127a8565b60015b611969575f91506119b3565b5f8160018151811061197e5761197d61255f565b5b60200260200101519050612710856127106119999190612976565b826119a4919061286e565b6119ae91906128dc565b935050505b5092915050565b5f80600267ffffffffffffffff8111156119d7576119d66124f3565b5b604051908082528060200260200182016040528015611a055781602001602082028036833780820191505090505b50905060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a72573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a969190612534565b815f81518110611aa957611aa861255f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681600181518110611b1957611b1861255f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611bae9190612335565b602060405180830381865afa158015611bc9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bed9190612816565b905060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b6f9de95868685306104b042611c3e91906129a9565b6040518663ffffffff1660e01b8152600401611c5d94939291906129dc565b5f604051808303818588803b158015611c74575f80fd5b505af193505050508015611c86575060015b611cbc576040517f81ceff3000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611d179190612335565b602060405180830381865afa158015611d32573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d569190612816565b90508181611d649190612976565b935084841015611da0576040517faf56342000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505092915050565b8160085f828254611dba91906129a9565b925050819055505f612710611b5884611dd3919061286e565b611ddd91906128dc565b90505f8184611dec9190612976565b90505f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f831115611f96578073ffffffffffffffffffffffffffffffffffffffff1663095ea7b360045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856040518363ffffffff1660e01b8152600401611e7792919061294f565b6020604051808303815f875af1158015611e93573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eb79190612a50565b611eed576040517f8164f84200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f612710611b5886611eff919061286e565b611f0991906128dc565b905060045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c3c8f6ca85836040518363ffffffff1660e01b8152600401611f679291906127ef565b5f604051808303815f87803b158015611f7e575f80fd5b505af1158015611f90573d5f803e3d5ffd5b50505050505b5f8211156120f8578073ffffffffffffffffffffffffffffffffffffffff1663095ea7b360055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401611ffa92919061294f565b6020604051808303815f875af1158015612016573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061203a9190612a50565b612070576040517f8164f84200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631a22de67836040518263ffffffff1660e01b81526004016120ca91906121c2565b5f604051808303815f87803b1580156120e1575f80fd5b505af11580156120f3573d5f803e3d5ffd5b505050505b5050505050565b60018081905550565b5f33905090565b5f8060205f8451602086015f885af18061212e576040513d5f823e3d81fd5b3d92505f519150505f8214612147576001811415612162565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b156121a457836040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161219b9190612335565b60405180910390fd5b50505050565b5f819050919050565b6121bc816121aa565b82525050565b5f6020820190506121d55f8301846121b3565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612215826121ec565b9050919050565b6122258161220b565b811461222f575f80fd5b50565b5f813590506122408161221c565b92915050565b5f6020828403121561225b5761225a6121e4565b5b5f61226884828501612232565b91505092915050565b5f8115159050919050565b61228581612271565b82525050565b5f60408201905061229e5f83018561227c565b6122ab60208301846121b3565b9392505050565b5f819050919050565b5f6122d56122d06122cb846121ec565b6122b2565b6121ec565b9050919050565b5f6122e6826122bb565b9050919050565b5f6122f7826122dc565b9050919050565b612307816122ed565b82525050565b5f6020820190506123205f8301846122fe565b92915050565b61232f8161220b565b82525050565b5f6020820190506123485f830184612326565b92915050565b5f612358826122dc565b9050919050565b6123688161234e565b82525050565b5f6020820190506123815f83018461235f565b92915050565b612390816121aa565b811461239a575f80fd5b50565b5f813590506123ab81612387565b92915050565b5f602082840312156123c6576123c56121e4565b5b5f6123d38482850161239d565b91505092915050565b5f80604083850312156123f2576123f16121e4565b5b5f6123ff85828601612232565b92505060206124108582860161239d565b9150509250929050565b5f60c08201905061242d5f8301896121b3565b61243a60208301886121b3565b6124476040830187612326565b6124546060830186612326565b6124616080830185612326565b61246e60a0830184612326565b979650505050505050565b5f612483826122dc565b9050919050565b61249381612479565b82525050565b5f6020820190506124ac5f83018461248a565b92915050565b5f81905092915050565b50565b5f6124ca5f836124b2565b91506124d5826124bc565b5f82019050919050565b5f6124e9826124bf565b9150819050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f8151905061252e8161221c565b92915050565b5f60208284031215612549576125486121e4565b5b5f61255684828501612520565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6125be8161220b565b82525050565b5f6125cf83836125b5565b60208301905092915050565b5f602082019050919050565b5f6125f18261258c565b6125fb8185612596565b9350612606836125a6565b805f5b8381101561263657815161261d88826125c4565b9750612628836125db565b925050600181019050612609565b5085935050505092915050565b5f6040820190506126565f8301856121b3565b818103602083015261266881846125e7565b90509392505050565b5f80fd5b5f601f19601f8301169050919050565b61268e82612675565b810181811067ffffffffffffffff821117156126ad576126ac6124f3565b5b80604052505050565b5f6126bf6121db565b90506126cb8282612685565b919050565b5f67ffffffffffffffff8211156126ea576126e96124f3565b5b602082029050602081019050919050565b5f80fd5b5f8151905061270d81612387565b92915050565b5f612725612720846126d0565b6126b6565b90508083825260208201905060208402830185811115612748576127476126fb565b5b835b81811015612771578061275d88826126ff565b84526020840193505060208101905061274a565b5050509392505050565b5f82601f83011261278f5761278e612671565b5b815161279f848260208601612713565b91505092915050565b5f602082840312156127bd576127bc6121e4565b5b5f82015167ffffffffffffffff8111156127da576127d96121e8565b5b6127e68482850161277b565b91505092915050565b5f6040820190506128025f8301856121b3565b61280f60208301846121b3565b9392505050565b5f6020828403121561282b5761282a6121e4565b5b5f612838848285016126ff565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612878826121aa565b9150612883836121aa565b9250828202612891816121aa565b915082820484148315176128a8576128a7612841565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6128e6826121aa565b91506128f1836121aa565b925082612901576129006128af565b5b828204905092915050565b5f60808201905061291f5f8301876121b3565b61292c60208301866121b3565b61293960408301856121b3565b61294660608301846121b3565b95945050505050565b5f6040820190506129625f830185612326565b61296f60208301846121b3565b9392505050565b5f612980826121aa565b915061298b836121aa565b92508282039050818111156129a3576129a2612841565b5b92915050565b5f6129b3826121aa565b91506129be836121aa565b92508282019050808211156129d6576129d5612841565b5b92915050565b5f6080820190506129ef5f8301876121b3565b8181036020830152612a0181866125e7565b9050612a106040830185612326565b612a1d60608301846121b3565b95945050505050565b612a2f81612271565b8114612a39575f80fd5b50565b5f81519050612a4a81612a26565b92915050565b5f60208284031215612a6557612a646121e4565b5b5f612a7284828501612a3c565b9150509291505056fea2646970667358221220cac4875bd7f2659711f97aca883b532a413f5b06eee3b25d6916601d0b8cbcd364736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000987cf44f3f5d854ec0703123d7fd003a8b56ebb4000000000000000000000000ad1eca41e6f772be3cb5a48a6141f9bcc1af9f7c0000000000000000000000006b973a20a7f5beb311e38d19e7b4a634f1f0b54e000000000000000000000000e8fa3aae1693ee1c7220e0ba8da2a9462a829d610000000000000000000000006b973a20a7f5beb311e38d19e7b4a634f1f0b54e
-----Decoded View---------------
Arg [0] : _penguAddress (address): 0x987CF44F3F5d854eC0703123d7fD003a8b56eBb4
Arg [1] : _router (address): 0xad1eCa41E6F772bE3cb5A48A6141f9bcc1AF9F7c
Arg [2] : _strategyCore (address): 0x6b973A20A7f5BEb311E38d19e7b4a634F1f0B54E
Arg [3] : _treasury (address): 0xe8Fa3AAE1693ee1C7220E0ba8Da2A9462a829D61
Arg [4] : _owner (address): 0x6b973A20A7f5BEb311E38d19e7b4a634F1f0B54E
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000987cf44f3f5d854ec0703123d7fd003a8b56ebb4
Arg [1] : 000000000000000000000000ad1eca41e6f772be3cb5a48a6141f9bcc1af9f7c
Arg [2] : 0000000000000000000000006b973a20a7f5beb311e38d19e7b4a634f1f0b54e
Arg [3] : 000000000000000000000000e8fa3aae1693ee1c7220e0ba8da2a9462a829d61
Arg [4] : 0000000000000000000000006b973a20a7f5beb311e38d19e7b4a634f1f0b54e
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$140.24
Net Worth in ETH
0.058928
Token Allocations
ETH
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ABSTRACT | 100.00% | $2,390.98 | 0.0587 | $140.24 |
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.