Source Code
Latest 25 from a total of 127 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Update Assets | 24699480 | 1 hr ago | IN | 0 ETH | 0.00007777 | ||||
| Update Assets | 24698581 | 4 hrs ago | IN | 0 ETH | 0.00006934 | ||||
| Update Assets | 24697682 | 7 hrs ago | IN | 0 ETH | 0.00007001 | ||||
| Update Assets | 24696786 | 10 hrs ago | IN | 0 ETH | 0.00006954 | ||||
| Update Assets | 24695889 | 13 hrs ago | IN | 0 ETH | 0.00006978 | ||||
| Update Assets | 24694991 | 16 hrs ago | IN | 0 ETH | 0.00006878 | ||||
| Update Assets | 24694095 | 19 hrs ago | IN | 0 ETH | 0.00006923 | ||||
| Update Assets | 24693197 | 22 hrs ago | IN | 0 ETH | 0.00007498 | ||||
| Update Assets | 24692363 | 25 hrs ago | IN | 0 ETH | 0.00007911 | ||||
| Update Assets | 24691404 | 28 hrs ago | IN | 0 ETH | 0.00007384 | ||||
| Update Assets | 24690505 | 31 hrs ago | IN | 0 ETH | 0.00007198 | ||||
| Deposit | 24690379 | 32 hrs ago | IN | 0 ETH | 0.00025793 | ||||
| Update Assets | 24689608 | 34 hrs ago | IN | 0 ETH | 0.0000693 | ||||
| Update Assets | 24688712 | 37 hrs ago | IN | 0 ETH | 0.00007105 | ||||
| Update Assets | 24687818 | 40 hrs ago | IN | 0 ETH | 0.00007216 | ||||
| Update Assets | 24686925 | 43 hrs ago | IN | 0 ETH | 0.00007391 | ||||
| Update Assets | 24686032 | 46 hrs ago | IN | 0 ETH | 0.00007346 | ||||
| Update Assets | 24685135 | 2 days ago | IN | 0 ETH | 0.00009002 | ||||
| Update Assets | 24684238 | 2 days ago | IN | 0 ETH | 0.00007098 | ||||
| Update Assets | 24683343 | 2 days ago | IN | 0 ETH | 0.00006964 | ||||
| Update Assets | 24682445 | 2 days ago | IN | 0 ETH | 0.00006911 | ||||
| Update Assets | 24681551 | 2 days ago | IN | 0 ETH | 0.00006874 | ||||
| Update Assets | 24680655 | 2 days ago | IN | 0 ETH | 0.00006886 | ||||
| Update Assets | 24679764 | 2 days ago | IN | 0 ETH | 0.00006925 | ||||
| Update Assets | 24678869 | 2 days ago | IN | 0 ETH | 0.00006938 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
PnLFundCoreDualStable
Compiler Version
v0.8.31+commit.fd3a2265
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "./PnLToken.sol";
import "./PnLInvestorManager.sol";
/**
* @title PnLFundCoreDualStable
* @notice Fund core contract with support for two stablecoins (USDT and USDC)
*/
contract PnLFundCoreDualStable is Ownable, ReentrancyGuard, Pausable {
using SafeERC20 for IERC20;
struct WithdrawalRequest {
address user;
uint256 pnlAmount;
address requestedCurrency;
uint32 timestamp;
uint8 status; // 0: pending, 1: approved, 2: completed, 3: cancelled, 4: expired
uint32 approvedTimestamp;
uint256 payoutAmount;
}
uint256 public constant REQUEST_TIMEOUT = 24 hours;
address public immutable stablecoin1; // USDT
address public immutable stablecoin2; // USDC
address public tradeWallet;
PnLToken public pnlToken;
PnLInvestorManager public investorManager;
uint256 public totalAssets;
bool public isInitialized;
WithdrawalRequest[] public withdrawalRequests;
mapping(address => uint256[]) public userWithdrawalRequests;
event FundInitialized(uint256 initialAssets, uint256 timestamp);
event AssetsUpdated(uint256 newAssets, uint256 timestamp);
event Deposit(address indexed user, address currency, uint256 amount, uint256 pnlAmount, uint256 timestamp);
event WithdrawalRequestCreated(uint256 indexed requestId, address indexed user, uint256 pnlAmount, address currency, uint256 timestamp);
event WithdrawalRequestApproved(uint256 indexed requestId, address indexed user, uint256 timestamp);
event WithdrawalRequestCompleted(uint256 indexed requestId, address indexed user, uint256 pnlAmount, address currency, uint256 payoutAmount, uint256 timestamp);
event WithdrawalRequestCancelled(uint256 indexed requestId, address indexed user, uint256 timestamp);
event WithdrawalRequestExpired(uint256 indexed requestId, address indexed user, uint256 timestamp);
event ContractFunded(address indexed funder, address currency, uint256 amount, uint256 timestamp);
event NAVUpdated(uint256 totalNAV, uint256 totalSupplyPNL, uint256 rate, uint256 timestamp);
event PerformanceFeeDistributed(address indexed investor, uint256 timestamp);
event TradeWalletUpdated(address indexed oldWallet, address indexed newWallet, uint256 timestamp);
event FundPaused(address indexed by, uint256 timestamp);
event FundUnpaused(address indexed by, uint256 timestamp);
modifier onlyInitialized() {
require(isInitialized, "Fund not initialized");
_;
}
modifier validStablecoin(address token) {
require(token == stablecoin1 || token == stablecoin2, "Invalid stablecoin");
_;
}
constructor(
address _stablecoin1,
address _stablecoin2,
address _tradeWallet,
address _pnlTokenAddress,
address _investorManager,
address initialOwner
) Ownable(initialOwner) {
require(
_stablecoin1 != address(0) &&
_stablecoin2 != address(0) &&
_tradeWallet != address(0) &&
_pnlTokenAddress != address(0) &&
_investorManager != address(0) &&
initialOwner != address(0),
"Invalid address"
);
require(_stablecoin1 != _stablecoin2, "Stablecoins must be different");
stablecoin1 = _stablecoin1;
stablecoin2 = _stablecoin2;
tradeWallet = _tradeWallet;
pnlToken = PnLToken(_pnlTokenAddress);
investorManager = PnLInvestorManager(_investorManager);
isInitialized = false;
}
function initializeFund(uint256 initialAssets) external onlyOwner {
require(!isInitialized, "Already initialized");
totalAssets = initialAssets;
isInitialized = true;
if (initialAssets > 0) {
uint256 pnlToMint = initialAssets * 1e12; // 6 decimals -> 18 decimals
if (pnlToMint > 0) {
pnlToken.mint(owner(), pnlToMint);
}
}
emit FundInitialized(initialAssets, block.timestamp);
emit NAVUpdated(getTotalNAV(), pnlToken.totalSupply(), getCurrentRate(), block.timestamp);
}
function pause() external onlyOwner {
_pause();
emit FundPaused(msg.sender, block.timestamp);
}
function unpause() external onlyOwner {
_unpause();
emit FundUnpaused(msg.sender, block.timestamp);
}
function updateTradeWallet(address newTradeWallet) external onlyOwner {
require(newTradeWallet != address(0), "Invalid trade wallet address");
require(newTradeWallet != tradeWallet, "Same address");
address oldWallet = tradeWallet;
tradeWallet = newTradeWallet;
emit TradeWalletUpdated(oldWallet, newTradeWallet, block.timestamp);
}
function deposit(address token, uint256 amount)
external
nonReentrant
onlyInitialized
whenNotPaused
validStablecoin(token)
{
require(amount > 0, "Invalid deposit amount");
uint256 pnlAmount = calculatePNLForDeposit(amount);
require(pnlAmount > 0, "PNL amount too small");
IERC20(token).safeTransferFrom(msg.sender, tradeWallet, amount);
totalAssets += amount;
pnlToken.mint(msg.sender, pnlAmount);
uint256 userTotalValue = (pnlToken.balanceOf(msg.sender) * getCurrentRate()) / 1e18;
investorManager.recordDeposit(msg.sender, amount, userTotalValue);
emit Deposit(msg.sender, token, amount, pnlAmount, block.timestamp);
emit NAVUpdated(getTotalNAV(), pnlToken.totalSupply(), getCurrentRate(), block.timestamp);
}
function requestWithdrawal(uint256 pnlAmount, address currency)
external
nonReentrant
onlyInitialized
whenNotPaused
validStablecoin(currency)
{
require(pnlAmount > 0, "Invalid withdrawal amount");
require(pnlToken.balanceOf(msg.sender) >= pnlAmount, "Insufficient PNL balance");
pnlToken.burn(msg.sender, pnlAmount);
uint256 requestId = withdrawalRequests.length;
withdrawalRequests.push(WithdrawalRequest({
user: msg.sender,
pnlAmount: pnlAmount,
requestedCurrency: currency,
timestamp: uint32(block.timestamp),
status: 0,
approvedTimestamp: 0,
payoutAmount: 0
}));
userWithdrawalRequests[msg.sender].push(requestId);
emit WithdrawalRequestCreated(requestId, msg.sender, pnlAmount, currency, block.timestamp);
}
function cancelWithdrawal(uint256 requestId)
external
nonReentrant
onlyInitialized
whenNotPaused
{
require(requestId < withdrawalRequests.length, "Invalid request ID");
WithdrawalRequest storage request = withdrawalRequests[requestId];
require(request.user == msg.sender, "Not your request");
require(request.status == 0, "Cannot cancel");
pnlToken.mint(msg.sender, request.pnlAmount);
request.status = 3;
emit WithdrawalRequestCancelled(requestId, msg.sender, block.timestamp);
}
function approveWithdrawal(uint256 requestId)
external
onlyOwner
onlyInitialized
whenNotPaused
{
require(requestId < withdrawalRequests.length, "Invalid request ID");
WithdrawalRequest storage request = withdrawalRequests[requestId];
require(request.status == 0, "Request not pending");
if (block.timestamp > request.timestamp + REQUEST_TIMEOUT) {
request.status = 4;
pnlToken.mint(request.user, request.pnlAmount);
emit WithdrawalRequestExpired(requestId, request.user, block.timestamp);
return;
}
uint256 payoutAmount = (request.pnlAmount * getCurrentRate()) / 1e18;
require(payoutAmount > 0, "Payout amount too small");
request.status = 1;
request.approvedTimestamp = uint32(block.timestamp);
request.payoutAmount = payoutAmount;
emit WithdrawalRequestApproved(requestId, request.user, block.timestamp);
}
function claimExpiredWithdrawal(uint256 requestId)
external
nonReentrant
onlyInitialized
whenNotPaused
{
require(requestId < withdrawalRequests.length, "Invalid request ID");
WithdrawalRequest storage request = withdrawalRequests[requestId];
require(request.user == msg.sender, "Not your request");
require(request.status == 0, "Request not pending");
require(block.timestamp > request.timestamp + REQUEST_TIMEOUT, "Not expired yet");
request.status = 4;
pnlToken.mint(msg.sender, request.pnlAmount);
emit WithdrawalRequestExpired(requestId, msg.sender, block.timestamp);
}
function completeWithdrawal(uint256 requestId)
external
onlyOwner
nonReentrant
onlyInitialized
whenNotPaused
{
require(requestId < withdrawalRequests.length, "Invalid request ID");
WithdrawalRequest storage request = withdrawalRequests[requestId];
require(request.status == 1, "Request not approved");
uint256 payoutAmount = request.payoutAmount;
require(payoutAmount > 0, "Payout amount too small");
// Check contract has sufficient balance of requested currency
require(
IERC20(request.requestedCurrency).balanceOf(address(this)) >= payoutAmount,
"Insufficient contract balance"
);
totalAssets -= payoutAmount;
// Adjust high water mark if user still has PNL tokens
uint256 totalPnlBalance = pnlToken.balanceOf(request.user);
if (totalPnlBalance > 0) {
uint256 withdrawalPercentageX100 = (request.pnlAmount * 10000) / (totalPnlBalance + request.pnlAmount);
investorManager.adjustHighWaterMarkOnWithdrawal(request.user, withdrawalPercentageX100);
}
IERC20(request.requestedCurrency).safeTransfer(request.user, payoutAmount);
request.status = 2;
emit WithdrawalRequestCompleted(
requestId,
request.user,
request.pnlAmount,
request.requestedCurrency,
payoutAmount,
block.timestamp
);
emit NAVUpdated(getTotalNAV(), pnlToken.totalSupply(), getCurrentRate(), block.timestamp);
}
function updateAssets(uint256 newAssets) external onlyOwner onlyInitialized {
totalAssets = newAssets;
emit AssetsUpdated(newAssets, block.timestamp);
emit NAVUpdated(getTotalNAV(), pnlToken.totalSupply(), getCurrentRate(), block.timestamp);
}
function fundContract(address token, uint256 amount)
external
onlyOwner
onlyInitialized
validStablecoin(token)
{
require(amount > 0, "Invalid funding amount");
IERC20(token).safeTransferFrom(msg.sender, address(this), amount);
emit ContractFunded(msg.sender, token, amount, block.timestamp);
}
function distributePerformanceFee(address investor)
external
onlyOwner
onlyInitialized
whenNotPaused
{
require(investor != address(0), "Invalid investor");
require(investorManager.isInvestorActive(investor), "Investor not active");
uint256 pnlBalance = pnlToken.balanceOf(investor);
require(pnlBalance > 0, "No PNL tokens");
uint256 currentRate = getCurrentRate();
require(currentRate > 0, "Invalid rate");
uint256 currentValue = (pnlBalance * currentRate) / 1e18;
investorManager.collectPerformanceFee(investor, currentValue, currentRate);
emit PerformanceFeeDistributed(investor, block.timestamp);
emit NAVUpdated(getTotalNAV(), pnlToken.totalSupply(), getCurrentRate(), block.timestamp);
}
function getTotalNAV() public view returns (uint256) {
return totalAssets;
}
function getCurrentRate() public view returns (uint256) {
uint256 totalSupply = pnlToken.totalSupply();
uint256 totalNAV = getTotalNAV();
if (totalSupply == 0 || totalNAV == 0) {
// Initial rate: 1 PNL = 1 USD (with proper decimals)
// PNL has 18 decimals, stablecoins have 6 decimals
return 1e6; // 1 USD in 6 decimal format, scaled to 18 decimal rate
}
// Rate = (totalNAV * 1e18) / totalSupply
// totalNAV is in 6 decimals, totalSupply is in 18 decimals
// Result is in 6 decimals (stablecoin units per PNL token)
return (totalNAV * 1e18) / totalSupply;
}
/**
* @notice Calculate PNL tokens to mint for deposit
* @param amount Amount of stablecoins deposited (6 decimals)
* @return Amount of PNL tokens to mint (18 decimals)
*/
function calculatePNLForDeposit(uint256 amount) public view returns (uint256) {
uint256 totalSupply = pnlToken.totalSupply();
uint256 totalNAV = getTotalNAV();
if (totalSupply == 0 || totalNAV == 0) {
// Initial deposit: 1 USD = 1e12 PNL tokens (6 decimals -> 18 decimals)
return amount * 1e12;
}
// pnlAmount = (amount * totalSupply) / totalNAV
return (amount * totalSupply) / totalNAV;
}
/**
* @notice Get contract balance of specific stablecoin
* @param token Stablecoin address
* @return Balance of the token
*/
function getContractBalance(address token) external view validStablecoin(token) returns (uint256) {
return IERC20(token).balanceOf(address(this));
}
/**
* @notice Get user's withdrawal request IDs
* @param user Address of the user
* @return Array of request IDs
*/
function getUserWithdrawalRequests(address user) external view returns (uint256[] memory) {
return userWithdrawalRequests[user];
}
/**
* @notice Get total number of withdrawal requests
* @return Total count
*/
function getWithdrawalRequestsCount() external view returns (uint256) {
return withdrawalRequests.length;
}
/**
* @notice Get withdrawal request details
* @param requestId ID of the request
* @return Withdrawal request struct
*/
function getWithdrawalRequest(uint256 requestId) external view returns (WithdrawalRequest memory) {
require(requestId < withdrawalRequests.length, "Invalid request ID");
return withdrawalRequests[requestId];
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./PnLToken.sol";
contract PnLInvestorManager is Ownable {
struct InvestorInfo {
uint16 successFeePercentage;
uint32 lastCalculationDate;
uint256 totalSuccessFeeEarned;
uint256 totalDeposited;
uint256 highWaterMark;
bool isActive;
uint32 joinedDate;
}
// --- СОСТОЯНИЕ ---
address public fundCoreAddress;
address public pnlTokenAddress;
// Хранилища инвесторов
mapping(address => InvestorInfo) public investorInfo;
address[] public activeInvestors;
// --- СОБЫТИЯ ---
event InvestorRegistered(address indexed investor, uint256 successFeePercentage, uint256 timestamp);
event InvestorDeactivated(address indexed investor, uint256 timestamp);
event SuccessFeeCollected(address indexed investor, uint256 feeAmount, uint256 feeTokens, uint256 newHWM, uint256 timestamp);
event HighWaterMarkUpdated(address indexed investor, uint256 oldHWM, uint256 newHWM, string reason);
event SuccessFeePercentageUpdated(address indexed investor, uint16 oldPercentage, uint16 newPercentage);
// --- МОДИФИКАТОРЫ ---
modifier onlyFundCore() {
require(msg.sender == fundCoreAddress, "Only fund core can call");
_;
}
// --- КОНСТРУКТОР ---
constructor(address initialOwner) Ownable(initialOwner) {
require(initialOwner != address(0), "Invalid owner address");
}
function setContractAddresses(address _fundCore, address _pnlToken) external onlyOwner {
require(_fundCore != address(0) && _pnlToken != address(0), "Invalid addresses");
require(fundCoreAddress == address(0), "Already initialized");
fundCoreAddress = _fundCore;
pnlTokenAddress = _pnlToken;
}
function registerInvestor(
address investor,
uint16 successFeePercentage
) external onlyOwner {
require(investor != address(0), "Invalid investor address");
require(successFeePercentage <= 5000, "Fee cannot exceed 50%");
require(!investorInfo[investor].isActive, "Investor already registered");
investorInfo[investor] = InvestorInfo({
successFeePercentage: successFeePercentage,
lastCalculationDate: 0,
totalSuccessFeeEarned: 0,
totalDeposited: 0,
highWaterMark: 0,
isActive: true,
joinedDate: uint32(block.timestamp)
});
activeInvestors.push(investor);
emit InvestorRegistered(investor, successFeePercentage, block.timestamp);
}
function updateInvestorSuccessFee(address investor, uint16 newFee) external onlyOwner {
require(investorInfo[investor].isActive, "Investor not active");
require(newFee <= 5000, "Fee too high");
uint16 oldFee = investorInfo[investor].successFeePercentage;
investorInfo[investor].successFeePercentage = newFee;
emit SuccessFeePercentageUpdated(investor, oldFee, newFee);
}
function deactivateInvestor(address investor) external onlyOwner {
require(investorInfo[investor].isActive, "Investor not active");
investorInfo[investor].isActive = false;
emit InvestorDeactivated(investor, block.timestamp);
}
function recordDeposit(
address investor,
uint256 depositAmount,
uint256 totalValue
) external onlyFundCore {
require(investorInfo[investor].isActive, "Investor not active");
InvestorInfo storage info = investorInfo[investor];
// Обновляем общую сумму депозитов
info.totalDeposited += depositAmount;
// HWM Logic: Если текущая стоимость выше HWM, поднимаем планку
if (totalValue > info.highWaterMark) {
uint256 oldHWM = info.highWaterMark;
info.highWaterMark = totalValue;
emit HighWaterMarkUpdated(investor, oldHWM, totalValue, "Deposit");
}
}
function adjustHighWaterMarkOnWithdrawal(
address investor,
uint256 withdrawalPercentageX100
) external onlyFundCore {
require(investorInfo[investor].isActive, "Investor not active");
require(withdrawalPercentageX100 <= 10000, "Invalid percentage");
InvestorInfo storage info = investorInfo[investor];
uint256 currentHWM = info.highWaterMark;
if (currentHWM == 0) return;
// Уменьшаем HWM пропорционально выведенной части
uint256 reduction = (currentHWM * withdrawalPercentageX100) / 10000;
uint256 newHWM = currentHWM - reduction;
info.highWaterMark = newHWM;
emit HighWaterMarkUpdated(investor, currentHWM, newHWM, "Withdrawal");
}
function collectPerformanceFee(
address investor,
uint256 currentTotalValue,
uint256 currentRate
) external onlyFundCore {
InvestorInfo storage info = investorInfo[investor];
require(info.isActive, "Investor not active");
require(currentRate > 0, "Invalid rate");
uint256 hwm = info.highWaterMark;
// Комиссия берется только с прибыли, превышающей HWM
if (currentTotalValue > hwm) {
uint256 profit = currentTotalValue - hwm;
uint256 feeAmount = (profit * info.successFeePercentage) / 10000;
if (feeAmount > 0) {
// Конвертируем комиссию в токены PnL и минтим оператору (Owner)
uint256 feeTokens = (feeAmount * 1e18) / currentRate;
if (feeTokens > 0) {
PnLToken(pnlTokenAddress).mint(owner(), feeTokens);
info.totalSuccessFeeEarned += feeAmount;
info.lastCalculationDate = uint32(block.timestamp);
// Поднимаем HWM до текущей стоимости
// Теперь эта прибыль "облагается" только один раз
info.highWaterMark = currentTotalValue;
emit SuccessFeeCollected(investor, feeAmount, feeTokens, currentTotalValue, block.timestamp);
}
}
}
}
function getInvestorInfo(address investor) external view returns (
uint16 successFeePercentage,
uint256 totalDeposited,
uint256 highWaterMark,
bool isActive,
uint256 lastCalculationDate,
uint256 totalSuccessFeeEarned
) {
InvestorInfo memory info = investorInfo[investor];
return (
info.successFeePercentage,
info.totalDeposited,
info.highWaterMark,
info.isActive,
info.lastCalculationDate,
info.totalSuccessFeeEarned
);
}
function getActiveInvestors() external view returns (address[] memory) {
return activeInvestors;
}
function isInvestorActive(address investor) external view returns (bool) {
return investorInfo[investor].isActive;
}
function getActiveInvestorCount() external view returns (uint256) {
uint256 count = 0;
for (uint256 i = 0; i < activeInvestors.length; i++) {
if (investorInfo[activeInvestors[i]].isActive) {
count++;
}
}
return count;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract PnLToken is ERC20, ERC20Burnable, Ownable {
mapping(address => bool) public authorizedMinters;
event MinterAuthorized(address indexed minter);
event MinterRevoked(address indexed minter);
constructor(
string memory name,
string memory symbol,
address initialOwner
)
ERC20(name, symbol)
Ownable(initialOwner)
{
require(initialOwner != address(0), "Invalid owner address");
}
function authorizeMinter(address minter) external onlyOwner {
require(minter != address(0), "Invalid minter address");
require(!authorizedMinters[minter], "Already authorized");
authorizedMinters[minter] = true;
emit MinterAuthorized(minter);
}
function revokeMinter(address minter) external onlyOwner {
require(authorizedMinters[minter], "Not authorized");
authorizedMinters[minter] = false;
emit MinterRevoked(minter);
}
function mint(address to, uint256 amount) external {
require(authorizedMinters[msg.sender], "PnLToken: Not authorized to mint");
require(to != address(0), "Cannot mint to zero address");
require(amount > 0, "Amount must be greater than 0");
_mint(to, amount);
}
function burn(address from, uint256 amount) external {
require(
authorizedMinters[msg.sender] || msg.sender == from,
"PnLToken: Not authorized to burn"
);
require(amount > 0, "Amount must be greater than 0");
_burn(from, amount);
}
function isAuthorizedMinter(address minter) external view returns (bool) {
return authorizedMinters[minter];
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
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
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (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.3.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol)
pragma solidity ^0.8.20;
import {ERC20} from "../ERC20.sol";
import {Context} from "../../../utils/Context.sol";
/**
* @dev Extension of {ERC20} that allows token holders to destroy both their own
* tokens and those that they have an allowance for, in a way that can be
* recognized off-chain (via event analysis).
*/
abstract contract ERC20Burnable is Context, ERC20 {
/**
* @dev Destroys a `value` amount of tokens from the caller.
*
* See {ERC20-_burn}.
*/
function burn(uint256 value) public virtual {
_burn(_msgSender(), value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, deducting from
* the caller's allowance.
*
* See {ERC20-_burn} and {ERC20-allowance}.
*
* Requirements:
*
* - the caller must have allowance for ``accounts``'s tokens of at least
* `value`.
*/
function burnFrom(address account, uint256 value) public virtual {
_spendAllowance(account, _msgSender(), value);
_burn(account, value);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC-20
* applications.
*/
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
mapping(address account => uint256) private _balances;
mapping(address account => mapping(address spender => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* Both values are immutable: they can only be set once during construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return 18;
}
/// @inheritdoc IERC20
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
/// @inheritdoc IERC20
function balanceOf(address account) public view virtual returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `value`.
*/
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/// @inheritdoc IERC20
function allowance(address owner, address spender) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Skips emitting an {Approval} event indicating an allowance update. This is not
* required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `value`.
* - the caller must have allowance for ``from``'s tokens of at least
* `value`.
*/
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
/**
* @dev Moves a `value` amount of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
/**
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
* this function.
*
* Emits a {Transfer} event.
*/
function _update(address from, address to, uint256 value) internal virtual {
if (from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
_totalSupply += value;
} else {
uint256 fromBalance = _balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
_balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
_totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
_balances[to] += value;
}
}
emit Transfer(from, to, value);
}
/**
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
* Relies on the `_update` mechanism
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
* Relies on the `_update` mechanism.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead
*/
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
/**
* @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
/**
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
*
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
* `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
* `Approval` event during `transferFrom` operations.
*
* Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
* true using the following override:
*
* ```solidity
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
* super._approve(owner, spender, value, true);
* }
* ```
*
* Requirements are the same as {_approve}.
*/
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
_allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
/**
* @dev Updates `owner`'s allowance for `spender` based on spent `value`.
*
* Does not update the allowance value in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Does not emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance < type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}// 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.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/draft-IERC6093.sol)
pragma solidity >=0.8.4;
/**
* @dev Standard ERC-20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC-721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC-1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity >=0.6.2;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC-20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.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);
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_stablecoin1","type":"address"},{"internalType":"address","name":"_stablecoin2","type":"address"},{"internalType":"address","name":"_tradeWallet","type":"address"},{"internalType":"address","name":"_pnlTokenAddress","type":"address"},{"internalType":"address","name":"_investorManager","type":"address"},{"internalType":"address","name":"initialOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newAssets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"AssetsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"funder","type":"address"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"ContractFunded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pnlAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"initialAssets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"FundInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"by","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"FundPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"by","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"FundUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalNAV","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalSupplyPNL","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"NAVUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"investor","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"PerformanceFeeDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldWallet","type":"address"},{"indexed":true,"internalType":"address","name":"newWallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"TradeWalletUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WithdrawalRequestApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WithdrawalRequestCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"pnlAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"uint256","name":"payoutAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WithdrawalRequestCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"pnlAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WithdrawalRequestCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WithdrawalRequestExpired","type":"event"},{"inputs":[],"name":"REQUEST_TIMEOUT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"approveWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calculatePNLForDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"cancelWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"claimExpiredWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"completeWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"investor","type":"address"}],"name":"distributePerformanceFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"fundContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getContractBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalNAV","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserWithdrawalRequests","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"getWithdrawalRequest","outputs":[{"components":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"pnlAmount","type":"uint256"},{"internalType":"address","name":"requestedCurrency","type":"address"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"uint32","name":"approvedTimestamp","type":"uint32"},{"internalType":"uint256","name":"payoutAmount","type":"uint256"}],"internalType":"struct PnLFundCoreDualStable.WithdrawalRequest","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawalRequestsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"initialAssets","type":"uint256"}],"name":"initializeFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"investorManager","outputs":[{"internalType":"contract PnLInvestorManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pnlToken","outputs":[{"internalType":"contract PnLToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pnlAmount","type":"uint256"},{"internalType":"address","name":"currency","type":"address"}],"name":"requestWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stablecoin1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stablecoin2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newAssets","type":"uint256"}],"name":"updateAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTradeWallet","type":"address"}],"name":"updateTradeWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userWithdrawalRequests","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdrawalRequests","outputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"pnlAmount","type":"uint256"},{"internalType":"address","name":"requestedCurrency","type":"address"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"uint32","name":"approvedTimestamp","type":"uint32"},{"internalType":"uint256","name":"payoutAmount","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60c060405234801561000f575f5ffd5b5060405161549438038061549483398181016040528101906100319190610533565b805f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100a2575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161009991906105cb565b60405180910390fd5b6100b18161041460201b60201c565b50600180819055505f60025f6101000a81548160ff0219169083151502179055505f73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561013a57505f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b801561017257505f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614155b80156101aa57505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b80156101e257505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561021a57505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b610259576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102509061063e565b60405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16036102c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102be906106a6565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250508473ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff168152505083600260016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508260035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505f60065f6101000a81548160ff0219169083151502179055505050505050506106c4565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610502826104d9565b9050919050565b610512816104f8565b811461051c575f5ffd5b50565b5f8151905061052d81610509565b92915050565b5f5f5f5f5f5f60c0878903121561054d5761054c6104d5565b5b5f61055a89828a0161051f565b965050602061056b89828a0161051f565b955050604061057c89828a0161051f565b945050606061058d89828a0161051f565b935050608061059e89828a0161051f565b92505060a06105af89828a0161051f565b9150509295509295509295565b6105c5816104f8565b82525050565b5f6020820190506105de5f8301846105bc565b92915050565b5f82825260208201905092915050565b7f496e76616c6964206164647265737300000000000000000000000000000000005f82015250565b5f610628600f836105e4565b9150610633826105f4565b602082019050919050565b5f6020820190508181035f8301526106558161061c565b9050919050565b7f537461626c65636f696e73206d75737420626520646966666572656e740000005f82015250565b5f610690601d836105e4565b915061069b8261065c565b602082019050919050565b5f6020820190508181035f8301526106bd81610684565b9050919050565b60805160a051614d7761071d5f395f818161096c015281816111e30152818161138f015281816115520152612fe401525f81816109170152818161118e0152818161133a015281816114fd0152612c720152614d775ff3fe608060405234801561000f575f5ffd5b5060043610610204575f3560e01c80638456cb5911610118578063b40c1b78116100ab578063d4fe21951161007a578063d4fe21951461057e578063e36675251461059c578063f2fde38b146105cc578063f3917d79146105e8578063f7fb07b01461060457610204565b8063b40c1b781461050a578063b9b83d3914610528578063bc2c81e914610544578063c696f4da1461056257610204565b8063a128c591116100e7578063a128c59114610470578063a4072b7f1461048e578063a471e547146104aa578063ae485651146104da57610204565b80638456cb59146103f65780638da5cb5b14610400578063937b25811461041e5780639eceddea1461045457610204565b806342e02fb41161019b5780635c38d22e1161016a5780635c38d22e146103625780635c975abb146103805780636c9302281461039e578063715018a6146103ce578063808f0a7c146103d857610204565b806342e02fb4146102de57806343ab265f146102fa57806347e7ef241461032a5780634f0cb5f31461034657610204565b806321739779116101d7578063217397791461027e578063392e53cd1461029a5780633efcfda4146102b85780633f4ba83a146102d457610204565b806301e1d11414610208578063037cff4614610226578063130a8292146102445780631942811114610262575b5f5ffd5b610210610622565b60405161021d9190613a97565b60405180910390f35b61022e610628565b60405161023b9190613b2a565b60405180910390f35b61024c61064d565b6040516102599190613b63565b60405180910390f35b61027c60048036038101906102779190613baa565b610673565b005b61029860048036038101906102939190613bff565b6108b6565b005b6102a2610e0f565b6040516102af9190613c57565b60405180910390f35b6102d260048036038101906102cd9190613baa565b610e21565b005b6102dc6110d5565b005b6102f860048036038101906102f39190613c70565b611135565b005b610314600480360381019061030f9190613cae565b611336565b6040516103219190613a97565b60405180910390f35b610344600480360381019061033f9190613c70565b61149c565b005b610360600480360381019061035b9190613baa565b6119e6565b005b61036a612000565b6040516103779190613a97565b60405180910390f35b61038861200c565b6040516103959190613c57565b60405180910390f35b6103b860048036038101906103b39190613cae565b612021565b6040516103c59190613d90565b60405180910390f35b6103d66120b4565b005b6103e06120c7565b6040516103ed9190613dd0565b60405180910390f35b6103fe6120ec565b005b61040861214c565b6040516104159190613b63565b60405180910390f35b61043860048036038101906104339190613baa565b612173565b60405161044b9796959493929190613e22565b60405180910390f35b61046e60048036038101906104699190613baa565b61222b565b005b6104786125ed565b6040516104859190613a97565b60405180910390f35b6104a860048036038101906104a39190613cae565b6125f6565b005b6104c460048036038101906104bf9190613c70565b612a9e565b6040516104d19190613a97565b60405180910390f35b6104f460048036038101906104ef9190613baa565b612ac9565b6040516105019190613f48565b60405180910390f35b610512612c70565b60405161051f9190613b63565b60405180910390f35b610542600480360381019061053d9190613baa565b612c94565b005b61054c612e05565b6040516105599190613a97565b60405180910390f35b61057c60048036038101906105779190613cae565b612e0c565b005b610586612fe2565b6040516105939190613b63565b60405180910390f35b6105b660048036038101906105b19190613baa565b613006565b6040516105c39190613a97565b60405180910390f35b6105e660048036038101906105e19190613cae565b6130f0565b005b61060260048036038101906105fd9190613baa565b613174565b005b61060c613492565b6040516106199190613a97565b60405180910390f35b60055481565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61067b613575565b60065f9054906101000a900460ff16156106ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c190613fbb565b60405180910390fd5b80600581905550600160065f6101000a81548160ff0219169083151502179055505f8111156107a2575f64e8d4a51000826107059190614006565b90505f8111156107a05760035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1961075461214c565b836040518363ffffffff1660e01b8152600401610772929190614047565b5f604051808303815f87803b158015610789575f5ffd5b505af115801561079b573d5f5f3e3d5ffd5b505050505b505b7f37d36da36de67b5a5c7adfc8ce80c29e2e220878ad7cfc48d23df0ca7197f49581426040516107d392919061406e565b60405180910390a17fe1e035f75f94e0038561eaa98c5e73b5dabc517ceee7892f8b3b9e5d92084ee36108046125ed565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561086e573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061089291906140a9565b61089a613492565b426040516108ab94939291906140d4565b60405180910390a150565b6108be6135fc565b60065f9054906101000a900460ff1661090c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090390614161565b60405180910390fd5b61091461364b565b807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806109ba57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b6109f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f0906141c9565b60405180910390fd5b5f8311610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3290614231565b60405180910390fd5b8260035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401610a969190613b63565b602060405180830381865afa158015610ab1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad591906140a9565b1015610b16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0d90614299565b60405180910390fd5b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dc29fac33856040518363ffffffff1660e01b8152600401610b72929190614047565b5f604051808303815f87803b158015610b89575f5ffd5b505af1158015610b9b573d5f5f3e3d5ffd5b505050505f600780549050905060076040518060e001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020014263ffffffff1681526020015f60ff1681526020015f63ffffffff1681526020015f815250908060018154018082558091505060019003905f5260205f2090600402015f909190919091505f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160146101000a81548163ffffffff021916908363ffffffff16021790555060808201518160020160186101000a81548160ff021916908360ff16021790555060a08201518160020160196101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160030155505060085f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081908060018154018082558091505060019003905f5260205f20015f90919091909150553373ffffffffffffffffffffffffffffffffffffffff16817f3aa0147eff4ace81f26e95a29e29f25bb9509b6bd6e3002879a1a71a5c29e1ad868642604051610df9939291906142b7565b60405180910390a35050610e0b613695565b5050565b60065f9054906101000a900460ff1681565b610e296135fc565b60065f9054906101000a900460ff16610e77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6e90614161565b60405180910390fd5b610e7f61364b565b6007805490508110610ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebd90614336565b60405180910390fd5b5f60078281548110610edb57610eda614354565b5b905f5260205f20906004020190503373ffffffffffffffffffffffffffffffffffffffff16815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610f79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f70906143cb565b60405180910390fd5b5f8160020160189054906101000a900460ff1660ff1614610fcf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fc690614433565b60405180910390fd5b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f193383600101546040518363ffffffff1660e01b815260040161102f929190614047565b5f604051808303815f87803b158015611046575f5ffd5b505af1158015611058573d5f5f3e3d5ffd5b5050505060038160020160186101000a81548160ff021916908360ff1602179055503373ffffffffffffffffffffffffffffffffffffffff16827faf28bc105571d58bdc8db31b07d28b142526b699802713e96ad9f7dca963474f426040516110c19190613a97565b60405180910390a3506110d2613695565b50565b6110dd613575565b6110e561369e565b3373ffffffffffffffffffffffffffffffffffffffff167f66213c89ece0bf063cc20061fbda1c3c1bde502eaaee2f4e96dd3c11dec0856c4260405161112b9190613a97565b60405180910390a2565b61113d613575565b60065f9054906101000a900460ff1661118b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118290614161565b60405180910390fd5b817f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061123157507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611270576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611267906141c9565b60405180910390fd5b5f82116112b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a99061449b565b60405180910390fd5b6112df3330848673ffffffffffffffffffffffffffffffffffffffff166136ff909392919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167fa37175a3415c4ec48c1ba6d18e2b563b5e88acf3b470b83ab91fa9eb741895f1848442604051611329939291906144b9565b60405180910390a2505050565b5f817f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806113dd57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b61141c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611413906141c9565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016114559190613b63565b602060405180830381865afa158015611470573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061149491906140a9565b915050919050565b6114a46135fc565b60065f9054906101000a900460ff166114f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e990614161565b60405180910390fd5b6114fa61364b565b817f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806115a057507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b6115df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115d6906141c9565b60405180910390fd5b5f8211611621576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161890614538565b60405180910390fd5b5f61162b83613006565b90505f811161166f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611666906145a0565b60405180910390fd5b6116be33600260019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16858773ffffffffffffffffffffffffffffffffffffffff166136ff909392919063ffffffff16565b8260055f8282546116cf91906145be565b9250508190555060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1933836040518363ffffffff1660e01b8152600401611732929190614047565b5f604051808303815f87803b158015611749575f5ffd5b505af115801561175b573d5f5f3e3d5ffd5b505050505f670de0b6b3a7640000611771613492565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016117cb9190613b63565b602060405180830381865afa1580156117e6573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061180a91906140a9565b6118149190614006565b61181e919061461e565b905060045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c68ba54c3386846040518463ffffffff1660e01b815260040161187e939291906144b9565b5f604051808303815f87803b158015611895575f5ffd5b505af11580156118a7573d5f5f3e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f6868685426040516118f7949392919061464e565b60405180910390a27fe1e035f75f94e0038561eaa98c5e73b5dabc517ceee7892f8b3b9e5d92084ee36119286125ed565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611992573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119b691906140a9565b6119be613492565b426040516119cf94939291906140d4565b60405180910390a15050506119e2613695565b5050565b6119ee613575565b6119f66135fc565b60065f9054906101000a900460ff16611a44576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3b90614161565b60405180910390fd5b611a4c61364b565b6007805490508110611a93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8a90614336565b60405180910390fd5b5f60078281548110611aa857611aa7614354565b5b905f5260205f209060040201905060018160020160189054906101000a900460ff1660ff1614611b0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b04906146db565b60405180910390fd5b5f816003015490505f8111611b57576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4e90614743565b60405180910390fd5b80826002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611bb49190613b63565b602060405180830381865afa158015611bcf573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bf391906140a9565b1015611c34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2b906147ab565b60405180910390fd5b8060055f828254611c4591906147c9565b925050819055505f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231845f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401611cc99190613b63565b602060405180830381865afa158015611ce4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d0891906140a9565b90505f811115611dee575f836001015482611d2391906145be565b6127108560010154611d359190614006565b611d3f919061461e565b905060045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663014d1d8d855f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401611dbf929190614047565b5f604051808303815f87803b158015611dd6575f5ffd5b505af1158015611de8573d5f5f3e3d5ffd5b50505050505b611e5e835f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683856002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137819092919063ffffffff16565b60028360020160186101000a81548160ff021916908360ff160217905550825f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16847f7d2bc9c190a026adb94946f747f545b2862f770335771262341c274e22924fb18560010154866002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff168642604051611f1294939291906147fc565b60405180910390a37fe1e035f75f94e0038561eaa98c5e73b5dabc517ceee7892f8b3b9e5d92084ee3611f436125ed565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fad573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fd191906140a9565b611fd9613492565b42604051611fea94939291906140d4565b60405180910390a1505050611ffd613695565b50565b5f600780549050905090565b5f60025f9054906101000a900460ff16905090565b606060085f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208054806020026020016040519081016040528092919081815260200182805480156120a857602002820191905f5260205f20905b815481526020019060010190808311612094575b50505050509050919050565b6120bc613575565b6120c55f613800565b565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6120f4613575565b6120fc6138c1565b3373ffffffffffffffffffffffffffffffffffffffff167f0248a1bee6b2ebe08af6245feaa774395a357b52ee147682094c1eea17168826426040516121429190613a97565b60405180910390a2565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60078181548110612182575f80fd5b905f5260205f2090600402015f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015490806002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020160149054906101000a900463ffffffff16908060020160189054906101000a900460ff16908060020160199054906101000a900463ffffffff16908060030154905087565b612233613575565b60065f9054906101000a900460ff16612281576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161227890614161565b60405180910390fd5b61228961364b565b60078054905081106122d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c790614336565b60405180910390fd5b5f600782815481106122e5576122e4614354565b5b905f5260205f20906004020190505f8160020160189054906101000a900460ff1660ff1614612349576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161234090614889565b60405180910390fd5b620151808160020160149054906101000a900463ffffffff1663ffffffff1661237291906145be565b4211156124bd5760048160020160186101000a81548160ff021916908360ff16021790555060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f19825f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683600101546040518363ffffffff1660e01b8152600401612419929190614047565b5f604051808303815f87803b158015612430575f5ffd5b505af1158015612442573d5f5f3e3d5ffd5b50505050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16827fdc208055b8c07aad9143ab5ad8f1518ec881df3039290c46be87c861e00484b8426040516124af9190613a97565b60405180910390a3506125ea565b5f670de0b6b3a76400006124cf613492565b83600101546124de9190614006565b6124e8919061461e565b90505f811161252c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161252390614743565b60405180910390fd5b60018260020160186101000a81548160ff021916908360ff160217905550428260020160196101000a81548163ffffffff021916908363ffffffff160217905550808260030181905550815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16837f20608164f7bc6db4fa0cb4a5d58ffb5ad642b65d39bb3fc267b465016789b4f0426040516125df9190613a97565b60405180910390a350505b50565b5f600554905090565b6125fe613575565b60065f9054906101000a900460ff1661264c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161264390614161565b60405180910390fd5b61265461364b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036126c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126b9906148f1565b60405180910390fd5b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166379cd2214826040518263ffffffff1660e01b815260040161271c9190613b63565b602060405180830381865afa158015612737573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061275b9190614939565b61279a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612791906149ae565b60405180910390fd5b5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b81526004016127f59190613b63565b602060405180830381865afa158015612810573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061283491906140a9565b90505f8111612878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286f90614a16565b60405180910390fd5b5f612881613492565b90505f81116128c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128bc90614a7e565b60405180910390fd5b5f670de0b6b3a764000082846128db9190614006565b6128e5919061461e565b905060045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f80acc008583856040518463ffffffff1660e01b8152600401612945939291906144b9565b5f604051808303815f87803b15801561295c575f5ffd5b505af115801561296e573d5f5f3e3d5ffd5b505050508373ffffffffffffffffffffffffffffffffffffffff167fff377e9a2f300bc0937632296a6167d789b286fad6a540f95a2560c6de6a08de426040516129b89190613a97565b60405180910390a27fe1e035f75f94e0038561eaa98c5e73b5dabc517ceee7892f8b3b9e5d92084ee36129e96125ed565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a53573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a7791906140a9565b612a7f613492565b42604051612a9094939291906140d4565b60405180910390a150505050565b6008602052815f5260405f208181548110612ab7575f80fd5b905f5260205f20015f91509150505481565b612ad1613a0e565b6007805490508210612b18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b0f90614336565b60405180910390fd5b60078281548110612b2c57612b2b614354565b5b905f5260205f2090600402016040518060e00160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820160149054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016002820160189054906101000a900460ff1660ff1660ff1681526020016002820160199054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016003820154815250509050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b612c9c613575565b60065f9054906101000a900460ff16612cea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ce190614161565b60405180910390fd5b806005819055507fe0651f3830a683d451cf1ab5bf6d378d4abaf4d38f24e4938f45a3cf92f925a68142604051612d2292919061406e565b60405180910390a17fe1e035f75f94e0038561eaa98c5e73b5dabc517ceee7892f8b3b9e5d92084ee3612d536125ed565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612dbd573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612de191906140a9565b612de9613492565b42604051612dfa94939291906140d4565b60405180910390a150565b6201518081565b612e14613575565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612e82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e7990614ae6565b60405180910390fd5b600260019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612f12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0990614b4e565b60405180910390fd5b5f600260019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600260016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f47a7eb2dcf8771aa3f60e234ddf0f1beffb0c213970e4d095d528698c7edf09d42604051612fd69190613a97565b60405180910390a35050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613072573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061309691906140a9565b90505f6130a16125ed565b90505f8214806130b057505f81145b156130cf5764e8d4a51000846130c69190614006565b925050506130eb565b8082856130dc9190614006565b6130e6919061461e565b925050505b919050565b6130f8613575565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613168575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161315f9190613b63565b60405180910390fd5b61317181613800565b50565b61317c6135fc565b60065f9054906101000a900460ff166131ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131c190614161565b60405180910390fd5b6131d261364b565b6007805490508110613219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161321090614336565b60405180910390fd5b5f6007828154811061322e5761322d614354565b5b905f5260205f20906004020190503373ffffffffffffffffffffffffffffffffffffffff16815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146132cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132c3906143cb565b60405180910390fd5b5f8160020160189054906101000a900460ff1660ff1614613322576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161331990614889565b60405180910390fd5b620151808160020160149054906101000a900463ffffffff1663ffffffff1661334b91906145be565b421161338c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161338390614bb6565b60405180910390fd5b60048160020160186101000a81548160ff021916908360ff16021790555060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f193383600101546040518363ffffffff1660e01b815260040161340a929190614047565b5f604051808303815f87803b158015613421575f5ffd5b505af1158015613433573d5f5f3e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff16827fdc208055b8c07aad9143ab5ad8f1518ec881df3039290c46be87c861e00484b84260405161347e9190613a97565b60405180910390a35061348f613695565b50565b5f5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134fe573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061352291906140a9565b90505f61352d6125ed565b90505f82148061353c57505f81145b1561354e57620f424092505050613572565b81670de0b6b3a7640000826135639190614006565b61356d919061461e565b925050505b90565b61357d613923565b73ffffffffffffffffffffffffffffffffffffffff1661359b61214c565b73ffffffffffffffffffffffffffffffffffffffff16146135fa576135be613923565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016135f19190613b63565b60405180910390fd5b565b600260015403613641576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161363890614c1e565b60405180910390fd5b6002600181905550565b61365361200c565b15613693576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161368a90614c86565b60405180910390fd5b565b60018081905550565b6136a661392a565b5f60025f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6136e8613923565b6040516136f59190613b63565b60405180910390a1565b61377b848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161373493929190614ca4565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613973565b50505050565b6137fb838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85856040516024016137b4929190614047565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613973565b505050565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6138c961364b565b600160025f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861390c613923565b6040516139199190613b63565b60405180910390a1565b5f33905090565b61393261200c565b613971576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161396890614d23565b60405180910390fd5b565b5f5f60205f8451602086015f885af180613992576040513d5f823e3d81fd5b3d92505f519150505f82146139ab5760018114156139c6565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b15613a0857836040517f5274afe70000000000000000000000000000000000000000000000000000000081526004016139ff9190613b63565b60405180910390fd5b50505050565b6040518060e001604052805f73ffffffffffffffffffffffffffffffffffffffff1681526020015f81526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f63ffffffff1681526020015f60ff1681526020015f63ffffffff1681526020015f81525090565b5f819050919050565b613a9181613a7f565b82525050565b5f602082019050613aaa5f830184613a88565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f819050919050565b5f613af2613aed613ae884613ab0565b613acf565b613ab0565b9050919050565b5f613b0382613ad8565b9050919050565b5f613b1482613af9565b9050919050565b613b2481613b0a565b82525050565b5f602082019050613b3d5f830184613b1b565b92915050565b5f613b4d82613ab0565b9050919050565b613b5d81613b43565b82525050565b5f602082019050613b765f830184613b54565b92915050565b5f5ffd5b613b8981613a7f565b8114613b93575f5ffd5b50565b5f81359050613ba481613b80565b92915050565b5f60208284031215613bbf57613bbe613b7c565b5b5f613bcc84828501613b96565b91505092915050565b613bde81613b43565b8114613be8575f5ffd5b50565b5f81359050613bf981613bd5565b92915050565b5f5f60408385031215613c1557613c14613b7c565b5b5f613c2285828601613b96565b9250506020613c3385828601613beb565b9150509250929050565b5f8115159050919050565b613c5181613c3d565b82525050565b5f602082019050613c6a5f830184613c48565b92915050565b5f5f60408385031215613c8657613c85613b7c565b5b5f613c9385828601613beb565b9250506020613ca485828601613b96565b9150509250929050565b5f60208284031215613cc357613cc2613b7c565b5b5f613cd084828501613beb565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b613d0b81613a7f565b82525050565b5f613d1c8383613d02565b60208301905092915050565b5f602082019050919050565b5f613d3e82613cd9565b613d488185613ce3565b9350613d5383613cf3565b805f5b83811015613d83578151613d6a8882613d11565b9750613d7583613d28565b925050600181019050613d56565b5085935050505092915050565b5f6020820190508181035f830152613da88184613d34565b905092915050565b5f613dba82613af9565b9050919050565b613dca81613db0565b82525050565b5f602082019050613de35f830184613dc1565b92915050565b5f63ffffffff82169050919050565b613e0181613de9565b82525050565b5f60ff82169050919050565b613e1c81613e07565b82525050565b5f60e082019050613e355f83018a613b54565b613e426020830189613a88565b613e4f6040830188613b54565b613e5c6060830187613df8565b613e696080830186613e13565b613e7660a0830185613df8565b613e8360c0830184613a88565b98975050505050505050565b613e9881613b43565b82525050565b613ea781613de9565b82525050565b613eb681613e07565b82525050565b60e082015f820151613ed05f850182613e8f565b506020820151613ee36020850182613d02565b506040820151613ef66040850182613e8f565b506060820151613f096060850182613e9e565b506080820151613f1c6080850182613ead565b5060a0820151613f2f60a0850182613e9e565b5060c0820151613f4260c0850182613d02565b50505050565b5f60e082019050613f5b5f830184613ebc565b92915050565b5f82825260208201905092915050565b7f416c726561647920696e697469616c697a6564000000000000000000000000005f82015250565b5f613fa5601383613f61565b9150613fb082613f71565b602082019050919050565b5f6020820190508181035f830152613fd281613f99565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61401082613a7f565b915061401b83613a7f565b925082820261402981613a7f565b915082820484148315176140405761403f613fd9565b5b5092915050565b5f60408201905061405a5f830185613b54565b6140676020830184613a88565b9392505050565b5f6040820190506140815f830185613a88565b61408e6020830184613a88565b9392505050565b5f815190506140a381613b80565b92915050565b5f602082840312156140be576140bd613b7c565b5b5f6140cb84828501614095565b91505092915050565b5f6080820190506140e75f830187613a88565b6140f46020830186613a88565b6141016040830185613a88565b61410e6060830184613a88565b95945050505050565b7f46756e64206e6f7420696e697469616c697a65640000000000000000000000005f82015250565b5f61414b601483613f61565b915061415682614117565b602082019050919050565b5f6020820190508181035f8301526141788161413f565b9050919050565b7f496e76616c696420737461626c65636f696e00000000000000000000000000005f82015250565b5f6141b3601283613f61565b91506141be8261417f565b602082019050919050565b5f6020820190508181035f8301526141e0816141a7565b9050919050565b7f496e76616c6964207769746864726177616c20616d6f756e74000000000000005f82015250565b5f61421b601983613f61565b9150614226826141e7565b602082019050919050565b5f6020820190508181035f8301526142488161420f565b9050919050565b7f496e73756666696369656e7420504e4c2062616c616e636500000000000000005f82015250565b5f614283601883613f61565b915061428e8261424f565b602082019050919050565b5f6020820190508181035f8301526142b081614277565b9050919050565b5f6060820190506142ca5f830186613a88565b6142d76020830185613b54565b6142e46040830184613a88565b949350505050565b7f496e76616c6964207265717565737420494400000000000000000000000000005f82015250565b5f614320601283613f61565b915061432b826142ec565b602082019050919050565b5f6020820190508181035f83015261434d81614314565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e6f7420796f75722072657175657374000000000000000000000000000000005f82015250565b5f6143b5601083613f61565b91506143c082614381565b602082019050919050565b5f6020820190508181035f8301526143e2816143a9565b9050919050565b7f43616e6e6f742063616e63656c000000000000000000000000000000000000005f82015250565b5f61441d600d83613f61565b9150614428826143e9565b602082019050919050565b5f6020820190508181035f83015261444a81614411565b9050919050565b7f496e76616c69642066756e64696e6720616d6f756e74000000000000000000005f82015250565b5f614485601683613f61565b915061449082614451565b602082019050919050565b5f6020820190508181035f8301526144b281614479565b9050919050565b5f6060820190506144cc5f830186613b54565b6144d96020830185613a88565b6144e66040830184613a88565b949350505050565b7f496e76616c6964206465706f73697420616d6f756e74000000000000000000005f82015250565b5f614522601683613f61565b915061452d826144ee565b602082019050919050565b5f6020820190508181035f83015261454f81614516565b9050919050565b7f504e4c20616d6f756e7420746f6f20736d616c6c0000000000000000000000005f82015250565b5f61458a601483613f61565b915061459582614556565b602082019050919050565b5f6020820190508181035f8301526145b78161457e565b9050919050565b5f6145c882613a7f565b91506145d383613a7f565b92508282019050808211156145eb576145ea613fd9565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61462882613a7f565b915061463383613a7f565b925082614643576146426145f1565b5b828204905092915050565b5f6080820190506146615f830187613b54565b61466e6020830186613a88565b61467b6040830185613a88565b6146886060830184613a88565b95945050505050565b7f52657175657374206e6f7420617070726f7665640000000000000000000000005f82015250565b5f6146c5601483613f61565b91506146d082614691565b602082019050919050565b5f6020820190508181035f8301526146f2816146b9565b9050919050565b7f5061796f757420616d6f756e7420746f6f20736d616c6c0000000000000000005f82015250565b5f61472d601783613f61565b9150614738826146f9565b602082019050919050565b5f6020820190508181035f83015261475a81614721565b9050919050565b7f496e73756666696369656e7420636f6e74726163742062616c616e63650000005f82015250565b5f614795601d83613f61565b91506147a082614761565b602082019050919050565b5f6020820190508181035f8301526147c281614789565b9050919050565b5f6147d382613a7f565b91506147de83613a7f565b92508282039050818111156147f6576147f5613fd9565b5b92915050565b5f60808201905061480f5f830187613a88565b61481c6020830186613b54565b6148296040830185613a88565b6148366060830184613a88565b95945050505050565b7f52657175657374206e6f742070656e64696e67000000000000000000000000005f82015250565b5f614873601383613f61565b915061487e8261483f565b602082019050919050565b5f6020820190508181035f8301526148a081614867565b9050919050565b7f496e76616c696420696e766573746f72000000000000000000000000000000005f82015250565b5f6148db601083613f61565b91506148e6826148a7565b602082019050919050565b5f6020820190508181035f830152614908816148cf565b9050919050565b61491881613c3d565b8114614922575f5ffd5b50565b5f815190506149338161490f565b92915050565b5f6020828403121561494e5761494d613b7c565b5b5f61495b84828501614925565b91505092915050565b7f496e766573746f72206e6f7420616374697665000000000000000000000000005f82015250565b5f614998601383613f61565b91506149a382614964565b602082019050919050565b5f6020820190508181035f8301526149c58161498c565b9050919050565b7f4e6f20504e4c20746f6b656e73000000000000000000000000000000000000005f82015250565b5f614a00600d83613f61565b9150614a0b826149cc565b602082019050919050565b5f6020820190508181035f830152614a2d816149f4565b9050919050565b7f496e76616c6964207261746500000000000000000000000000000000000000005f82015250565b5f614a68600c83613f61565b9150614a7382614a34565b602082019050919050565b5f6020820190508181035f830152614a9581614a5c565b9050919050565b7f496e76616c69642074726164652077616c6c65742061646472657373000000005f82015250565b5f614ad0601c83613f61565b9150614adb82614a9c565b602082019050919050565b5f6020820190508181035f830152614afd81614ac4565b9050919050565b7f53616d65206164647265737300000000000000000000000000000000000000005f82015250565b5f614b38600c83613f61565b9150614b4382614b04565b602082019050919050565b5f6020820190508181035f830152614b6581614b2c565b9050919050565b7f4e6f7420657870697265642079657400000000000000000000000000000000005f82015250565b5f614ba0600f83613f61565b9150614bab82614b6c565b602082019050919050565b5f6020820190508181035f830152614bcd81614b94565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f614c08601f83613f61565b9150614c1382614bd4565b602082019050919050565b5f6020820190508181035f830152614c3581614bfc565b9050919050565b7f5061757361626c653a20706175736564000000000000000000000000000000005f82015250565b5f614c70601083613f61565b9150614c7b82614c3c565b602082019050919050565b5f6020820190508181035f830152614c9d81614c64565b9050919050565b5f606082019050614cb75f830186613b54565b614cc46020830185613b54565b614cd16040830184613a88565b949350505050565b7f5061757361626c653a206e6f74207061757365640000000000000000000000005f82015250565b5f614d0d601483613f61565b9150614d1882614cd9565b602082019050919050565b5f6020820190508181035f830152614d3a81614d01565b905091905056fea26469706673582212209293e50e319354c367874b486f1b3b879ece596e69444bf5c160bc04b2c12a1664736f6c634300081f0033000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000134c024d5ce4373c4360d0d85cb675488e95488000000000000000000000000eed5135b096348f4cf37026f2a6e33c95e1386e70000000000000000000000008795526899edbfd83d1cc89bab919287a1ebcfea0000000000000000000000006946e9886cb5ed3bb24dc9174b6e5f9f6e23daf6
Deployed Bytecode
0x608060405234801561000f575f5ffd5b5060043610610204575f3560e01c80638456cb5911610118578063b40c1b78116100ab578063d4fe21951161007a578063d4fe21951461057e578063e36675251461059c578063f2fde38b146105cc578063f3917d79146105e8578063f7fb07b01461060457610204565b8063b40c1b781461050a578063b9b83d3914610528578063bc2c81e914610544578063c696f4da1461056257610204565b8063a128c591116100e7578063a128c59114610470578063a4072b7f1461048e578063a471e547146104aa578063ae485651146104da57610204565b80638456cb59146103f65780638da5cb5b14610400578063937b25811461041e5780639eceddea1461045457610204565b806342e02fb41161019b5780635c38d22e1161016a5780635c38d22e146103625780635c975abb146103805780636c9302281461039e578063715018a6146103ce578063808f0a7c146103d857610204565b806342e02fb4146102de57806343ab265f146102fa57806347e7ef241461032a5780634f0cb5f31461034657610204565b806321739779116101d7578063217397791461027e578063392e53cd1461029a5780633efcfda4146102b85780633f4ba83a146102d457610204565b806301e1d11414610208578063037cff4614610226578063130a8292146102445780631942811114610262575b5f5ffd5b610210610622565b60405161021d9190613a97565b60405180910390f35b61022e610628565b60405161023b9190613b2a565b60405180910390f35b61024c61064d565b6040516102599190613b63565b60405180910390f35b61027c60048036038101906102779190613baa565b610673565b005b61029860048036038101906102939190613bff565b6108b6565b005b6102a2610e0f565b6040516102af9190613c57565b60405180910390f35b6102d260048036038101906102cd9190613baa565b610e21565b005b6102dc6110d5565b005b6102f860048036038101906102f39190613c70565b611135565b005b610314600480360381019061030f9190613cae565b611336565b6040516103219190613a97565b60405180910390f35b610344600480360381019061033f9190613c70565b61149c565b005b610360600480360381019061035b9190613baa565b6119e6565b005b61036a612000565b6040516103779190613a97565b60405180910390f35b61038861200c565b6040516103959190613c57565b60405180910390f35b6103b860048036038101906103b39190613cae565b612021565b6040516103c59190613d90565b60405180910390f35b6103d66120b4565b005b6103e06120c7565b6040516103ed9190613dd0565b60405180910390f35b6103fe6120ec565b005b61040861214c565b6040516104159190613b63565b60405180910390f35b61043860048036038101906104339190613baa565b612173565b60405161044b9796959493929190613e22565b60405180910390f35b61046e60048036038101906104699190613baa565b61222b565b005b6104786125ed565b6040516104859190613a97565b60405180910390f35b6104a860048036038101906104a39190613cae565b6125f6565b005b6104c460048036038101906104bf9190613c70565b612a9e565b6040516104d19190613a97565b60405180910390f35b6104f460048036038101906104ef9190613baa565b612ac9565b6040516105019190613f48565b60405180910390f35b610512612c70565b60405161051f9190613b63565b60405180910390f35b610542600480360381019061053d9190613baa565b612c94565b005b61054c612e05565b6040516105599190613a97565b60405180910390f35b61057c60048036038101906105779190613cae565b612e0c565b005b610586612fe2565b6040516105939190613b63565b60405180910390f35b6105b660048036038101906105b19190613baa565b613006565b6040516105c39190613a97565b60405180910390f35b6105e660048036038101906105e19190613cae565b6130f0565b005b61060260048036038101906105fd9190613baa565b613174565b005b61060c613492565b6040516106199190613a97565b60405180910390f35b60055481565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61067b613575565b60065f9054906101000a900460ff16156106ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c190613fbb565b60405180910390fd5b80600581905550600160065f6101000a81548160ff0219169083151502179055505f8111156107a2575f64e8d4a51000826107059190614006565b90505f8111156107a05760035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1961075461214c565b836040518363ffffffff1660e01b8152600401610772929190614047565b5f604051808303815f87803b158015610789575f5ffd5b505af115801561079b573d5f5f3e3d5ffd5b505050505b505b7f37d36da36de67b5a5c7adfc8ce80c29e2e220878ad7cfc48d23df0ca7197f49581426040516107d392919061406e565b60405180910390a17fe1e035f75f94e0038561eaa98c5e73b5dabc517ceee7892f8b3b9e5d92084ee36108046125ed565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561086e573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061089291906140a9565b61089a613492565b426040516108ab94939291906140d4565b60405180910390a150565b6108be6135fc565b60065f9054906101000a900460ff1661090c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090390614161565b60405180910390fd5b61091461364b565b807f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806109ba57507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b6109f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f0906141c9565b60405180910390fd5b5f8311610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3290614231565b60405180910390fd5b8260035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401610a969190613b63565b602060405180830381865afa158015610ab1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad591906140a9565b1015610b16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0d90614299565b60405180910390fd5b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dc29fac33856040518363ffffffff1660e01b8152600401610b72929190614047565b5f604051808303815f87803b158015610b89575f5ffd5b505af1158015610b9b573d5f5f3e3d5ffd5b505050505f600780549050905060076040518060e001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020014263ffffffff1681526020015f60ff1681526020015f63ffffffff1681526020015f815250908060018154018082558091505060019003905f5260205f2090600402015f909190919091505f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160146101000a81548163ffffffff021916908363ffffffff16021790555060808201518160020160186101000a81548160ff021916908360ff16021790555060a08201518160020160196101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160030155505060085f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081908060018154018082558091505060019003905f5260205f20015f90919091909150553373ffffffffffffffffffffffffffffffffffffffff16817f3aa0147eff4ace81f26e95a29e29f25bb9509b6bd6e3002879a1a71a5c29e1ad868642604051610df9939291906142b7565b60405180910390a35050610e0b613695565b5050565b60065f9054906101000a900460ff1681565b610e296135fc565b60065f9054906101000a900460ff16610e77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6e90614161565b60405180910390fd5b610e7f61364b565b6007805490508110610ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebd90614336565b60405180910390fd5b5f60078281548110610edb57610eda614354565b5b905f5260205f20906004020190503373ffffffffffffffffffffffffffffffffffffffff16815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610f79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f70906143cb565b60405180910390fd5b5f8160020160189054906101000a900460ff1660ff1614610fcf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fc690614433565b60405180910390fd5b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f193383600101546040518363ffffffff1660e01b815260040161102f929190614047565b5f604051808303815f87803b158015611046575f5ffd5b505af1158015611058573d5f5f3e3d5ffd5b5050505060038160020160186101000a81548160ff021916908360ff1602179055503373ffffffffffffffffffffffffffffffffffffffff16827faf28bc105571d58bdc8db31b07d28b142526b699802713e96ad9f7dca963474f426040516110c19190613a97565b60405180910390a3506110d2613695565b50565b6110dd613575565b6110e561369e565b3373ffffffffffffffffffffffffffffffffffffffff167f66213c89ece0bf063cc20061fbda1c3c1bde502eaaee2f4e96dd3c11dec0856c4260405161112b9190613a97565b60405180910390a2565b61113d613575565b60065f9054906101000a900460ff1661118b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118290614161565b60405180910390fd5b817f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061123157507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611270576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611267906141c9565b60405180910390fd5b5f82116112b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a99061449b565b60405180910390fd5b6112df3330848673ffffffffffffffffffffffffffffffffffffffff166136ff909392919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167fa37175a3415c4ec48c1ba6d18e2b563b5e88acf3b470b83ab91fa9eb741895f1848442604051611329939291906144b9565b60405180910390a2505050565b5f817f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806113dd57507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b61141c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611413906141c9565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016114559190613b63565b602060405180830381865afa158015611470573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061149491906140a9565b915050919050565b6114a46135fc565b60065f9054906101000a900460ff166114f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e990614161565b60405180910390fd5b6114fa61364b565b817f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806115a057507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b6115df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115d6906141c9565b60405180910390fd5b5f8211611621576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161890614538565b60405180910390fd5b5f61162b83613006565b90505f811161166f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611666906145a0565b60405180910390fd5b6116be33600260019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16858773ffffffffffffffffffffffffffffffffffffffff166136ff909392919063ffffffff16565b8260055f8282546116cf91906145be565b9250508190555060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1933836040518363ffffffff1660e01b8152600401611732929190614047565b5f604051808303815f87803b158015611749575f5ffd5b505af115801561175b573d5f5f3e3d5ffd5b505050505f670de0b6b3a7640000611771613492565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016117cb9190613b63565b602060405180830381865afa1580156117e6573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061180a91906140a9565b6118149190614006565b61181e919061461e565b905060045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c68ba54c3386846040518463ffffffff1660e01b815260040161187e939291906144b9565b5f604051808303815f87803b158015611895575f5ffd5b505af11580156118a7573d5f5f3e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f6868685426040516118f7949392919061464e565b60405180910390a27fe1e035f75f94e0038561eaa98c5e73b5dabc517ceee7892f8b3b9e5d92084ee36119286125ed565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611992573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119b691906140a9565b6119be613492565b426040516119cf94939291906140d4565b60405180910390a15050506119e2613695565b5050565b6119ee613575565b6119f66135fc565b60065f9054906101000a900460ff16611a44576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3b90614161565b60405180910390fd5b611a4c61364b565b6007805490508110611a93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8a90614336565b60405180910390fd5b5f60078281548110611aa857611aa7614354565b5b905f5260205f209060040201905060018160020160189054906101000a900460ff1660ff1614611b0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b04906146db565b60405180910390fd5b5f816003015490505f8111611b57576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4e90614743565b60405180910390fd5b80826002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611bb49190613b63565b602060405180830381865afa158015611bcf573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bf391906140a9565b1015611c34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2b906147ab565b60405180910390fd5b8060055f828254611c4591906147c9565b925050819055505f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231845f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401611cc99190613b63565b602060405180830381865afa158015611ce4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d0891906140a9565b90505f811115611dee575f836001015482611d2391906145be565b6127108560010154611d359190614006565b611d3f919061461e565b905060045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663014d1d8d855f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401611dbf929190614047565b5f604051808303815f87803b158015611dd6575f5ffd5b505af1158015611de8573d5f5f3e3d5ffd5b50505050505b611e5e835f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683856002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137819092919063ffffffff16565b60028360020160186101000a81548160ff021916908360ff160217905550825f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16847f7d2bc9c190a026adb94946f747f545b2862f770335771262341c274e22924fb18560010154866002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff168642604051611f1294939291906147fc565b60405180910390a37fe1e035f75f94e0038561eaa98c5e73b5dabc517ceee7892f8b3b9e5d92084ee3611f436125ed565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fad573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fd191906140a9565b611fd9613492565b42604051611fea94939291906140d4565b60405180910390a1505050611ffd613695565b50565b5f600780549050905090565b5f60025f9054906101000a900460ff16905090565b606060085f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208054806020026020016040519081016040528092919081815260200182805480156120a857602002820191905f5260205f20905b815481526020019060010190808311612094575b50505050509050919050565b6120bc613575565b6120c55f613800565b565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6120f4613575565b6120fc6138c1565b3373ffffffffffffffffffffffffffffffffffffffff167f0248a1bee6b2ebe08af6245feaa774395a357b52ee147682094c1eea17168826426040516121429190613a97565b60405180910390a2565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60078181548110612182575f80fd5b905f5260205f2090600402015f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015490806002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020160149054906101000a900463ffffffff16908060020160189054906101000a900460ff16908060020160199054906101000a900463ffffffff16908060030154905087565b612233613575565b60065f9054906101000a900460ff16612281576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161227890614161565b60405180910390fd5b61228961364b565b60078054905081106122d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c790614336565b60405180910390fd5b5f600782815481106122e5576122e4614354565b5b905f5260205f20906004020190505f8160020160189054906101000a900460ff1660ff1614612349576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161234090614889565b60405180910390fd5b620151808160020160149054906101000a900463ffffffff1663ffffffff1661237291906145be565b4211156124bd5760048160020160186101000a81548160ff021916908360ff16021790555060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f19825f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683600101546040518363ffffffff1660e01b8152600401612419929190614047565b5f604051808303815f87803b158015612430575f5ffd5b505af1158015612442573d5f5f3e3d5ffd5b50505050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16827fdc208055b8c07aad9143ab5ad8f1518ec881df3039290c46be87c861e00484b8426040516124af9190613a97565b60405180910390a3506125ea565b5f670de0b6b3a76400006124cf613492565b83600101546124de9190614006565b6124e8919061461e565b90505f811161252c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161252390614743565b60405180910390fd5b60018260020160186101000a81548160ff021916908360ff160217905550428260020160196101000a81548163ffffffff021916908363ffffffff160217905550808260030181905550815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16837f20608164f7bc6db4fa0cb4a5d58ffb5ad642b65d39bb3fc267b465016789b4f0426040516125df9190613a97565b60405180910390a350505b50565b5f600554905090565b6125fe613575565b60065f9054906101000a900460ff1661264c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161264390614161565b60405180910390fd5b61265461364b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036126c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126b9906148f1565b60405180910390fd5b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166379cd2214826040518263ffffffff1660e01b815260040161271c9190613b63565b602060405180830381865afa158015612737573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061275b9190614939565b61279a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612791906149ae565b60405180910390fd5b5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b81526004016127f59190613b63565b602060405180830381865afa158015612810573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061283491906140a9565b90505f8111612878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286f90614a16565b60405180910390fd5b5f612881613492565b90505f81116128c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128bc90614a7e565b60405180910390fd5b5f670de0b6b3a764000082846128db9190614006565b6128e5919061461e565b905060045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f80acc008583856040518463ffffffff1660e01b8152600401612945939291906144b9565b5f604051808303815f87803b15801561295c575f5ffd5b505af115801561296e573d5f5f3e3d5ffd5b505050508373ffffffffffffffffffffffffffffffffffffffff167fff377e9a2f300bc0937632296a6167d789b286fad6a540f95a2560c6de6a08de426040516129b89190613a97565b60405180910390a27fe1e035f75f94e0038561eaa98c5e73b5dabc517ceee7892f8b3b9e5d92084ee36129e96125ed565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a53573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a7791906140a9565b612a7f613492565b42604051612a9094939291906140d4565b60405180910390a150505050565b6008602052815f5260405f208181548110612ab7575f80fd5b905f5260205f20015f91509150505481565b612ad1613a0e565b6007805490508210612b18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b0f90614336565b60405180910390fd5b60078281548110612b2c57612b2b614354565b5b905f5260205f2090600402016040518060e00160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820160149054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016002820160189054906101000a900460ff1660ff1660ff1681526020016002820160199054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016003820154815250509050919050565b7f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec781565b612c9c613575565b60065f9054906101000a900460ff16612cea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ce190614161565b60405180910390fd5b806005819055507fe0651f3830a683d451cf1ab5bf6d378d4abaf4d38f24e4938f45a3cf92f925a68142604051612d2292919061406e565b60405180910390a17fe1e035f75f94e0038561eaa98c5e73b5dabc517ceee7892f8b3b9e5d92084ee3612d536125ed565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612dbd573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612de191906140a9565b612de9613492565b42604051612dfa94939291906140d4565b60405180910390a150565b6201518081565b612e14613575565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612e82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e7990614ae6565b60405180910390fd5b600260019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612f12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0990614b4e565b60405180910390fd5b5f600260019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600260016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f47a7eb2dcf8771aa3f60e234ddf0f1beffb0c213970e4d095d528698c7edf09d42604051612fd69190613a97565b60405180910390a35050565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b5f5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613072573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061309691906140a9565b90505f6130a16125ed565b90505f8214806130b057505f81145b156130cf5764e8d4a51000846130c69190614006565b925050506130eb565b8082856130dc9190614006565b6130e6919061461e565b925050505b919050565b6130f8613575565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613168575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161315f9190613b63565b60405180910390fd5b61317181613800565b50565b61317c6135fc565b60065f9054906101000a900460ff166131ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131c190614161565b60405180910390fd5b6131d261364b565b6007805490508110613219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161321090614336565b60405180910390fd5b5f6007828154811061322e5761322d614354565b5b905f5260205f20906004020190503373ffffffffffffffffffffffffffffffffffffffff16815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146132cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132c3906143cb565b60405180910390fd5b5f8160020160189054906101000a900460ff1660ff1614613322576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161331990614889565b60405180910390fd5b620151808160020160149054906101000a900463ffffffff1663ffffffff1661334b91906145be565b421161338c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161338390614bb6565b60405180910390fd5b60048160020160186101000a81548160ff021916908360ff16021790555060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f193383600101546040518363ffffffff1660e01b815260040161340a929190614047565b5f604051808303815f87803b158015613421575f5ffd5b505af1158015613433573d5f5f3e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff16827fdc208055b8c07aad9143ab5ad8f1518ec881df3039290c46be87c861e00484b84260405161347e9190613a97565b60405180910390a35061348f613695565b50565b5f5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134fe573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061352291906140a9565b90505f61352d6125ed565b90505f82148061353c57505f81145b1561354e57620f424092505050613572565b81670de0b6b3a7640000826135639190614006565b61356d919061461e565b925050505b90565b61357d613923565b73ffffffffffffffffffffffffffffffffffffffff1661359b61214c565b73ffffffffffffffffffffffffffffffffffffffff16146135fa576135be613923565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016135f19190613b63565b60405180910390fd5b565b600260015403613641576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161363890614c1e565b60405180910390fd5b6002600181905550565b61365361200c565b15613693576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161368a90614c86565b60405180910390fd5b565b60018081905550565b6136a661392a565b5f60025f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6136e8613923565b6040516136f59190613b63565b60405180910390a1565b61377b848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161373493929190614ca4565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613973565b50505050565b6137fb838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85856040516024016137b4929190614047565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613973565b505050565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6138c961364b565b600160025f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861390c613923565b6040516139199190613b63565b60405180910390a1565b5f33905090565b61393261200c565b613971576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161396890614d23565b60405180910390fd5b565b5f5f60205f8451602086015f885af180613992576040513d5f823e3d81fd5b3d92505f519150505f82146139ab5760018114156139c6565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b15613a0857836040517f5274afe70000000000000000000000000000000000000000000000000000000081526004016139ff9190613b63565b60405180910390fd5b50505050565b6040518060e001604052805f73ffffffffffffffffffffffffffffffffffffffff1681526020015f81526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f63ffffffff1681526020015f60ff1681526020015f63ffffffff1681526020015f81525090565b5f819050919050565b613a9181613a7f565b82525050565b5f602082019050613aaa5f830184613a88565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f819050919050565b5f613af2613aed613ae884613ab0565b613acf565b613ab0565b9050919050565b5f613b0382613ad8565b9050919050565b5f613b1482613af9565b9050919050565b613b2481613b0a565b82525050565b5f602082019050613b3d5f830184613b1b565b92915050565b5f613b4d82613ab0565b9050919050565b613b5d81613b43565b82525050565b5f602082019050613b765f830184613b54565b92915050565b5f5ffd5b613b8981613a7f565b8114613b93575f5ffd5b50565b5f81359050613ba481613b80565b92915050565b5f60208284031215613bbf57613bbe613b7c565b5b5f613bcc84828501613b96565b91505092915050565b613bde81613b43565b8114613be8575f5ffd5b50565b5f81359050613bf981613bd5565b92915050565b5f5f60408385031215613c1557613c14613b7c565b5b5f613c2285828601613b96565b9250506020613c3385828601613beb565b9150509250929050565b5f8115159050919050565b613c5181613c3d565b82525050565b5f602082019050613c6a5f830184613c48565b92915050565b5f5f60408385031215613c8657613c85613b7c565b5b5f613c9385828601613beb565b9250506020613ca485828601613b96565b9150509250929050565b5f60208284031215613cc357613cc2613b7c565b5b5f613cd084828501613beb565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b613d0b81613a7f565b82525050565b5f613d1c8383613d02565b60208301905092915050565b5f602082019050919050565b5f613d3e82613cd9565b613d488185613ce3565b9350613d5383613cf3565b805f5b83811015613d83578151613d6a8882613d11565b9750613d7583613d28565b925050600181019050613d56565b5085935050505092915050565b5f6020820190508181035f830152613da88184613d34565b905092915050565b5f613dba82613af9565b9050919050565b613dca81613db0565b82525050565b5f602082019050613de35f830184613dc1565b92915050565b5f63ffffffff82169050919050565b613e0181613de9565b82525050565b5f60ff82169050919050565b613e1c81613e07565b82525050565b5f60e082019050613e355f83018a613b54565b613e426020830189613a88565b613e4f6040830188613b54565b613e5c6060830187613df8565b613e696080830186613e13565b613e7660a0830185613df8565b613e8360c0830184613a88565b98975050505050505050565b613e9881613b43565b82525050565b613ea781613de9565b82525050565b613eb681613e07565b82525050565b60e082015f820151613ed05f850182613e8f565b506020820151613ee36020850182613d02565b506040820151613ef66040850182613e8f565b506060820151613f096060850182613e9e565b506080820151613f1c6080850182613ead565b5060a0820151613f2f60a0850182613e9e565b5060c0820151613f4260c0850182613d02565b50505050565b5f60e082019050613f5b5f830184613ebc565b92915050565b5f82825260208201905092915050565b7f416c726561647920696e697469616c697a6564000000000000000000000000005f82015250565b5f613fa5601383613f61565b9150613fb082613f71565b602082019050919050565b5f6020820190508181035f830152613fd281613f99565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61401082613a7f565b915061401b83613a7f565b925082820261402981613a7f565b915082820484148315176140405761403f613fd9565b5b5092915050565b5f60408201905061405a5f830185613b54565b6140676020830184613a88565b9392505050565b5f6040820190506140815f830185613a88565b61408e6020830184613a88565b9392505050565b5f815190506140a381613b80565b92915050565b5f602082840312156140be576140bd613b7c565b5b5f6140cb84828501614095565b91505092915050565b5f6080820190506140e75f830187613a88565b6140f46020830186613a88565b6141016040830185613a88565b61410e6060830184613a88565b95945050505050565b7f46756e64206e6f7420696e697469616c697a65640000000000000000000000005f82015250565b5f61414b601483613f61565b915061415682614117565b602082019050919050565b5f6020820190508181035f8301526141788161413f565b9050919050565b7f496e76616c696420737461626c65636f696e00000000000000000000000000005f82015250565b5f6141b3601283613f61565b91506141be8261417f565b602082019050919050565b5f6020820190508181035f8301526141e0816141a7565b9050919050565b7f496e76616c6964207769746864726177616c20616d6f756e74000000000000005f82015250565b5f61421b601983613f61565b9150614226826141e7565b602082019050919050565b5f6020820190508181035f8301526142488161420f565b9050919050565b7f496e73756666696369656e7420504e4c2062616c616e636500000000000000005f82015250565b5f614283601883613f61565b915061428e8261424f565b602082019050919050565b5f6020820190508181035f8301526142b081614277565b9050919050565b5f6060820190506142ca5f830186613a88565b6142d76020830185613b54565b6142e46040830184613a88565b949350505050565b7f496e76616c6964207265717565737420494400000000000000000000000000005f82015250565b5f614320601283613f61565b915061432b826142ec565b602082019050919050565b5f6020820190508181035f83015261434d81614314565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e6f7420796f75722072657175657374000000000000000000000000000000005f82015250565b5f6143b5601083613f61565b91506143c082614381565b602082019050919050565b5f6020820190508181035f8301526143e2816143a9565b9050919050565b7f43616e6e6f742063616e63656c000000000000000000000000000000000000005f82015250565b5f61441d600d83613f61565b9150614428826143e9565b602082019050919050565b5f6020820190508181035f83015261444a81614411565b9050919050565b7f496e76616c69642066756e64696e6720616d6f756e74000000000000000000005f82015250565b5f614485601683613f61565b915061449082614451565b602082019050919050565b5f6020820190508181035f8301526144b281614479565b9050919050565b5f6060820190506144cc5f830186613b54565b6144d96020830185613a88565b6144e66040830184613a88565b949350505050565b7f496e76616c6964206465706f73697420616d6f756e74000000000000000000005f82015250565b5f614522601683613f61565b915061452d826144ee565b602082019050919050565b5f6020820190508181035f83015261454f81614516565b9050919050565b7f504e4c20616d6f756e7420746f6f20736d616c6c0000000000000000000000005f82015250565b5f61458a601483613f61565b915061459582614556565b602082019050919050565b5f6020820190508181035f8301526145b78161457e565b9050919050565b5f6145c882613a7f565b91506145d383613a7f565b92508282019050808211156145eb576145ea613fd9565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61462882613a7f565b915061463383613a7f565b925082614643576146426145f1565b5b828204905092915050565b5f6080820190506146615f830187613b54565b61466e6020830186613a88565b61467b6040830185613a88565b6146886060830184613a88565b95945050505050565b7f52657175657374206e6f7420617070726f7665640000000000000000000000005f82015250565b5f6146c5601483613f61565b91506146d082614691565b602082019050919050565b5f6020820190508181035f8301526146f2816146b9565b9050919050565b7f5061796f757420616d6f756e7420746f6f20736d616c6c0000000000000000005f82015250565b5f61472d601783613f61565b9150614738826146f9565b602082019050919050565b5f6020820190508181035f83015261475a81614721565b9050919050565b7f496e73756666696369656e7420636f6e74726163742062616c616e63650000005f82015250565b5f614795601d83613f61565b91506147a082614761565b602082019050919050565b5f6020820190508181035f8301526147c281614789565b9050919050565b5f6147d382613a7f565b91506147de83613a7f565b92508282039050818111156147f6576147f5613fd9565b5b92915050565b5f60808201905061480f5f830187613a88565b61481c6020830186613b54565b6148296040830185613a88565b6148366060830184613a88565b95945050505050565b7f52657175657374206e6f742070656e64696e67000000000000000000000000005f82015250565b5f614873601383613f61565b915061487e8261483f565b602082019050919050565b5f6020820190508181035f8301526148a081614867565b9050919050565b7f496e76616c696420696e766573746f72000000000000000000000000000000005f82015250565b5f6148db601083613f61565b91506148e6826148a7565b602082019050919050565b5f6020820190508181035f830152614908816148cf565b9050919050565b61491881613c3d565b8114614922575f5ffd5b50565b5f815190506149338161490f565b92915050565b5f6020828403121561494e5761494d613b7c565b5b5f61495b84828501614925565b91505092915050565b7f496e766573746f72206e6f7420616374697665000000000000000000000000005f82015250565b5f614998601383613f61565b91506149a382614964565b602082019050919050565b5f6020820190508181035f8301526149c58161498c565b9050919050565b7f4e6f20504e4c20746f6b656e73000000000000000000000000000000000000005f82015250565b5f614a00600d83613f61565b9150614a0b826149cc565b602082019050919050565b5f6020820190508181035f830152614a2d816149f4565b9050919050565b7f496e76616c6964207261746500000000000000000000000000000000000000005f82015250565b5f614a68600c83613f61565b9150614a7382614a34565b602082019050919050565b5f6020820190508181035f830152614a9581614a5c565b9050919050565b7f496e76616c69642074726164652077616c6c65742061646472657373000000005f82015250565b5f614ad0601c83613f61565b9150614adb82614a9c565b602082019050919050565b5f6020820190508181035f830152614afd81614ac4565b9050919050565b7f53616d65206164647265737300000000000000000000000000000000000000005f82015250565b5f614b38600c83613f61565b9150614b4382614b04565b602082019050919050565b5f6020820190508181035f830152614b6581614b2c565b9050919050565b7f4e6f7420657870697265642079657400000000000000000000000000000000005f82015250565b5f614ba0600f83613f61565b9150614bab82614b6c565b602082019050919050565b5f6020820190508181035f830152614bcd81614b94565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f614c08601f83613f61565b9150614c1382614bd4565b602082019050919050565b5f6020820190508181035f830152614c3581614bfc565b9050919050565b7f5061757361626c653a20706175736564000000000000000000000000000000005f82015250565b5f614c70601083613f61565b9150614c7b82614c3c565b602082019050919050565b5f6020820190508181035f830152614c9d81614c64565b9050919050565b5f606082019050614cb75f830186613b54565b614cc46020830185613b54565b614cd16040830184613a88565b949350505050565b7f5061757361626c653a206e6f74207061757365640000000000000000000000005f82015250565b5f614d0d601483613f61565b9150614d1882614cd9565b602082019050919050565b5f6020820190508181035f830152614d3a81614d01565b905091905056fea26469706673582212209293e50e319354c367874b486f1b3b879ece596e69444bf5c160bc04b2c12a1664736f6c634300081f0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000134c024d5ce4373c4360d0d85cb675488e95488000000000000000000000000eed5135b096348f4cf37026f2a6e33c95e1386e70000000000000000000000008795526899edbfd83d1cc89bab919287a1ebcfea0000000000000000000000006946e9886cb5ed3bb24dc9174b6e5f9f6e23daf6
-----Decoded View---------------
Arg [0] : _stablecoin1 (address): 0xdAC17F958D2ee523a2206206994597C13D831ec7
Arg [1] : _stablecoin2 (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [2] : _tradeWallet (address): 0x0134C024D5CE4373c4360d0d85Cb675488e95488
Arg [3] : _pnlTokenAddress (address): 0xEEd5135b096348F4Cf37026F2a6e33C95e1386E7
Arg [4] : _investorManager (address): 0x8795526899EDbFd83D1Cc89bAB919287a1eBcFEA
Arg [5] : initialOwner (address): 0x6946e9886Cb5eD3Bb24dC9174b6E5f9f6e23DAF6
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Arg [1] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [2] : 0000000000000000000000000134c024d5ce4373c4360d0d85cb675488e95488
Arg [3] : 000000000000000000000000eed5135b096348f4cf37026f2a6e33c95e1386e7
Arg [4] : 0000000000000000000000008795526899edbfd83d1cc89bab919287a1ebcfea
Arg [5] : 0000000000000000000000006946e9886cb5ed3bb24dc9174b6e5f9f6e23daf6
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 32 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.